前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MFC中如何画带实心箭头的直线

MFC中如何画带实心箭头的直线

作者头像
用户1198337
发布2018-01-19 10:46:24
1.9K0
发布2018-01-19 10:46:24
举报
文章被收录于专栏:我有一个梦想我有一个梦想

工作中遇到话流程图的项目,需要画带箭头的直线,经过摸索,解决;思路如下:

(1) 两个点(p1,p2)确定一个直线,以直线的一个端点(假设p2)为原点,设定一个角度

(2)以P2为原点得到向量P2P1(P),向量P旋转theta角得到向量P1,向量P旋转-theta角得到向量P2

(3)伸缩向量至制定长度,平移变量到直线的末端

(4)现在已经有3个点了,画线就可

具体代码如下:

代码语言:javascript
复制
void CworkflowDlg::DrawLine(CPoint p1, CPoint p2)
{
        CClientDC dc(this);//获取客户窗口DC
    CPen pen,pen1,*oldpen;
    int PenLineWidth=2;//为了根据线条宽度设置箭头的大小
    pen.CreatePen(PS_SOLID, PenLineWidth, RGB(0, 0, 0));
    pen1.CreatePen(PS_SOLID, PenLineWidth, RGB(0, 0, 0));
    oldpen=dc.SelectObject(&pen);
    
    double theta=3.1415926/15*PenLineWidth;//转换为弧度
    double Px,Py,P1x,P1y,P2x,P2y;
    //以P2为原点得到向量P2P1(P)
    Px=p1.x-p2.x;
    Py=p1.y-p2.y;
    //向量P旋转theta角得到向量P1
    P1x=Px*cos(theta)-Py*sin(theta);
    P1y=Px*sin(theta)+Py*cos(theta);
    //向量P旋转-theta角得到向量P2
    P2x=Px*cos(-theta)-Py*sin(-theta);
    P2y=Px*sin(-theta)+Py*cos(-theta);
    //伸缩向量至制定长度
    double x1,x2;
    int length=10;
    x1=sqrt(P1x*P1x+P1y*P1y);
    P1x=P1x*length/x1;
    P1y=P1y*length/x1;
    x2=sqrt(P2x*P2x+P2y*P2y);
    P2x=P2x*length/x2;
    P2y=P2y*length/x2;
    //平移变量到直线的末端
    P1x=P1x+p2.x;
    P1y=P1y+p2.y;
    P2x=P2x+p2.x;
    P2y=P2y+p2.y;

    

    dc.MoveTo(p1.x,p1.y);
    dc.LineTo(p2.x,p2.y);
    dc.SelectObject(&pen1);
    dc.MoveTo(p2.x,p2.y);
    dc.LineTo(P1x,P1y);
    dc.MoveTo(p2.x,p2.y);
    dc.LineTo(P2x,P2y);

    dc.MoveTo(P1x,P1y);
    dc.LineTo(P2x,P2y);

    CPoint ptVertex[3];

    ptVertex[0].x = p2.x;
    ptVertex[0].y = p2.y;
    ptVertex[1].x = P1x;
    ptVertex[1].y = P1y;
    ptVertex[2].x = P2x;
    ptVertex[2].y = P2y;
        //填充三角形区域
    CBrush br(RGB(40,130,170));  
    CRgn rgn; 
    rgn.CreatePolygonRgn(ptVertex,3,ALTERNATE);
    dc.FillRgn(&rgn, &br);  

    dc.SelectObject(oldpen);

    br.DeleteObject();  
    rgn.DeleteObject();
}  

这里面用到CreatePolyonRgn这个函数,具体用法如下:

BOOL CRgn::CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode);

[说明]

创建一个由一系列点围成的区域。windows在需要时自动将最后点与第一点相连以封闭多边形

[参数表]

lpPoint -------- POINTAPI,nCount个POINTAPI结构中的第一个POINTAPI结构

nCount --------- Long,多边形的点数

nPolyFillMode -- Long,描述多边形填充模式。可为ALTERNATE 或 WINDING常数。nPolyFillMode在默认情 况下为ALTERNATE;

模式ALTERNATE:其从封闭区域中的一个点向无穷远处水平画一条射线,只有当该射线穿越奇数条边框线时,封闭区域才被填充,如为偶数,则不填充该区域;

模式WINDING:方法一样,如为奇数,填充该区域;如为偶数则要根据边框线的方向来判断:如果穿过的边框线在不同方向的边框线数目相等,则不填充,如不等,则填充。

[返回值]

Long,执行成功为创建的区域句柄,失败则为0

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档