zoukankan      html  css  js  c++  java
  • MFC中如何画带实心箭头的直线

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

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

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

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

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

    具体代码如下:

    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
    感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。 博主网址:http://www.cnblogs.com/ChinacloudTech/ 独立博客:http://futuretechx.com 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:1145356699@qq.com。 本博客为博主原创,欢迎转载,但必须注明博客来源。 更多关于游戏开发的内容也可关注微信公众号:微浪游戏
  • 相关阅读:
    等待通知--wait notify
    表单重复提交与解决
    Cookie Session 与Token
    springMVC实现登陆
    第11章 AOF持久化
    第10章 RDB持久化
    MyBatis动态SQL
    第4章 网络层
    第9章 数据库
    代理设计模式
  • 原文地址:https://www.cnblogs.com/ChinacloudTech/p/6207109.html
Copyright © 2011-2022 走看看