(5)一步一步开发一个简单CAD之线,圆及矩形类

为了实现捡选,平称及旋转命令,必需对实体进行这些动作的操作

分别开发了线,圆及矩形类

class CMyrect;
class CLine : public CSolid
{
public:
 CLine();
 CLine(CPosition &pos1, CPosition &pos2);
 CSolid *CopySolid(){ return new CLine(this->m_begin, this->m_end);}//深复制直线
 virtual ~CLine();
public:
 CSolid* Explan(CPosition pos,short zDelta);
    CSolid* Rotate(const CPosition &base, float angle);
    CSolid* Move(CPosition first, CPosition second);
 BOOL PickSolid(CPosition &pos, float dis);
 void DrawSolid(CDC *pDC, int drawMode);
 void GetBox(CBox2D &box);//包围盒
 void DrawRect(BOOL br, CPosition &pos, CPosition *bpos = NULL);
 void GetEnd(CPosition &end){end = m_end;}
 CSolid *Mirror(CPosition &first, CPosition &second);
  
protected:
 CPosition m_begin, m_end;

};

class CCircle : public CSolid//圆形对像,中心和圆上一点
{
public:
 CCircle(){};
 CCircle(const CPosition begin, const CPosition end);
 CSolid *CopySolid(){ return new CCircle(this->m_begin, this->m_end);}
 virtual ~CCircle(){};
public:
 CSolid* Explan(CPosition pos,short zDelta);
    CSolid* Rotate(const CPosition &base, float angle);
    CSolid* Move(CPosition first, CPosition second);
 void DrawSolid(CDC *pDC, int drawMode);//画圆形
 BOOL PickSolid(CPosition &pos, float dis);
 void DrawRect(BOOL br, CPosition &pos, CPosition *bpos = NULL);
 CSolid *Mirror(CPosition &first, CPosition &second);
private:
    CPosition m_begin, m_end;

};

class CCRect : public CSolid//两个对角点
{
public:
 CCRect(){};
 CCRect(const CPosition begin, const CPosition end);
 CSolid *CopySolid(){ return new CCRect(this->m_begin, this->m_end);}
 virtual ~CCRect(){};
public:
 CSolid* Explan(CPosition pos,short zDelta);
    CSolid* Rotate(const CPosition &base, float angle);
    CSolid* Move(CPosition first, CPosition second);
 void DrawSolid(CDC *pDC, int drawMode);//画圆形
 BOOL PickSolid(CPosition &pos, float dis);
 void DrawRect(BOOL br, CPosition &pos, CPosition *bpos = NULL);
 CSolid *Mirror(CPosition &first, CPosition &second);
 
private:
    CPosition m_begin, m_end;

};

CLine::CLine()
{
  
}

CLine::CLine(CPosition &pos1, CPosition &pos2)
{
 m_begin = pos1;
   m_end = pos2;
  
 m_Style = PS_SOLID;
 m_Width = 0;
    m_color = RGB(255, 255, 255);

 
}

CLine::~CLine()
{
 
}

void CLine::DrawSolid(CDC *pDC, int drawMode)
{
 CPoint point1, point2;

 g_pView->WPTODP(m_begin, point1);
 g_pView->WPTODP(m_end, point2);


 
    CPen pen;
  if (drawMode == Normal)//根据输入模式生居画笔
  {
 pen.CreatePen(m_Style, m_Width, m_color);

  }
  else
  {
     GSetDrawMode(pDC, drawMode, &pen);
  }
 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
  Oldpen = pDC->SelectObject(&pen);

 pDC->MoveTo(point1.x, point1.y);
 pDC->LineTo(point2.x, point2.y);


 pDC->SetROP2(n);
 pDC->SelectObject(Oldpen);
}

BOOL CLine::PickSolid(CPosition &pos, float dis)
{
    CBox2D box;
 GetBox(box);
 box.GetExBox2D(dis);//得到扩张包围盒,考虑直线是水平或者竖直的情况
 if (!pos.IsBox(box))
 {
  return FALSE;
 }
 else
 {
  return  ( pos.verdistance(m_begin, m_end) <= dis );//小于给定距离
 }
 

}

void CLine::GetBox(CBox2D &box)
{
   box.m_min.m_x = min(m_begin.m_x, m_end.m_x);
   box.m_min.m_y = min(m_begin.m_y, m_end.m_y);

   box.m_max.m_x = max(m_begin.m_x, m_end.m_x);
   box.m_max.m_y = max(m_begin.m_y, m_end.m_y);
}

CSolid* CLine::Rotate(const CPosition &base, float angle)//
{
 m_begin.Rotate(base, angle);
 m_end.Rotate(base, angle);
 return (CSolid*)this;
}

CSolid* CLine::Explan(CPosition pos, short zDelta)
{
 float scale = 0.0;
 if (zDelta > 0)
 scale = 0.7;
 else
 scale = 1.3;
 
    m_begin.Explan(pos, scale);
 m_end.Explan(pos, scale);
    return (CSolid*)this;
}

CSolid* CLine::Move(CPosition first, CPosition second)
{
     m_begin.Move(first, second);
  m_end.Move(first, second);
  return (CSolid*)this;
}

CSolid *CLine::Mirror(CPosition &first, CPosition &second)
{
  CPosition pos1 = m_begin.Mirror(first, second);
  CPosition pos2 = m_end.Mirror(first, second);
  return new CLine(pos1, pos2);
}

void CLine::DrawRect(BOOL br, CPosition &pos, CPosition *bpos)//直线带有三个矩形标记
{
  CMyrect* rect1 = new CMyrect(m_begin);
     CMyrect* rect2 = new CMyrect(m_end);
  CMyrect* center = new CMyTri( (m_begin + m_end ) * 0.5);
 

 CDC *pDC = g_pView->GetDC();
  
 rect1->DrawRect(pDC, rect1->PisRect(pos), 1, pos, bpos);
  rect2->DrawRect(pDC, rect2->PisRect(pos), 1, pos, bpos);
    center->DrawRect(pDC, center->PisRect(pos), 1, pos, bpos);

   g_pView->ReleaseDC(pDC);

 delete rect1, rect2, center;


 

}

CCircle::CCircle(const CPosition begin, const CPosition end)
{
 m_begin = begin;
   m_end = end;

  
 m_Style = PS_SOLID;
 m_Width = 0;
    m_color = RGB(255, 255, 255);
}
BOOL CCircle::PickSolid(CPosition &pos, float dis)//认为圆是有宽度的线,宽度为6个像素
{
   dis = 3 * ( g_pView->m_scale );
   float r = m_begin.Distance(m_end);
   float dis1 = r - dis;
 
   float dis2 = r + dis;

   float ro = m_begin.Distance(pos);
  

   if (ro >= dis1 && ro <= dis2)
   {
    return TRUE;
   }
   else
   {
    return FALSE;
   }

}
CSolid* CCircle::Rotate(const CPosition &base, float angle)//
{
 m_begin.Rotate(base, angle);
 m_end.Rotate(base, angle);
 return (CSolid*)this;
}

CSolid* CCircle::Explan(CPosition pos, short zDelta)
{
 float scale = 0.0;
 if (zDelta > 0)
 scale = 0.7;
 else
 scale = 1.3;
 
    m_begin.Explan(pos, scale);
 m_end.Explan(pos, scale);
    return (CSolid*)this;
}

CSolid* CCircle::Move(CPosition first, CPosition second)
{
     m_begin.Move(first, second);
  m_end.Move(first, second);
  return (CSolid*)this;
}

CSolid *CCircle::Mirror(CPosition &first, CPosition &second)
{
   CPosition pos1 = m_begin.Mirror(first, second);
   CPosition pos2 = m_end.Mirror(first, second);
   return new CCircle(pos1, pos2);
}

class CMyCircle;
class CCros;
void CCircle::DrawRect(BOOL br, CPosition &pos, CPosition *bpos)//多边形带有五个矩形标记
{

  float dis = m_begin.Distance(m_end);

  CDC *pDC = g_pView->GetDC();

 CPosition Numpos[4];
 Numpos[0] = (CPosition(0, 1) * dis + m_begin);
 
 Numpos[1] = (CPosition(0, -1) * dis + m_begin);
 Numpos[2] = (CPosition(1, 0) * dis + m_begin);
 Numpos[3] = (CPosition(-1, 0) * dis + m_begin);
   
 CMyrect *circle = new CMyCircle(m_begin);//画圆心
    circle->DrawRect(pDC, circle->PisRect(pos), 1, pos, bpos);
 delete circle;

 CMyrect *rect = new CCros[4];
 CMyrect::DrawMRect(pDC, 4, Numpos, &pos, bpos, rect);
    delete [] rect;
    g_pView->ReleaseDC(pDC);
}

void CCircle::DrawSolid(CDC *pDC, int drawMode)
{
     CPosition pos[2];
  float dis = m_begin.Distance(m_end);
  pos[0] = CPosition(-1, 0) * dis  + CPosition(0, 1) * dis+ m_begin;
  pos[1] = m_begin * 2 - pos[0];
      
  CPoint point1, point2;

  g_pView->WPTODP(pos[0], point1);
  g_pView->WPTODP(pos[1], point2);

 CPen pen;
  if (drawMode == Normal)//根据输入模式生居画笔
  {
 pen.CreatePen(m_Style, m_Width, m_color);

  }
  else
  {
     GSetDrawMode(pDC, drawMode, &pen);
  }
   
 CBrush brush;
 LOGBRUSH logbrush;
 logbrush.lbStyle = BS_NULL;
 
 brush.CreateBrushIndirect(&logbrush);

 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
 CBrush *Oldbrush = NULL;
 Oldbrush = pDC->SelectObject(&brush);
  Oldpen = pDC->SelectObject(&pen);

    pDC->Ellipse(&CRect(point1, point2));

 pDC->SetROP2(n);
 pDC->SelectObject(Oldpen);
 pDC->SelectObject(Oldbrush);
   

   
}

CCRect::CCRect(const CPosition begin, const CPosition end)
{
 m_begin = begin;
   m_end = end;

  
 m_Style = PS_SOLID;
 m_Width = 0;
    m_color = RGB(255, 255, 255);
}
BOOL CCRect::PickSolid(CPosition &pos, float dis)//分别对四个边捡选,可以直接利用CLine 类
{
    CPosition Arraypos[5];
       Arraypos[0] = m_begin;
    Arraypos[1] = CPosition(m_begin.m_x, m_end.m_y);//左下
       Arraypos[2] = m_end;
    Arraypos[3] = CPosition(m_end.m_x, m_begin.m_y);//右上
    Arraypos[4] = m_begin;
  
    for (int i = 0; i <4; i++)
    {
           CLine *line = new CLine(Arraypos[i], Arraypos[i + 1]);
     if (line->PickSolid(pos, dis))
     {
              delete line;
     return TRUE;
     }
    
    
    }
    return FALSE;
  

}
CSolid* CCRect::Rotate(const CPosition &base, float angle)//
{
 m_begin.Rotate(base, angle);
 m_end.Rotate(base, angle);
 return (CSolid*)this;
}

CSolid* CCRect::Explan(CPosition pos, short zDelta)
{
 float scale = 0.0;
 if (zDelta > 0)
 scale = 0.7;
 else
 scale = 1.3;
 
    m_begin.Explan(pos, scale);
 m_end.Explan(pos, scale);
    return (CSolid*)this;
}

CSolid* CCRect::Move(CPosition first, CPosition second)
{
     m_begin.Move(first, second);
  m_end.Move(first, second);
  return (CSolid*)this;
}

CSolid *CCRect::Mirror(CPosition &first, CPosition &second)
{
      CPosition pos1 = m_begin.Mirror(first, second);
   CPosition pos2 = m_end.Mirror(first, second);
   return new CCRect(pos1, pos2); 
}

void CCRect::DrawRect(BOOL br, CPosition &pos, CPosition *bpos)//矩形带有9个标记
{

  CDC *pDC = g_pView->GetDC();

       CPosition Arraypos[4];
       Arraypos[0] = m_begin; //0
    Arraypos[1] = CPosition(m_begin.m_x, m_end.m_y);//左下1///端点
       Arraypos[2] = m_end;//2
    Arraypos[3] = CPosition(m_end.m_x, m_begin.m_y);//右上3

       CPosition CtrArraypos[4];
    CtrArraypos[0] = (Arraypos[0] + Arraypos[3]) * 0.5;//03//中点
    CtrArraypos[1] = (Arraypos[0] + Arraypos[1]) * 0.5;//01
    CtrArraypos[2] = (Arraypos[1] + Arraypos[2]) * 0.5;//12
    CtrArraypos[3] = (Arraypos[2] + Arraypos[3]) * 0.5;//23

   CPosition cenArraypos[1];
   cenArraypos[1] = (Arraypos[0] + Arraypos[2]) * 0.5;//02//圆心

      CMyrect *circle = new CMyCircle(cenArraypos[0]);//画圆心
      circle->DrawRect(pDC, circle->PisRect(pos), 1, pos, bpos);
   delete circle;

   CMyrect *myrect = new CMyrect[4];//端点
      CMyrect::DrawMRect(pDC, 4, Arraypos, &pos, bpos, myrect);
   delete [] myrect;

      CMyrect *rect = new CMyTri[4];
   CMyrect::DrawMRect(pDC, 4, CtrArraypos, &pos, bpos, rect);
   delete [] rect;

    g_pView->ReleaseDC(pDC);
}

void CCRect::DrawSolid(CDC *pDC, int drawMode)
{
  
      
  CPoint point1, point2;

  g_pView->WPTODP(m_begin, point1);
  g_pView->WPTODP(m_end, point2);

 CPen pen;
  if (drawMode == Normal)//根据输入模式生居画笔
  {
 pen.CreatePen(m_Style, m_Width, m_color);

  }
  else
  {
     GSetDrawMode(pDC, drawMode, &pen);
  }
   
 CBrush brush;
 LOGBRUSH logbrush;
 logbrush.lbStyle = BS_NULL;
 
 brush.CreateBrushIndirect(&logbrush);

 int n = pDC->GetROP2();
  CPen *Oldpen = NULL;
 CBrush *Oldbrush = NULL;
 Oldbrush = pDC->SelectObject(&brush);
  Oldpen = pDC->SelectObject(&pen);

    pDC->Rectangle(&CRect(point1, point2));

 pDC->SetROP2(n);
 pDC->SelectObject(Oldpen);
 pDC->SelectObject(Oldbrush);
   

   
}

原文地址:https://www.cnblogs.com/lizhengjin/p/1289226.html