• (1)一步一步开发一个简单二维CAD之基本框架


    在学校没事,所以开发一个具有基本功能的二维CAD,具有画线,画矩形,画圆,有捡选,平移,旋转,镜像,删除,实时放大,缩小,串行化的功能

     

    首先谈架构,架构采用流行的MVC架构,也就是模型,视图,控制器的架购,模型包括数据和对数据的操作,而视图则是对模型的显示,控制器则是根据界面的操作.

     

     

    (1)为了开发方便,首先开发了两个数学工具类,以便于使用

    点类和包围盒类

     

    class CBox2D;
    class CPosition 
    {
    public:
     CPosition();
     CPosition(float x, float y);
     virtual ~CPosition();
    public:
     float verdistance(CPosition &begin, CPosition &end);
     float Distance(const CPosition pos);
     BOOL  IsBox(const CBox2D &pox);
     CPosition Rotate(const CPosition &base, float angle);
     CPosition Explan(const CPosition &base, float scale);
     CPosition Mirror(CPosition &first, CPosition &second);
     CPosition Move(CPosition &first, CPosition &second);
     float AagleTox();
     void Get2Point(double circel[2]);
       
     CPosition operator-(CPosition pos);
     CPosition operator+(CPosition pos);
     void operator-=(CPosition pos);
     void operator+=(CPosition pos);
     CPosition operator*(float scale);

    private:
     float m_x;
     float m_y;
    };

    class CBox2D
    {
    public:
     CBox2D();
     CBox2D(CPosition min, CPosition max);
     virtual ~CBox2D();
    public:
     void GetExBox2D(float distance);//扩张包围
     

    private:
     CPosition m_min;
     CPosition m_max;
    };

    两个类的实现如下

    #define IP 3.1415926

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    CBox2D::CBox2D()
    {

    }

    CBox2D::~CBox2D()
    {

    }

    CBox2D::CBox2D(CPosition min, CPosition max)
    {
     m_min = min;
     m_max = max;
    }

    void CBox2D::GetExBox2D(float distance)//扩张包围盒,当直线是水平或者垂直的时候,不存在包围盒,所以要包围对角点平移,以适应这种情况
    {
     m_min.m_x -= distance;
     m_min.m_y -= distance;

     m_max.m_x += distance;
     m_max.m_y += distance;
    }


    CPosition::CPosition()
    {

    }

    CPosition::CPosition(float x, float y)
    {
     m_x = x;
     m_y = y;

      
    }
    CPosition::~CPosition()
    {

    }

    float CPosition::verdistance(CPosition &begin, CPosition &end)//利用三维叉集计算二维距离,Z坐标为0
    {
        float a = fabsf( (m_x - begin.m_x) * (end.m_y - begin.m_y) - (m_y - begin.m_y) * (end.m_x - begin.m_x) );
        float b = sqrt( (end.m_x - begin.m_x) * (end.m_x - begin.m_x) + (end.m_y - begin.m_y) * (end.m_y - begin.m_y) );
     return a/b;
    }

    BOOL  CPosition::IsBox(const CBox2D &pox)
    {
     if (m_x >= pox.m_min.m_x && m_y >= pox.m_min.m_y && m_x <= pox.m_max.m_x && m_y <= pox.m_max.m_y)
        return TRUE;
        else
        return FALSE;
    }

    CPosition CPosition::Rotate(const CPosition &base, float angle)//沿一点旋转angle度,逆时针为正
    {
     
     float x = (m_x - base.m_x) * cos(angle) - (m_y - base.m_y) * sin(angle) + base.m_x;
     float y = (m_x - base.m_x) * sin(angle) + (m_y - base.m_y) * cos(angle) + base.m_y;
     
     return CPosition(x, y);
    }

    CPosition CPosition::Explan(const CPosition &base, float scale)
    {
       *this = (*this - base) * scale + base;
          return *this;

    }

    CPosition CPosition::Move(CPosition &first, CPosition &second)//沿两点方向平移
    {
        CPosition pos;
        pos = second - first;
        *this += pos;
        return *this;
    }

    CPosition CPosition::operator-(CPosition pos)
    {
     return CPosition(m_x - pos.m_x, m_y - pos.m_y);
    }

    CPosition CPosition::operator+(CPosition pos)
    {
       return CPosition(m_x + pos.m_x, m_y + pos.m_y);
    }

    void CPosition::operator-=(CPosition pos)
    {
     m_x -= pos.m_x;
     m_y -= pos.m_y;

    }

    void CPosition::operator+=(CPosition pos)
    {
     m_x += pos.m_x;
     m_y += pos.m_y;
    }

    float CPosition::Distance(const CPosition pos)
    {
     return sqrt( (m_x - pos.m_x) * (m_x - pos.m_x) + (m_y - pos.m_y) * (m_y - pos.m_y) );
    }

    float CPosition::AagleTox()//
    {
       
     float cosv = m_x/sqrt(m_x * m_x + m_y * m_y);
     float sinv = m_y/sqrt(m_x * m_x + m_y * m_y) ;

     if(sinv >= 0)
      return acos(cosv) ;
     else if(sinv < 0)
      return 2.*IP-acos(cosv) ;
     return FALSE ;
      
    }

    CPosition CPosition::operator*(float scale)
    {
     return CPosition(m_x * scale, m_y * scale);
    }

    CPosition CPosition::Mirror(CPosition &first, CPosition &second)
    {
         CPosition pos = (second - first) * ( 1 / second.Distance(first) );//镜像线单位化
         CPosition pos1 = *this - first;//第一起点和镜像点之间的矢量
      float pos2 = pos1.m_x * pos.m_x + pos1.m_y * pos.m_y;
      return (first + pos * pos2 ) * 2 - *this;
    }  

     

    世界坐标,也就是我们在现实中实际看到的物体的坐标

    客户坐标,也就是我们屏幕客户区的坐标

    我们一切点的坐标,必需在这两个坐标之间转换

    这两个函数可以放在CView的派生类里面

     

    void CMcadView::DPTOWP(CPoint &point, CPosition &pos)//m_base_x, m_base_y观察坐标系的基点坐标,m_scale是观察坐标和客户转换的系数
    {  
     
     CRect rect;
     GetClientRect(&rect);


        pos.m_x = point.x * m_scale + m_base_x;
     pos.m_y = (rect.Height() - point.y) * m_scale + m_base_y;
    }

    void CMcadView::WPTODP(CPosition &pos, CPoint &point)
    {
       CRect rect;
       GetClientRect(&rect);
     

       point.x = (int)(pos.m_x - m_base_x)/m_scale;
       point.y = rect.Height() - (int)(pos.m_y - m_base_y)/m_scale;
    }

    所有的一切鼠标在屏幕上的操作,必需用这两个函数转换成实际坐标,而所有的实际坐标屏幕上显示的时候,都必需转换为

    屏幕坐标

     

  • 相关阅读:
    修改requests_html.AsyncHTMLSessions使得支持url参数
    MyBatis查询返回Map示例代码
    java.util.ConcurrentModificationException 异常原因和解决方法
    Springboot整合RabbitMQ(四)——设置消息过期时间TTL
    MySql Lock wait timeout exceeded该如何处理? (转载)
    对开发流程优化的建议
    容器未正常启动-->docker ps看不到,docker ps -a可以看到-->执行命令时出现Container is not running
    Linux下C语言多线程编程
    curl库相关使用
    PCB走线&过孔载流分析
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1289119.html
Copyright © 2020-2023  润新知