在codeproject中寻找到一个这样的算法,在这里介绍一下

可以改变三角形大小,顶点角度,是否填充和填充颜色等

但是画出的箭头还是不够美观....呵呵,还好吧

其中填充是代表箭头内是否填充颜色

先来看声明和实现

  1. //使用一个结构体来存储相关的信息
  2. //Defines the attributes of an arrow.
  3. typedef struct tARROWSTRUCT {
  4. int nWidth;     // width (in pixels) of the full base of the arrowhead
  5. float fTheta;   // angle (in radians) at the arrow tip between the two
  6. //  sides of the arrowhead
  7. bool bFill;     // flag indicating whether or not the arrowhead should be
  8. //  filled
  9. } ARROWSTRUCT;
  10. ///
  11. //函数声明
  12. // Draws an arrow, using the current pen and brush, from the current position
  13. //  to the passed point using the attributes defined in the ARROWSTRUCT.
  14. void ArrowTo(HDC hDC, int x, int y, ARROWSTRUCT *pArrow);
  15. void ArrowTo(HDC hDC, const POINT *lpTo, ARROWSTRUCT *pArrow);
  16. ///
  17. //画箭头函数实现
  18. void CMyDialog::ArrowTo(HDC hDC, int x, int y, ARROWSTRUCT *pA) {
  19. POINT ptTo = {x, y};
  20. ArrowTo(hDC, &ptTo, pA);
  21. }
  22. void CMyDialog::ArrowTo(HDC hDC, const POINT *lpTo, ARROWSTRUCT *pA) {
  23. POINT pFrom;
  24. POINT pBase;
  25. POINT aptPoly[3];
  26. float vecLine[2];
  27. float vecLeft[2];
  28. float fLength;
  29. float th;
  30. float ta;
  31. // get from point
  32. MoveToEx(hDC, 0, 0, &pFrom);
  33. // set to point
  34. aptPoly[0].x = lpTo->x;
  35. aptPoly[0].y = lpTo->y;
  36. // build the line vector
  37. vecLine[0] = (float) aptPoly[0].x - pFrom.x;
  38. vecLine[1] = (float) aptPoly[0].y - pFrom.y;
  39. // build the arrow base vector - normal to the line
  40. vecLeft[0] = -vecLine[1];
  41. vecLeft[1] = vecLine[0];
  42. // setup length parameters
  43. fLength = (float) sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]);
  44. th = pA->nWidth / (2.0f * fLength);
  45. ta = pA->nWidth / (2.0f * (tanf(pA->fTheta) / 2.0f) * fLength);
  46. // find the base of the arrow
  47. pBase.x = (int) (aptPoly[0].x + -ta * vecLine[0]);
  48. pBase.y = (int) (aptPoly[0].y + -ta * vecLine[1]);
  49. // build the points on the sides of the arrow
  50. aptPoly[1].x = (int) (pBase.x + th * vecLeft[0]);
  51. aptPoly[1].y = (int) (pBase.y + th * vecLeft[1]);
  52. aptPoly[2].x = (int) (pBase.x + -th * vecLeft[0]);
  53. aptPoly[2].y = (int) (pBase.y + -th * vecLeft[1]);
  54. MoveToEx(hDC, pFrom.x, pFrom.y, NULL);
  55. // draw we're fillin'...
  56. if(pA->bFill) {
  57. LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
  58. Polygon(hDC, aptPoly, 3);
  59. }
  60. // ... or even jes chillin'...
  61. else {
  62. LineTo(hDC, pBase.x, pBase.y);
  63. LineTo(hDC, aptPoly[1].x, aptPoly[1].y);
  64. LineTo(hDC, aptPoly[0].x, aptPoly[0].y);
  65. LineTo(hDC, aptPoly[2].x, aptPoly[2].y);
  66. LineTo(hDC, pBase.x, pBase.y);
  67. MoveToEx(hDC, aptPoly[0].x, aptPoly[0].y, NULL);
  68. }
  69. }

再来看调用实现(加一层封装更加适用)

  1. /
  2. //封装调用函数实现(其实还是有很大的扩展空间的)
  3. void CMyDialog::ArrowTo(
  4. CDC *pDC,              //画刷
  5. CPoint point,          //终点坐标
  6. int nPenStyle,         //线样式
  7. int nPenWidth,         //线宽度
  8. COLORREF color, //颜色
  9. int nWidth,            //三角形底边宽度
  10. float fTheta,          //三角形顶角角度
  11. bool bFill             //是否填充颜色
  12. )
  13. {
  14. ARROWSTRUCT a;
  15. a.nWidth = nWidth;     //三角形底边宽度
  16. a.fTheta = fTheta;     //三角形顶角角度
  17. a.bFill = bFill;       //是否填充颜色
  18. CPen* pOldPen;
  19. CPen pen(nPenStyle,nPenWidth,color);
  20. pOldPen = pDC->SelectObject(&pen);
  21. CBrush br,*pbrOld;
  22. br.CreateSolidBrush(color);
  23. pbrOld = pDC->SelectObject(&br);
  24. ArrowTo(*pDC,point.x,point.y,&a);       //调用画箭头函数
  25. pDC->SelectObject(pOldPen);
  26. pDC->SelectObject(pbrOld);
  27. }

转载于:https://www.cnblogs.com/wupingzsf/archive/2010/05/16/1736958.html

MFC中实现的画箭头算法 (Arrow in MFC)相关推荐

  1. 在MFC中,运用轨迹球算法实现鼠标旋转物体

    参考资料:nehe教程第48课<轨迹球实现的鼠标旋转> 1.在头文件中为Arcball添加变量 //为Arcball添加变量用来获取当前鼠标点Point2fT MousePt;// NEW ...

  2. ATL--创建简单的ATL之dll工程,添加类和类的接口并在MFC中调用

    资源打包 开发环境 Windows Server 2012 VS2010 Sp1 番茄助手 创建ATL简单dll工程 1.打开VS2010,新建ATL COM 项目,步骤:"文件" ...

  3. mfc中插入PNG透明图片

    mfc中插入PNG透明图片 记录下在mfc中插入png透明图片的方法 新建项目 在对话框界面中插入两个 Picture Control 在MFC_pngDlg.h中添加 在MFC_pngDlg.cpp ...

  4. 修改MFC中AfxMessageBox()函数的对话框标题

    修改MFC中AfxMessageBox()函数的对话框标题 如何在MFC中修改AfxMessageBox()函数所弹出的对话框标题,步骤如下: 1.找到项目工程的资源视图,打开.rc资源文件下的Str ...

  5. 【opencv】3.在一个opencv窗口中显示多个视频界面、画箭头、画掉头箭头

    1.在一个opencv窗口中显示不同视频界面 /** * @brief 在一个opencv窗口win_name中显示不同视频界面 * @param img_1 和 img_2 是分别是取自不同视频中的 ...

  6. mfc 画圆算法 画椭圆算法

    mfc画圆算法 求半径:圆心一点:m_ptOrigin1,圆上一点:m_ptOrigin2 注释:这里的m_ptOrigin1,m_ptOrigin2均为Cpoint类型 R=int(sqrt(pow ...

  7. 中点Bresenham画圆算法|MFC|计算机图形学

    中点Bresenham画圆算法|MFC|计算机图形学 Bresenham中点画圆算法 计算机图形学-基本图元的生成-圆 基于学习直线的生成算法后,又展开了圆.椭圆的讲解: 此次试验是简单的MFC应用, ...

  8. MFC中的控件是怎么实现的呢?一个按钮就是一个窗口?还是所有按钮画在一个分层窗口上再叠

    请教一下MFC中的控件是怎么实现的呢(通过调用什么样的API,传递什么参数)?一个按钮就是一个窗口?还是所有按钮画在一个分层窗口上再叠在主窗口上?还是直接在主窗口上画图? 我想到的是: JavaScr ...

  9. matlab 中画箭头

    matlab 画图时,没有直接画箭头的函数.网上搜索解决方案时,有人提到用 annotation 函数,但该函数的位置坐标并不是传统的坐标值,而是在整个图形位置的单位坐标,不好调整:另一种方法 用 f ...

最新文章

  1. “静态常量”与“ #define”与“枚举”
  2. Oracle创建触发器的普通应用
  3. linux上安装配置vsftpd
  4. Backup Exec for Windows Servers (BEWS) 简体中文文档汇总(持续更新)
  5. Debian Security Advisory(Debian安全报告) DSA-4411-1 firefox-esr security update
  6. (pytorch-深度学习)深度循环神经网络
  7. 哈工大未来计算机院士,2017年中国高校新增工程院院士名单出炉,哈工大依然很强!...
  8. helm安装_如何利用 Helm 在 Kubernetes 上快速部署 Jenkins
  9. c 连接mysql数据库查询_C语言实现访问及查询MySQL数据库的方法
  10. php数据库随机选择,php – 在MySQL数据库中选择两个随机行
  11. 小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_41、SpringBoot定时任务schedule讲解...
  12. 系统架构设计师与系统分析师历年实体分析与解答下载_架构设计的本质
  13. 什么是互联网外包公司
  14. web前端入门到实战:img中alt和title属性的区别
  15. web网站整体变灰色仅仅需要两行代码
  16. 小提琴统计图_快速绘制分组小提琴图工具
  17. JVM之运行时数据区(方法区)
  18. 把你的阿里巴巴图标库转成你自己的@ant-design/icons
  19. 7、Callable接口
  20. Race_Condition实验

热门文章

  1. LeetCode 1072. 按列翻转得到最大值等行数(查找相同的模式,哈希计数)
  2. LeetCode 491. 递增子序列(回溯+判重剪枝)
  3. LeetCode 98. 验证二叉搜索树(中序遍历)
  4. java impala_Java实现impala操作kudu
  5. 利用python批量修改文件名称
  6. python中的字符串操作及注意事项
  7. python混沌时间序列分析_用Python进行时间序列分析
  8. java私有表示标识_java里面的标识符、关键字和类型
  9. python odoo_odoo python 使用缓存
  10. python清除列表内容_Python 列表的清空方式