PolygonClipView.cpp
上传用户:shwyly
上传日期:2007-11-25
资源大小:47k
文件大小:7k
- // PolygonClipView.cpp : implementation of the CPolygonClipView class
- //
- #include "stdafx.h"
- #include "PolygonClip.h"
- #include "PolygonClipDoc.h"
- #include "PolygonClipView.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CPolygonClipView
- IMPLEMENT_DYNCREATE(CPolygonClipView, CView)
- BEGIN_MESSAGE_MAP(CPolygonClipView, CView)
- //{{AFX_MSG_MAP(CPolygonClipView)
- ON_WM_RBUTTONDOWN()
- ON_WM_LBUTTONDOWN()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CPolygonClipView construction/destruction
- CPolygonClipView::CPolygonClipView()
- {
- // TODO: add construction code here
- outLength=new int;
- *outLength = 0;
- inLength = 0;
- count =1;//记录画线次数
- //初始化输出点列表
- for(int i=0;i<MAX;i++)
- {
- outVertexArray[i].x=0;
- outVertexArray[i].y=0;
- }
- }
- CPolygonClipView::~CPolygonClipView()
- {
- }
- BOOL CPolygonClipView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CView::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CPolygonClipView drawing
- void CPolygonClipView::OnDraw(CDC* pDC)
- {
- CPolygonClipDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- // TODO: add draw code for native data here
- CPen Pen(PS_SOLID,1,RGB(0, 0, 0));
- CPen *pOldPen;
- pOldPen=pDC->SelectObject(&Pen);
- screen.left=200;
- screen.bottom=100;
- screen.right=500;
- screen.top=300;
- pDC->Rectangle(&screen);
- CString str;
- str.Format("请在屏幕上用左键点出%d个多边形顶点,点击右键执行剪裁",EdgeNum);
- pDC->TextOut(0,0,str);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CPolygonClipView diagnostics
- #ifdef _DEBUG
- void CPolygonClipView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CPolygonClipView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CPolygonClipDoc* CPolygonClipView::GetDocument() // non-debug version is inline
- {
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPolygonClipDoc)));
- return (CPolygonClipDoc*)m_pDocument;
- }
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CPolygonClipView message handlers
- void CPolygonClipView::Intersect(Vertex *s, Vertex *p, Edge clipBoundary, Vertex *I)
- {//求多边形的边与剪裁边的交点I
- if(clipBoundary[0].y==clipBoundary[1].y)//水平剪裁边
- {
- I->y=clipBoundary[0].y;
- I->x=s->x+(clipBoundary[0].y - s->y)*(p->x - s->x)/(p->y - s->y);
- }
- else//竖直边剪裁
- {
- I->x = clipBoundary[0].x;
- I->y = s->y+(clipBoundary[0].x - s->x)*(p->y - s->y)/(p->x - s->x);
- }
- }
- bool CPolygonClipView::Inside(Vertex *testVertex, Edge clipBoundary)
- {
- if(clipBoundary[1].x > clipBoundary[0].x)//剪裁边为窗口下边
- {
- if(testVertex->y >= clipBoundary[0].y)
- return true;
- }
- else if(clipBoundary[1].x < clipBoundary[0].x)//剪裁边为窗口上边
- {
- if(testVertex->y <= clipBoundary[0].y)
- return true;
- }
- else if(clipBoundary[1].y > clipBoundary[0].y)//剪裁边为窗口右边
- {
- if(testVertex->x <= clipBoundary[0].x)
- return true;
- }
- else if(clipBoundary[1].y < clipBoundary[0].y)//剪裁边为窗口左边
- {
- if(testVertex->x >= clipBoundary[0].x)
- return true;
- }
- return false;
- }
- void CPolygonClipView::Output(Vertex *newVertex, int *outLength, VertexArray outVertexArray)
- {
- //将newVertex加入到结果多边形顶点表outVertexArray中
- outVertexArray[*outLength].x = newVertex->x;
- outVertexArray[*outLength].y = newVertex->y;
-
- (*outLength)++;
- }
- void CPolygonClipView::SHPolygonClip(int inLength, VertexArray inVertexArray, int *outLength, VertexArray outVertexArray, Edge clipBoundary)
- {
- Vertex *s,*p,I;
- int j;
-
- *outLength = 0;
- s=&(inVertexArray[inLength-1]);
- for(j=0;j<inLength;j++)
- {
- p=&(inVertexArray[j]);
- if( Inside(p,clipBoundary) )
- {
- if(Inside(s,clipBoundary))
- Output(p,outLength,outVertexArray);//情况1
- else
- {
- Intersect(s,p,clipBoundary,&I);//情况4
- Output(&I,outLength,outVertexArray);
- Output(p,outLength,outVertexArray);
- }
- }
- else if(Inside(s,clipBoundary))
- {
- Intersect(s,p,clipBoundary,&I);//情况2
- Output(&I,outLength,outVertexArray);
- }//情况3无输出
- s=p;
- }
- }
- void CPolygonClipView::OnRButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- if(count==EdgeNum+1)
- {
- //剪裁左边
- clipBoundary[0].x=screen.left;
- clipBoundary[0].y=screen.top;
- clipBoundary[1].x=screen.left;
- clipBoundary[1].y=screen.bottom;
- SHPolygonClip(inLength,inVertexArray,outLength,outVertexArray,clipBoundary);
-
-
- //剪裁下边,注意此时输出多边形变为输入多边形!!
- clipBoundary[0].x=screen.left;
- clipBoundary[0].y=screen.bottom;
- clipBoundary[1].x=screen.right;
- clipBoundary[1].y=screen.bottom;
- inLength=*outLength;
- //初始化输出点列表
- for(int i=0;i<MAX;i++)
- {
- inVertexArray[i].x=0;
- inVertexArray[i].y=0;
- }
- SHPolygonClip(inLength,outVertexArray,outLength,inVertexArray,clipBoundary);
-
-
- //剪裁右边
- clipBoundary[0].x=screen.right;
- clipBoundary[0].y=screen.bottom;
- clipBoundary[1].x=screen.right;
- clipBoundary[1].y=screen.top;
- inLength=*outLength;
- //初始化输出点列表
- for(i=0;i<MAX;i++)
- {
- outVertexArray[i].x=0;
- outVertexArray[i].y=0;
- }
- SHPolygonClip(inLength,inVertexArray,outLength,outVertexArray,clipBoundary);
-
-
- //剪裁上边
- clipBoundary[0].x=screen.right;
- clipBoundary[0].y=screen.top;
- clipBoundary[1].x=screen.left;
- clipBoundary[1].y=screen.top;
- inLength=*outLength;
- //初始化输出点列表
- for(i=0;i<MAX;i++)
- {
- inVertexArray[i].x=0;
- inVertexArray[i].y=0;
- }
- SHPolygonClip(inLength,outVertexArray,outLength,inVertexArray,clipBoundary);
-
-
- //描出结果
- CDC *pDC=GetDC();
- CPen pen(PS_SOLID,3,RGB(100,220,253));
- CPen* pOldPen=pDC->SelectObject(&pen);
- //inVertexArray为最后的输出多变形
- for(i=1;inVertexArray[i].x!=0 && inVertexArray[i].y!=0;i++)
- {
- pDC->MoveTo(inVertexArray[i-1].x,inVertexArray[i-1].y);
- pDC->LineTo(inVertexArray[i].x,inVertexArray[i].y);
- }
- pDC->MoveTo(inVertexArray[i-1].x,inVertexArray[i-1].y);
- pDC->LineTo(inVertexArray[0].x,inVertexArray[0].y);
- }
-
- CView::OnRButtonDown(nFlags, point);
- }
- void CPolygonClipView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- // startpoint=point;
- // lastendpoint=point;
- // SetCapture();
- CDC *pDC=GetDC();
- if(count<=EdgeNum)
- {
- inVertexArray[inLength].x=point.x;
- inVertexArray[inLength].y=point.y;
- if(count!=1)
- {
- pDC->MoveTo(inVertexArray[inLength-1].x,inVertexArray[inLength-1].y);
- pDC->LineTo(point);
- }
- if(count==EdgeNum)
- {
- pDC->MoveTo(point);
- pDC->LineTo(inVertexArray[0].x,inVertexArray[0].y);
- }
- inLength++;
- count++;
- }
- CView::OnLButtonDown(nFlags, point);
- }