Polygon.cpp
资源名称:CAD2006.rar [点击查看]
上传用户:ckg1000
上传日期:2013-01-26
资源大小:630k
文件大小:11k
源码类别:
CAD
开发平台:
Visual C++
- // Polygon.cpp: implementation of the CPolygon class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "CAD2006.h"
- #include "Polygon.h"
- #include "math.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CPolygon::CPolygon()
- {
- m_status = NoClicked;
- }
- CPolygon::~CPolygon()
- {
- }
- int CPolygon::Distance(POINT Pt1, POINT Pt2) //求两点之间的距离
- {
- int nDist;
- nDist =(int)(sqrt((Pt1.x - Pt2.x)*(Pt1.x - Pt2.x) + (Pt1.y - Pt2.y)*(Pt1.y - Pt2.y)));
- return nDist;
- }
- void CPolygon::CalculateTopPt(POINT PtArray[], int nRadius) //计算一个圆上等分点的坐标
- {
- const double Pi = 3.14159; ////////////////
- double angle = 2*Pi/m_nSide;
- double angleT = 0;
- for(int nIndex = 0; nIndex < m_nSide; nIndex++, angleT += angle)
- {
- POINT NowPoint;
- NowPoint.x = (int)(m_centPt.x + nRadius * sin(angleT));
- NowPoint.y = (int)(m_centPt.y - nRadius * cos(angleT));
- PtArray[nIndex] = NowPoint;
- }
- }
- void CPolygon::Draw(CDC *pDC,POINT topPt[], POINT OldTopPt[]) //输入两组点
- {
- HPEN newPen = ::CreatePen(m_borderStyle,
- m_borderWidth,m_borderColor^pDC->GetBkColor());
- HBRUSH newBrush = ::CreateSolidBrush(m_backColor^ pDC->GetBkColor());
- pDC->SelectObject(newPen);
- pDC->SelectObject(newBrush);
- int oldR2 = pDC->SetROP2(R2_XORPEN);
- pDC->Polygon( OldTopPt, m_nSide );
- pDC->Polygon( topPt, m_nSide );
- pDC->SetROP2(oldR2);
- ::DeleteObject(newPen);
- ::DeleteObject(newBrush);
- }
- void CPolygon::Update(CDC *pDC) //更新图形
- {
- HDC hdc = pDC->GetSafeHdc();
- DrawRound(pDC,GetBkColor(hdc)); //先擦掉小圆圈
- KillMirLine(pDC); //擦掉镜像直线
- }
- void CPolygon::OnLbuttondown(CDC *pDC,CPoint point)
- {
- POINT curPoint; //左键点击的点
- curPoint.x = point.x ; //取低16位 x 值
- curPoint.y = point.y ; //取高16位 y 值
- switch(m_status)
- {
- case NoClicked:
- {
- m_centPt = m_oldPt = curPoint;
- m_status = FirstClicked;
- }
- break;
- case FirstClicked:
- {
- m_endPt = curPoint;
- m_status = NoClicked;
- }
- break;
- }
- }
- void CPolygon::Onmousemove(CDC *pDC,CPoint point)
- {
- POINT curPoint;
- curPoint.x = point.x ;
- curPoint.y = point.y ;
- if( m_status == FirstClicked )
- {
- m_topPt = new POINT[m_nSide]; //动态分配一个顶点数组
- POINT *OldtopPt = new POINT[m_nSide];
- m_endPt = curPoint;
- m_Radius = Distance(m_centPt,m_endPt);
- int OldRadius = Distance(m_centPt,m_oldPt);
- CalculateTopPt(m_topPt, m_Radius); //重新计算每顶点坐标
- CalculateTopPt(OldtopPt, OldRadius);
- Draw(pDC,m_topPt, OldtopPt);
- m_oldPt = curPoint;
- }
- }
- bool CPolygon::IsOnPolygon(POINT curPt) //判断一个点是否在多边型上
- {
- bool yesno= false;
- int SideLength = Distance(m_topPt[0],m_topPt[1]); //计算边长
- for(int i = 0; i < m_nSide; i++) //遍历每条边
- {
- if( Distance(curPt,m_topPt[i]) + Distance(curPt,m_topPt[i+1]) <= SideLength +2 )
- {
- yesno= true;
- break;
- }
- }
- return yesno;
- }
- void CPolygon::DrawRound(CDC *pDC,COLORREF colorRound) //画小圆圈(默认红色)
- {
- POINT *signPt = new POINT[m_nSide]; //指向标记点
- for(int j = 0; j < m_nSide; j++)
- {
- signPt[j] = CaleSignPt(m_centPt, m_topPt[j]);
- }
- POINT *topPtL = new POINT[m_nSide]; //顶点小左点
- POINT *topPtR = new POINT[m_nSide]; //顶点小右点
- for(int i = 0; i < m_nSide; i++)
- {
- topPtL[i].x = signPt[i].x - 4;
- topPtL[i].y = signPt[i].y - 4;
- topPtR[i].x = signPt[i].x + 4;
- topPtR[i].y = signPt[i].y + 4;
- }
- HDC hdc = pDC->GetSafeHdc();
- HPEN newPen = ::CreatePen(0,0, colorRound);
- HBRUSH newBrush = ::CreateSolidBrush(colorRound);
- SelectObject(hdc,newPen);
- SelectObject(hdc,newBrush);
- for(int n = 0; n < m_nSide; n++)
- {
- Ellipse(hdc,topPtL[n].x,topPtL[n].y, topPtR[n].x,topPtR[n].y);
- }
- DeleteObject(newPen);
- DeleteObject(newBrush);
- delete signPt;
- delete topPtL;
- delete topPtR;
- }
- bool CPolygon::Select(CDC *pDC,CPoint point) //选定
- {
- bool yesno = false;
- POINT curPt;
- curPt.x = point.x ;
- curPt.y = point.y ;
- if(IsOnPolygon(curPt) == true)
- {
- DrawRound(pDC); //画小圈
- // ::MessageBox(m_hWnd,"中了","提示",NULL);
- m_oldPt = curPt;
- yesno = true;
- }
- return yesno;
- }
- void CPolygon::Move(CDC *pDC,CPoint point) //图形移动
- {
- POINT curPt;
- curPt = point;
- POINT centOldPt = m_centPt; //老中心点
- m_centPt.x = centOldPt.x + curPt.x - m_oldPt.x; //重新计算中心点
- m_centPt.y = centOldPt.y + curPt.y - m_oldPt.y;
- POINT *topOldPt = new POINT[m_nSide];
- for(int i = 0; i < m_nSide; i++)
- {
- topOldPt[i].x = m_topPt[i].x; //传值
- topOldPt[i].y = m_topPt[i].y;
- }
- for(int j = 0; j < m_nSide; j++)
- {
- m_topPt[j].x = topOldPt[j].x + curPt.x - m_oldPt.x;
- m_topPt[j].y = topOldPt[j].y + curPt.y - m_oldPt.y;
- }
- Draw(pDC,m_topPt, topOldPt);
- delete topOldPt;
- m_oldPt = curPt;
- }
- void CPolygon::Mirror(CDC *pDC,CPoint point) //镜像方法(以点为参照)
- {
- POINT curPt;
- curPt = point;
- m_oldPt = m_MirEndPt;
- m_MirEndPt = curPt;
- m_MirTopPt = new POINT[m_nSide];
- POINT *OldMirTopPt = new POINT[m_nSide];
- for(int i = 0; i < m_nSide; i++)
- {
- OldMirTopPt[i].x = m_MirTopPt[i].x;
- OldMirTopPt[i].y = m_MirTopPt[i].y;
- }
- for(int j = 0; j < m_nSide; j++)
- {
- m_MirTopPt[j] = GetMirPt(m_MirBegPt, m_MirEndPt, m_topPt[j]);
- }
- DrawMirLine(pDC,m_MirBegPt,m_MirEndPt); //画镜像直线
- Draw(pDC,m_MirTopPt, OldMirTopPt);
- delete OldMirTopPt;
- m_oldPt = curPt;
- }
- void CPolygon::Zoom(CDC *pDC,CPoint point) //缩放
- {
- //Update(pDC);
- POINT curPt;
- curPt = point;
- m_Radius = Distance(curPt, m_centPt); //重新计算半径
- POINT *OldTopPt =new POINT[m_nSide]; //存老顶点
- for(int i = 0; i < m_nSide; i++)
- {
- OldTopPt[i].x = m_topPt[i].x;
- OldTopPt[i].y = m_topPt[i].y;
- }
- CalculateTopPt(m_topPt, m_Radius); //重新计算各顶点
- Draw(pDC,m_topPt, OldTopPt);
- delete OldTopPt;
- }
- void CPolygon::Rotate(CDC *pDC,CPoint point) //旋转
- {
- Update(pDC);
- double Pi = 3.14159;
- double radian = Pi * this->m_angle/180; //化成弧度
- POINT *topOldPt = new POINT[m_nSide];
- for(int i = 0; i < m_nSide; i++)
- {
- topOldPt[i].x = m_topPt[i].x; //传值
- topOldPt[i].y = m_topPt[i].y;
- }
- for(int j = 0; j < m_nSide; j++)
- {
- m_topPt[j] = CalRotatePt(m_centPt, topOldPt[j], radian);
- }
- Draw(pDC,m_topPt, topOldPt);
- delete topOldPt;
- }
- void CPolygon::SetBorder(int i)
- {
- m_nSide = i;
- }
- void CPolygon::SetSide(int side)
- {
- this->m_nSide = side;
- }
- CPoint CPolygon::GetPosBegin()
- {
- return m_centPt;
- }
- CPoint CPolygon::GetPosEnd()
- {
- CPoint point;
- point.x = m_nSide;
- point.y = m_Radius;
- return point;
- }
- void CPolygon::SetPosBegin(CPoint point)
- {
- m_centPt = point;
- }
- void CPolygon::SetPosEnd(CPoint point)
- {
- m_nSide = point.x;
- m_Radius = point.y;
- }
- POINT * CPolygon::GetPosBorder()
- {
- return m_topPt;
- }
- void CPolygon::SetPosBorder(POINT *point)
- {
- m_topPt = point;
- }
- // 功 能: 计算点绕指定点旋转dbAngle个角度后的点
- // 输入参数: 定 点 POINT ptCenter
- // 弧度 double dbAngle
- // 返 回 值: 旋转到的位置 POINT ptDest;
- POINT CPolygon::CalRotatePt(POINT ptCenter,POINT ptPos,double dbAngle)
- {
- struct tagMatrix //旋转矩阵
- {
- double r11, r12, r13;
- double r21, r22, r23;
- double r31, r32, r33;
- }matrix;
- matrix.r11 = (double)cos(dbAngle);
- matrix.r21 = (double)sin(dbAngle);
- matrix.r31 = 0.0;
- matrix.r12 = (double)(-sin(dbAngle));
- matrix.r22 = (double)cos(dbAngle);
- matrix.r32 = 0.0;
- matrix.r13 = (double)((1 - cos(dbAngle)) * ptCenter.x + ptCenter.y * sin(dbAngle));
- matrix.r23 = (double)((1 - cos(dbAngle)) * ptCenter.y - ptCenter.x * sin(dbAngle));
- matrix.r33 = 1.0;
- POINT ptDest;
- ptDest.x = (int)(matrix.r11 * ptPos.x + matrix.r12 * ptPos.y + matrix.r13);
- ptDest.y = (int)(matrix.r21 * ptPos.x + matrix.r22 * ptPos.y + matrix.r23);
- return ptDest;
- }
- bool CPolygon::SelectOnePt(CDC *pDC, CPoint point)
- {
- bool yesno = false;
- POINT curPt;
- curPt = point;
- for(int i = 0; i < m_nSide; i++)
- {
- if(curPt.x == m_topPt[i].x && curPt.y == m_topPt[i].y )
- {
- DrawRound(pDC);
- m_oldPt = curPt;
- yesno = true;
- break;
- }
- }
- return yesno;
- }
- /*功 能:求一点关于直线对称的点
- 输入参数:直线起点:ptBegin,直线终点:ptEnd,待求点:ptCur
- 返 回 值:对称点ptNew */
- POINT CPolygon::GetMirPt(const POINT& ptBegin, const POINT& ptEnd,POINT ptCur)
- {
- POINT ptNew;
- double length = Distance(ptBegin,ptEnd);
- if(length == 0)
- return ptNew=ptCur;
- double t1 = 2. * ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.y-ptBegin.y)/length);
- double t2 = ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.x-ptBegin.x)/length)
- - ((ptEnd.y-ptBegin.y)/length) * ((ptEnd.y-ptBegin.y)/length);
- ptNew.x =(int)(ptCur.x*t2 + ptCur.y*t1 + ptBegin.x*(-t2) - ptBegin.y*t1 + ptBegin.x);
- ptNew.y =(int)(ptCur.x*t1 + ptCur.y*(-t2) + ptBegin.y*t2 - ptBegin.x*t1 + ptBegin.y);
- return ptNew;
- }
- //画镜像直线
- void CPolygon::DrawMirLine(CDC *pDC,POINT MirBegPt, POINT MirEndPt)
- {
- HDC hdc = pDC->GetSafeHdc();
- HPEN newPen = CreatePen(0,0,RGB(255,0,0)^GetBkColor(hdc));
- HPEN oldPen = (HPEN)SelectObject(hdc,newPen);
- int oldR2 = SetROP2(hdc,R2_XORPEN);
- ::MoveToEx(hdc,MirBegPt.x,MirBegPt.y,NULL);
- ::LineTo(hdc,m_oldPt.x,m_oldPt.y);
- ::MoveToEx(hdc,MirBegPt.x,MirBegPt.y,NULL);
- ::LineTo(hdc,MirEndPt.x,MirEndPt.y);
- SetROP2(hdc,oldR2);
- SelectObject(hdc,oldPen);
- ::DeleteObject(newPen);
- ::DeleteObject(oldPen);
- }
- //销毁镜像直线
- void CPolygon::KillMirLine(CDC *pDC)
- {
- HDC hdc = pDC->GetSafeHdc();
- HPEN newPen = CreatePen(0,0,GetBkColor(hdc)); //用背景色重画
- HPEN oldPen = (HPEN)SelectObject(hdc,newPen);
- ::MoveToEx(hdc,m_MirBegPt.x,m_MirBegPt.y,NULL);
- ::LineTo(hdc,m_MirEndPt.x,m_MirEndPt.y);
- SelectObject(hdc,oldPen);
- ::DeleteObject(newPen);
- ::DeleteObject(oldPen);
- }
- //镜像时左键点击
- void CPolygon::OnMirLBtnDn(CDC *pDC,CPoint point)
- {
- HDC hdc = pDC->GetSafeHdc();
- m_MirBegPt = m_MirEndPt = m_oldPt = point;
- }
- void CPolygon::SetAngle(int angle)
- {
- m_angle = angle;
- }
- //计算一条线末端外的标记点
- POINT CPolygon::CaleSignPt(POINT centPt, POINT orderPt)
- {
- int dLen = 6; //标记点与末端点的距离
- POINT signPt;
- int r = Distance(centPt, orderPt);
- int xLen = abs(centPt.x - orderPt.x);
- int yLen = abs(centPt.y - orderPt.y);
- int xAdd = dLen * xLen/r;
- int yAdd = dLen * yLen/r;
- if(centPt.x <= orderPt.x && centPt.y >= orderPt.y) //第一象限
- {
- signPt.x = orderPt.x + xAdd;
- signPt.y = orderPt.y - yAdd;
- }
- if(centPt.x <= orderPt.x && centPt.y <= orderPt.y) //第二象限
- {
- signPt.x = orderPt.x + xAdd;
- signPt.y = orderPt.y + yAdd;
- }
- if(centPt.x >= orderPt.x && centPt.y <= orderPt.y) //第三象限
- {
- signPt.x = orderPt.x - xAdd;
- signPt.y = orderPt.y + yAdd;
- }
- if(centPt.x >= orderPt.x && centPt.y >= orderPt.y) //第四象限
- {
- signPt.x = orderPt.x - xAdd;
- signPt.y = orderPt.y - yAdd;
- }
- return signPt;
- }
- void CPolygon::Delete(CDC *pDC)
- {
- Update(pDC);
- HDC hdc = pDC->GetSafeHdc();
- HPEN newPen = ::CreatePen(m_borderStyle,
- m_borderWidth, GetBkColor(hdc));
- SelectObject(hdc,GetStockObject(NULL_BRUSH)); //空画刷
- ::SelectObject(hdc,newPen);
- Polygon( hdc, m_topPt, m_nSide );
- ::DeleteObject(newPen);
- }