PolygonClipView.cpp
上传用户:shwyly
上传日期:2007-11-25
资源大小:47k
文件大小:7k
源码类别:

绘图程序

开发平台:

Visual C++

  1. // PolygonClipView.cpp : implementation of the CPolygonClipView class
  2. //
  3. #include "stdafx.h"
  4. #include "PolygonClip.h"
  5. #include "PolygonClipDoc.h"
  6. #include "PolygonClipView.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CPolygonClipView
  14. IMPLEMENT_DYNCREATE(CPolygonClipView, CView)
  15. BEGIN_MESSAGE_MAP(CPolygonClipView, CView)
  16. //{{AFX_MSG_MAP(CPolygonClipView)
  17. ON_WM_RBUTTONDOWN()
  18. ON_WM_LBUTTONDOWN()
  19. //}}AFX_MSG_MAP
  20. END_MESSAGE_MAP()
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CPolygonClipView construction/destruction
  23. CPolygonClipView::CPolygonClipView()
  24. {
  25. // TODO: add construction code here
  26. outLength=new int;
  27. *outLength = 0;
  28. inLength = 0;
  29. count =1;//记录画线次数
  30. //初始化输出点列表
  31. for(int i=0;i<MAX;i++)
  32. {
  33. outVertexArray[i].x=0;
  34. outVertexArray[i].y=0;
  35. }
  36. }
  37. CPolygonClipView::~CPolygonClipView()
  38. {
  39. }
  40. BOOL CPolygonClipView::PreCreateWindow(CREATESTRUCT& cs)
  41. {
  42. // TODO: Modify the Window class or styles here by modifying
  43. //  the CREATESTRUCT cs
  44. return CView::PreCreateWindow(cs);
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CPolygonClipView drawing
  48. void CPolygonClipView::OnDraw(CDC* pDC)
  49. {
  50. CPolygonClipDoc* pDoc = GetDocument();
  51. ASSERT_VALID(pDoc);
  52. // TODO: add draw code for native data here
  53. CPen Pen(PS_SOLID,1,RGB(0, 0, 0));
  54. CPen *pOldPen;
  55. pOldPen=pDC->SelectObject(&Pen);
  56. screen.left=200;
  57. screen.bottom=100;
  58. screen.right=500;
  59. screen.top=300;
  60. pDC->Rectangle(&screen);
  61. CString str;
  62. str.Format("请在屏幕上用左键点出%d个多边形顶点,点击右键执行剪裁",EdgeNum);
  63. pDC->TextOut(0,0,str);
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CPolygonClipView diagnostics
  67. #ifdef _DEBUG
  68. void CPolygonClipView::AssertValid() const
  69. {
  70. CView::AssertValid();
  71. }
  72. void CPolygonClipView::Dump(CDumpContext& dc) const
  73. {
  74. CView::Dump(dc);
  75. }
  76. CPolygonClipDoc* CPolygonClipView::GetDocument() // non-debug version is inline
  77. {
  78. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPolygonClipDoc)));
  79. return (CPolygonClipDoc*)m_pDocument;
  80. }
  81. #endif //_DEBUG
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CPolygonClipView message handlers
  84. void CPolygonClipView::Intersect(Vertex *s, Vertex *p, Edge clipBoundary, Vertex *I)
  85. {//求多边形的边与剪裁边的交点I
  86. if(clipBoundary[0].y==clipBoundary[1].y)//水平剪裁边
  87. {
  88. I->y=clipBoundary[0].y;
  89. I->x=s->x+(clipBoundary[0].y - s->y)*(p->x - s->x)/(p->y - s->y);
  90. }
  91. else//竖直边剪裁
  92. {
  93. I->x = clipBoundary[0].x;
  94. I->y = s->y+(clipBoundary[0].x - s->x)*(p->y - s->y)/(p->x - s->x);
  95. }
  96. }
  97. bool CPolygonClipView::Inside(Vertex *testVertex, Edge clipBoundary)
  98. {
  99. if(clipBoundary[1].x > clipBoundary[0].x)//剪裁边为窗口下边
  100. {
  101. if(testVertex->y >= clipBoundary[0].y)
  102. return true;
  103. }
  104. else if(clipBoundary[1].x < clipBoundary[0].x)//剪裁边为窗口上边
  105. {
  106. if(testVertex->y <= clipBoundary[0].y)
  107. return true;
  108. }
  109. else if(clipBoundary[1].y > clipBoundary[0].y)//剪裁边为窗口右边
  110. {
  111. if(testVertex->x <= clipBoundary[0].x)
  112. return true;
  113. }
  114. else if(clipBoundary[1].y < clipBoundary[0].y)//剪裁边为窗口左边
  115. {
  116. if(testVertex->x >= clipBoundary[0].x)
  117. return true;
  118. }
  119. return false;
  120. }
  121. void CPolygonClipView::Output(Vertex *newVertex, int *outLength, VertexArray outVertexArray)
  122. {
  123. //将newVertex加入到结果多边形顶点表outVertexArray中
  124. outVertexArray[*outLength].x = newVertex->x;
  125. outVertexArray[*outLength].y = newVertex->y;
  126. (*outLength)++;
  127. }
  128. void CPolygonClipView::SHPolygonClip(int inLength, VertexArray inVertexArray, int *outLength, VertexArray outVertexArray, Edge clipBoundary)
  129. {
  130. Vertex *s,*p,I;
  131. int j;
  132. *outLength = 0;
  133. s=&(inVertexArray[inLength-1]);
  134. for(j=0;j<inLength;j++)
  135. {
  136. p=&(inVertexArray[j]);
  137. if( Inside(p,clipBoundary) )
  138. {
  139. if(Inside(s,clipBoundary))
  140. Output(p,outLength,outVertexArray);//情况1
  141. else
  142. {
  143. Intersect(s,p,clipBoundary,&I);//情况4
  144. Output(&I,outLength,outVertexArray);
  145. Output(p,outLength,outVertexArray);
  146. }
  147. }
  148. else if(Inside(s,clipBoundary))
  149. {
  150. Intersect(s,p,clipBoundary,&I);//情况2
  151. Output(&I,outLength,outVertexArray);
  152. }//情况3无输出
  153. s=p;
  154. }
  155. }
  156. void CPolygonClipView::OnRButtonDown(UINT nFlags, CPoint point) 
  157. {
  158. // TODO: Add your message handler code here and/or call default
  159. if(count==EdgeNum+1)
  160. {
  161. //剪裁左边
  162. clipBoundary[0].x=screen.left;
  163. clipBoundary[0].y=screen.top;
  164. clipBoundary[1].x=screen.left;
  165. clipBoundary[1].y=screen.bottom;
  166. SHPolygonClip(inLength,inVertexArray,outLength,outVertexArray,clipBoundary);
  167. //剪裁下边,注意此时输出多边形变为输入多边形!!
  168. clipBoundary[0].x=screen.left;
  169. clipBoundary[0].y=screen.bottom;
  170. clipBoundary[1].x=screen.right;
  171. clipBoundary[1].y=screen.bottom;
  172. inLength=*outLength;
  173. //初始化输出点列表
  174. for(int i=0;i<MAX;i++)
  175. {
  176. inVertexArray[i].x=0;
  177. inVertexArray[i].y=0;
  178. }
  179. SHPolygonClip(inLength,outVertexArray,outLength,inVertexArray,clipBoundary);
  180. //剪裁右边
  181. clipBoundary[0].x=screen.right;
  182. clipBoundary[0].y=screen.bottom;
  183. clipBoundary[1].x=screen.right;
  184. clipBoundary[1].y=screen.top;
  185. inLength=*outLength;
  186. //初始化输出点列表
  187. for(i=0;i<MAX;i++)
  188. {
  189. outVertexArray[i].x=0;
  190. outVertexArray[i].y=0;
  191. }
  192. SHPolygonClip(inLength,inVertexArray,outLength,outVertexArray,clipBoundary);
  193. //剪裁上边
  194. clipBoundary[0].x=screen.right;
  195. clipBoundary[0].y=screen.top;
  196. clipBoundary[1].x=screen.left;
  197. clipBoundary[1].y=screen.top;
  198. inLength=*outLength;
  199. //初始化输出点列表
  200. for(i=0;i<MAX;i++)
  201. {
  202. inVertexArray[i].x=0;
  203. inVertexArray[i].y=0;
  204. }
  205. SHPolygonClip(inLength,outVertexArray,outLength,inVertexArray,clipBoundary);
  206. //描出结果
  207. CDC *pDC=GetDC();
  208. CPen pen(PS_SOLID,3,RGB(100,220,253));
  209. CPen* pOldPen=pDC->SelectObject(&pen);
  210. //inVertexArray为最后的输出多变形
  211. for(i=1;inVertexArray[i].x!=0 && inVertexArray[i].y!=0;i++)
  212. {
  213. pDC->MoveTo(inVertexArray[i-1].x,inVertexArray[i-1].y);
  214. pDC->LineTo(inVertexArray[i].x,inVertexArray[i].y);
  215. }
  216. pDC->MoveTo(inVertexArray[i-1].x,inVertexArray[i-1].y);
  217. pDC->LineTo(inVertexArray[0].x,inVertexArray[0].y);
  218. }
  219. CView::OnRButtonDown(nFlags, point);
  220. }
  221. void CPolygonClipView::OnLButtonDown(UINT nFlags, CPoint point) 
  222. {
  223. // TODO: Add your message handler code here and/or call default
  224. // startpoint=point;
  225. // lastendpoint=point;
  226. // SetCapture();
  227. CDC *pDC=GetDC();
  228. if(count<=EdgeNum)
  229. {
  230. inVertexArray[inLength].x=point.x;
  231. inVertexArray[inLength].y=point.y;
  232. if(count!=1)
  233. {
  234. pDC->MoveTo(inVertexArray[inLength-1].x,inVertexArray[inLength-1].y);
  235. pDC->LineTo(point);
  236. }
  237. if(count==EdgeNum)
  238. {
  239. pDC->MoveTo(point);
  240. pDC->LineTo(inVertexArray[0].x,inVertexArray[0].y);
  241. }
  242. inLength++;
  243. count++;
  244. }
  245. CView::OnLButtonDown(nFlags, point);
  246. }