Polygon.cpp
上传用户:ckg1000
上传日期:2013-01-26
资源大小:630k
文件大小:11k
源码类别:

CAD

开发平台:

Visual C++

  1. // Polygon.cpp: implementation of the CPolygon class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CAD2006.h"
  6. #include "Polygon.h"
  7. #include "math.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CPolygon::CPolygon()
  17. {
  18. m_status = NoClicked;
  19. }
  20. CPolygon::~CPolygon()
  21. {
  22. }
  23. int CPolygon::Distance(POINT Pt1, POINT Pt2)  //求两点之间的距离
  24. {
  25. int nDist;
  26. nDist =(int)(sqrt((Pt1.x - Pt2.x)*(Pt1.x - Pt2.x) + (Pt1.y - Pt2.y)*(Pt1.y - Pt2.y)));
  27. return nDist;
  28. }
  29. void CPolygon::CalculateTopPt(POINT PtArray[], int nRadius) //计算一个圆上等分点的坐标
  30. {
  31. const double Pi = 3.14159;   ////////////////
  32. double angle = 2*Pi/m_nSide;                            
  33. double angleT = 0;     
  34. for(int nIndex = 0; nIndex < m_nSide; nIndex++, angleT += angle)
  35. {
  36. POINT NowPoint;
  37. NowPoint.x = (int)(m_centPt.x + nRadius * sin(angleT));
  38. NowPoint.y = (int)(m_centPt.y - nRadius * cos(angleT));
  39. PtArray[nIndex] = NowPoint;
  40. }
  41. }
  42. void CPolygon::Draw(CDC *pDC,POINT topPt[], POINT OldTopPt[])  //输入两组点
  43. {
  44. HPEN newPen = ::CreatePen(m_borderStyle,
  45. m_borderWidth,m_borderColor^pDC->GetBkColor());
  46. HBRUSH newBrush = ::CreateSolidBrush(m_backColor^ pDC->GetBkColor());
  47. pDC->SelectObject(newPen);
  48. pDC->SelectObject(newBrush);
  49. int oldR2 = pDC->SetROP2(R2_XORPEN);
  50. pDC->Polygon( OldTopPt, m_nSide );
  51. pDC->Polygon(  topPt, m_nSide );
  52. pDC->SetROP2(oldR2);
  53. ::DeleteObject(newPen);
  54. ::DeleteObject(newBrush);
  55. }
  56. void CPolygon::Update(CDC *pDC)   //更新图形
  57. {
  58. HDC hdc = pDC->GetSafeHdc();
  59. DrawRound(pDC,GetBkColor(hdc));  //先擦掉小圆圈
  60. KillMirLine(pDC);                //擦掉镜像直线
  61. }
  62. void CPolygon::OnLbuttondown(CDC *pDC,CPoint point)
  63. {
  64. POINT curPoint;   //左键点击的点
  65. curPoint.x = point.x ;   //取低16位 x 值
  66. curPoint.y = point.y ;   //取高16位 y 值
  67. switch(m_status)
  68. {
  69. case NoClicked:
  70. {
  71. m_centPt = m_oldPt = curPoint;
  72. m_status = FirstClicked;
  73. }
  74. break;
  75. case FirstClicked:
  76. {
  77. m_endPt = curPoint;
  78. m_status = NoClicked;
  79. }
  80. break;
  81. }
  82. }
  83. void CPolygon::Onmousemove(CDC *pDC,CPoint point)
  84. {
  85. POINT curPoint;
  86. curPoint.x = point.x ;
  87. curPoint.y = point.y ;
  88. if( m_status == FirstClicked )
  89. {
  90. m_topPt = new POINT[m_nSide];     //动态分配一个顶点数组
  91. POINT *OldtopPt = new POINT[m_nSide];
  92. m_endPt = curPoint;
  93. m_Radius = Distance(m_centPt,m_endPt);
  94. int OldRadius = Distance(m_centPt,m_oldPt);
  95. CalculateTopPt(m_topPt, m_Radius); //重新计算每顶点坐标
  96. CalculateTopPt(OldtopPt, OldRadius);
  97. Draw(pDC,m_topPt, OldtopPt);
  98. m_oldPt = curPoint;
  99. }
  100. }
  101. bool CPolygon::IsOnPolygon(POINT curPt)   //判断一个点是否在多边型上
  102. {
  103. bool yesno= false;
  104. int SideLength = Distance(m_topPt[0],m_topPt[1]);  //计算边长
  105. for(int i = 0; i < m_nSide; i++) //遍历每条边
  106. {
  107. if( Distance(curPt,m_topPt[i]) + Distance(curPt,m_topPt[i+1]) <= SideLength +2 )
  108. {
  109. yesno= true;
  110. break;
  111. }
  112. }
  113. return yesno;
  114. }
  115. void CPolygon::DrawRound(CDC *pDC,COLORREF colorRound)   //画小圆圈(默认红色)
  116. {
  117. POINT *signPt = new POINT[m_nSide];   //指向标记点
  118. for(int j = 0; j < m_nSide; j++)
  119. {
  120. signPt[j] = CaleSignPt(m_centPt, m_topPt[j]);
  121. }
  122. POINT *topPtL = new POINT[m_nSide];   //顶点小左点
  123. POINT *topPtR = new POINT[m_nSide];   //顶点小右点
  124. for(int i = 0; i < m_nSide; i++)
  125. {
  126. topPtL[i].x = signPt[i].x - 4; 
  127. topPtL[i].y = signPt[i].y - 4;
  128. topPtR[i].x = signPt[i].x + 4; 
  129. topPtR[i].y = signPt[i].y + 4;
  130. }
  131. HDC hdc = pDC->GetSafeHdc();
  132. HPEN newPen = ::CreatePen(0,0, colorRound);
  133. HBRUSH newBrush = ::CreateSolidBrush(colorRound);
  134. SelectObject(hdc,newPen);
  135. SelectObject(hdc,newBrush);
  136. for(int n = 0; n < m_nSide; n++)
  137. {
  138. Ellipse(hdc,topPtL[n].x,topPtL[n].y, topPtR[n].x,topPtR[n].y);  
  139. }
  140. DeleteObject(newPen);
  141. DeleteObject(newBrush);
  142. delete signPt;
  143. delete topPtL;
  144. delete topPtR;
  145. }
  146. bool CPolygon::Select(CDC *pDC,CPoint point)  //选定
  147. {
  148. bool yesno = false;
  149. POINT curPt;
  150. curPt.x = point.x ;
  151. curPt.y = point.y ;
  152. if(IsOnPolygon(curPt) == true)
  153. {
  154. DrawRound(pDC); //画小圈
  155. // ::MessageBox(m_hWnd,"中了","提示",NULL);
  156. m_oldPt  = curPt;
  157. yesno = true;
  158. }
  159. return yesno;
  160. }
  161. void CPolygon::Move(CDC *pDC,CPoint point)  //图形移动
  162. {
  163. POINT curPt;
  164. curPt = point;
  165. POINT centOldPt = m_centPt;  //老中心点
  166. m_centPt.x = centOldPt.x + curPt.x - m_oldPt.x;  //重新计算中心点
  167. m_centPt.y = centOldPt.y + curPt.y - m_oldPt.y;
  168. POINT *topOldPt = new POINT[m_nSide];
  169. for(int i = 0; i < m_nSide; i++)
  170. {
  171. topOldPt[i].x = m_topPt[i].x;    //传值
  172. topOldPt[i].y = m_topPt[i].y;
  173. }
  174. for(int j = 0; j < m_nSide; j++)
  175. {
  176. m_topPt[j].x = topOldPt[j].x + curPt.x - m_oldPt.x;
  177. m_topPt[j].y = topOldPt[j].y + curPt.y - m_oldPt.y;
  178. }
  179. Draw(pDC,m_topPt, topOldPt);
  180. delete topOldPt;
  181. m_oldPt = curPt;
  182. }
  183. void CPolygon::Mirror(CDC *pDC,CPoint point) //镜像方法(以点为参照)
  184. {
  185. POINT curPt;
  186. curPt = point;
  187. m_oldPt = m_MirEndPt;
  188. m_MirEndPt = curPt;
  189. m_MirTopPt = new POINT[m_nSide];
  190. POINT *OldMirTopPt = new POINT[m_nSide];
  191. for(int i = 0; i < m_nSide; i++)
  192. {
  193. OldMirTopPt[i].x = m_MirTopPt[i].x;
  194. OldMirTopPt[i].y = m_MirTopPt[i].y;
  195. }
  196. for(int j = 0; j < m_nSide; j++)
  197. {
  198. m_MirTopPt[j] = GetMirPt(m_MirBegPt, m_MirEndPt, m_topPt[j]);
  199. }
  200. DrawMirLine(pDC,m_MirBegPt,m_MirEndPt);  //画镜像直线
  201. Draw(pDC,m_MirTopPt, OldMirTopPt);
  202. delete OldMirTopPt;
  203. m_oldPt = curPt;
  204. }
  205. void CPolygon::Zoom(CDC *pDC,CPoint point)  //缩放
  206. {
  207. //Update(pDC);
  208. POINT curPt;
  209. curPt = point;
  210. m_Radius = Distance(curPt, m_centPt);             //重新计算半径
  211. POINT *OldTopPt =new POINT[m_nSide];              //存老顶点
  212. for(int i = 0; i < m_nSide; i++)
  213. {
  214. OldTopPt[i].x = m_topPt[i].x;
  215. OldTopPt[i].y = m_topPt[i].y;
  216. }
  217. CalculateTopPt(m_topPt, m_Radius);      //重新计算各顶点
  218. Draw(pDC,m_topPt, OldTopPt);
  219. delete OldTopPt;
  220. }
  221. void CPolygon::Rotate(CDC *pDC,CPoint point)  //旋转
  222. {
  223. Update(pDC); 
  224. double Pi = 3.14159;
  225. double radian = Pi * this->m_angle/180;      //化成弧度
  226. POINT *topOldPt = new POINT[m_nSide];
  227. for(int i = 0; i < m_nSide; i++)
  228. {
  229. topOldPt[i].x = m_topPt[i].x;    //传值
  230. topOldPt[i].y = m_topPt[i].y;
  231. }
  232. for(int j = 0; j < m_nSide; j++)
  233. {
  234. m_topPt[j] = CalRotatePt(m_centPt, topOldPt[j], radian);
  235. }
  236. Draw(pDC,m_topPt, topOldPt);
  237. delete topOldPt;
  238. }
  239. void CPolygon::SetBorder(int i)
  240. {
  241. m_nSide = i;
  242. }
  243. void CPolygon::SetSide(int side)
  244. {
  245. this->m_nSide = side;
  246. }
  247. CPoint CPolygon::GetPosBegin()
  248. {
  249. return m_centPt;
  250. }
  251. CPoint CPolygon::GetPosEnd()
  252. {
  253. CPoint point;
  254. point.x = m_nSide;
  255. point.y = m_Radius;
  256. return point;
  257. }
  258. void CPolygon::SetPosBegin(CPoint point)
  259. {
  260. m_centPt = point;
  261. }
  262. void CPolygon::SetPosEnd(CPoint point)
  263. {
  264. m_nSide = point.x;
  265. m_Radius = point.y;
  266. }
  267. POINT * CPolygon::GetPosBorder()
  268. {
  269. return m_topPt;
  270. }
  271. void CPolygon::SetPosBorder(POINT *point)
  272. {
  273. m_topPt = point;
  274. }
  275. // 功    能: 计算点绕指定点旋转dbAngle个角度后的点
  276. // 输入参数: 定 点 POINT ptCenter
  277. //           弧度 double dbAngle 
  278. // 返 回 值: 旋转到的位置 POINT ptDest;
  279. POINT CPolygon::CalRotatePt(POINT ptCenter,POINT ptPos,double dbAngle)
  280. {
  281. struct tagMatrix             //旋转矩阵
  282. {
  283. double r11, r12, r13;
  284. double r21, r22, r23;
  285. double r31, r32, r33;
  286. }matrix;
  287. matrix.r11 = (double)cos(dbAngle);
  288. matrix.r21 = (double)sin(dbAngle);
  289. matrix.r31 = 0.0;
  290. matrix.r12 = (double)(-sin(dbAngle));
  291. matrix.r22 = (double)cos(dbAngle);
  292. matrix.r32 = 0.0;
  293. matrix.r13 = (double)((1 - cos(dbAngle)) * ptCenter.x + ptCenter.y * sin(dbAngle));
  294. matrix.r23 = (double)((1 - cos(dbAngle)) * ptCenter.y - ptCenter.x * sin(dbAngle));
  295. matrix.r33 = 1.0;
  296. POINT ptDest;
  297. ptDest.x = (int)(matrix.r11 * ptPos.x + matrix.r12 * ptPos.y + matrix.r13);
  298. ptDest.y = (int)(matrix.r21 * ptPos.x + matrix.r22 * ptPos.y + matrix.r23);
  299. return ptDest;
  300. }
  301. bool CPolygon::SelectOnePt(CDC *pDC, CPoint point)
  302. {
  303. bool yesno = false;
  304. POINT curPt;
  305. curPt = point;
  306. for(int i = 0; i < m_nSide; i++)
  307. {
  308. if(curPt.x == m_topPt[i].x && curPt.y == m_topPt[i].y )
  309. {
  310. DrawRound(pDC);
  311. m_oldPt  = curPt;
  312. yesno = true;
  313. break;
  314. }
  315. }
  316. return yesno;
  317. }
  318. /*功    能:求一点关于直线对称的点
  319.   输入参数:直线起点:ptBegin,直线终点:ptEnd,待求点:ptCur
  320.   返 回 值:对称点ptNew                                          */
  321. POINT CPolygon::GetMirPt(const POINT& ptBegin, const POINT& ptEnd,POINT ptCur)
  322. {
  323. POINT ptNew;
  324. double length = Distance(ptBegin,ptEnd);
  325. if(length == 0)
  326. return ptNew=ptCur;
  327. double t1 = 2. * ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.y-ptBegin.y)/length);
  328. double t2 = ((ptEnd.x-ptBegin.x)/length) * ((ptEnd.x-ptBegin.x)/length)
  329. - ((ptEnd.y-ptBegin.y)/length) * ((ptEnd.y-ptBegin.y)/length);
  330. ptNew.x =(int)(ptCur.x*t2 + ptCur.y*t1 + ptBegin.x*(-t2) - ptBegin.y*t1 + ptBegin.x);
  331. ptNew.y =(int)(ptCur.x*t1 + ptCur.y*(-t2) + ptBegin.y*t2 - ptBegin.x*t1 + ptBegin.y);
  332. return ptNew;
  333. }
  334. //画镜像直线
  335. void CPolygon::DrawMirLine(CDC *pDC,POINT MirBegPt, POINT MirEndPt)
  336. {
  337. HDC hdc = pDC->GetSafeHdc();
  338. HPEN newPen = CreatePen(0,0,RGB(255,0,0)^GetBkColor(hdc));
  339. HPEN oldPen = (HPEN)SelectObject(hdc,newPen);
  340. int oldR2 = SetROP2(hdc,R2_XORPEN);
  341. ::MoveToEx(hdc,MirBegPt.x,MirBegPt.y,NULL);
  342. ::LineTo(hdc,m_oldPt.x,m_oldPt.y);
  343. ::MoveToEx(hdc,MirBegPt.x,MirBegPt.y,NULL);
  344. ::LineTo(hdc,MirEndPt.x,MirEndPt.y);
  345. SetROP2(hdc,oldR2);
  346. SelectObject(hdc,oldPen);
  347. ::DeleteObject(newPen);
  348. ::DeleteObject(oldPen);
  349. }
  350. //销毁镜像直线
  351. void CPolygon::KillMirLine(CDC *pDC)
  352. {
  353. HDC hdc = pDC->GetSafeHdc();
  354. HPEN newPen = CreatePen(0,0,GetBkColor(hdc));   //用背景色重画
  355. HPEN oldPen = (HPEN)SelectObject(hdc,newPen);
  356. ::MoveToEx(hdc,m_MirBegPt.x,m_MirBegPt.y,NULL);
  357. ::LineTo(hdc,m_MirEndPt.x,m_MirEndPt.y);
  358. SelectObject(hdc,oldPen);
  359. ::DeleteObject(newPen);
  360. ::DeleteObject(oldPen);
  361. }
  362. //镜像时左键点击
  363. void CPolygon::OnMirLBtnDn(CDC *pDC,CPoint point)  
  364. {
  365. HDC hdc = pDC->GetSafeHdc();
  366. m_MirBegPt = m_MirEndPt = m_oldPt = point;
  367. }
  368. void CPolygon::SetAngle(int angle)
  369. {
  370. m_angle = angle;
  371. }
  372. //计算一条线末端外的标记点
  373. POINT CPolygon::CaleSignPt(POINT centPt, POINT orderPt)
  374. {
  375. int dLen = 6;     //标记点与末端点的距离
  376. POINT signPt;
  377. int r = Distance(centPt, orderPt);
  378. int xLen = abs(centPt.x - orderPt.x);
  379. int yLen = abs(centPt.y - orderPt.y);
  380. int xAdd =  dLen * xLen/r;
  381. int yAdd =  dLen * yLen/r;
  382. if(centPt.x <= orderPt.x && centPt.y >= orderPt.y)  //第一象限
  383. {
  384. signPt.x = orderPt.x + xAdd;
  385. signPt.y = orderPt.y - yAdd;
  386. }
  387. if(centPt.x <= orderPt.x && centPt.y <= orderPt.y) //第二象限
  388. {
  389. signPt.x = orderPt.x + xAdd;
  390. signPt.y = orderPt.y + yAdd;
  391. }
  392. if(centPt.x >= orderPt.x && centPt.y <= orderPt.y) //第三象限
  393. {
  394. signPt.x = orderPt.x - xAdd;
  395. signPt.y = orderPt.y + yAdd;
  396. }
  397. if(centPt.x >= orderPt.x && centPt.y >= orderPt.y) //第四象限
  398. {
  399. signPt.x = orderPt.x - xAdd;
  400. signPt.y = orderPt.y - yAdd;
  401. }
  402. return signPt;
  403. }
  404. void CPolygon::Delete(CDC *pDC)
  405. {
  406. Update(pDC);
  407. HDC hdc = pDC->GetSafeHdc();
  408. HPEN newPen = ::CreatePen(m_borderStyle,
  409. m_borderWidth, GetBkColor(hdc));
  410. SelectObject(hdc,GetStockObject(NULL_BRUSH)); //空画刷
  411. ::SelectObject(hdc,newPen);
  412. Polygon( hdc, m_topPt, m_nSide );
  413. ::DeleteObject(newPen);
  414. }