MFC中实现的画箭头算法 (Arrow in MFC)

在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. //函数声明
  13. // Draws an arrow, using the current pen and brush, from the current position
  14. //  to the passed point using the attributes defined in the ARROWSTRUCT.
  15. void ArrowTo (HDC hDC, int x, int y, ARROWSTRUCT *pArrow );
  16. void ArrowTo (HDC hDC, const POINT *lpTo, ARROWSTRUCT *pArrow );
  17.  
  18. ///
  19. //画箭头函数实现
  20. void CMyDialog:: ArrowTo (HDC hDC, int x, int y, ARROWSTRUCT *pA ) {
  21.  
  22.         POINT ptTo = {x, y };
  23.  
  24.         ArrowTo (hDC, &ptTo, pA );
  25. }
  26.  
  27. void CMyDialog:: ArrowTo (HDC hDC, const POINT *lpTo, ARROWSTRUCT *pA ) {
  28.  
  29.         POINT pFrom;
  30.         POINT pBase;
  31.         POINT aptPoly [ 3 ];
  32.         float vecLine [ 2 ];
  33.         float vecLeft [ 2 ];
  34.         float fLength;
  35.         float th;
  36.         float ta;
  37.  
  38.         // get from point
  39.         MoveToEx (hDC, 0, 0, &pFrom );
  40.  
  41.         // set to point
  42.         aptPoly [ 0 ]. x = lpTo->x;
  43.         aptPoly [ 0 ]. y = lpTo->y;
  44.  
  45.         // build the line vector
  46.         vecLine [ 0 ] = ( float ) aptPoly [ 0 ]. x - pFrom. x;
  47.         vecLine [ 1 ] = ( float ) aptPoly [ 0 ]. y - pFrom. y;
  48.  
  49.         // build the arrow base vector - normal to the line
  50.         vecLeft [ 0 ] = -vecLine [ 1 ];
  51.         vecLeft [ 1 ] = vecLine [ 0 ];
  52.  
  53.         // setup length parameters
  54.         fLength = ( float ) sqrt (vecLine [ 0 ] * vecLine [ 0 ] + vecLine [ 1 ] * vecLine [ 1 ] );
  55.         th = pA->nWidth / ( 2.0f * fLength );
  56.         ta = pA->nWidth / ( 2.0f * (tanf (pA->fTheta ) / 2.0f ) * fLength );
  57.  
  58.         // find the base of the arrow
  59.         pBase. x = ( int ) (aptPoly [ 0 ]. x + -ta * vecLine [ 0 ] );
  60.         pBase. y = ( int ) (aptPoly [ 0 ]. y + -ta * vecLine [ 1 ] );
  61.  
  62.         // build the points on the sides of the arrow
  63.         aptPoly [ 1 ]. x = ( int ) (pBase. x + th * vecLeft [ 0 ] );
  64.         aptPoly [ 1 ]. y = ( int ) (pBase. y + th * vecLeft [ 1 ] );
  65.         aptPoly [ 2 ]. x = ( int ) (pBase. x + -th * vecLeft [ 0 ] );
  66.         aptPoly [ 2 ]. y = ( int ) (pBase. y + -th * vecLeft [ 1 ] );
  67.  
  68.         MoveToEx (hDC, pFrom. x, pFrom. y, NULL );
  69.  
  70.         // draw we're fillin'...
  71.         if (pA->bFill ) {
  72.                 LineTo (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y );
  73.                 Polygon (hDC, aptPoly, 3 );
  74.         }
  75.  
  76.         // ... or even jes chillin'...
  77.         else {
  78.                 LineTo (hDC, pBase. x, pBase. y );
  79.                 LineTo (hDC, aptPoly [ 1 ]. x, aptPoly [ 1 ]. y );
  80.                 LineTo (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y );
  81.                 LineTo (hDC, aptPoly [ 2 ]. x, aptPoly [ 2 ]. y );
  82.                 LineTo (hDC, pBase. x, pBase. y );
  83.                 MoveToEx (hDC, aptPoly [ 0 ]. x, aptPoly [ 0 ]. y, NULL );
  84.         }
  85. }

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

 

  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.        
  19.         CPen* pOldPen;
  20.         CPen pen (nPenStyle,nPenWidth,color );
  21.         pOldPen = pDC->SelectObject (&pen );
  22.  
  23.         CBrush br,*pbrOld;
  24.         br. CreateSolidBrush (color );
  25.         pbrOld = pDC->SelectObject (&br );
  26.  
  27.         ArrowTo (*pDC,point. x,point. y,&a );        //调用画箭头函数
  28.  
  29.         pDC->SelectObject (pOldPen );
  30.         pDC->SelectObject (pbrOld );
  31. }

 

 

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值