Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A Matrix-Based 2-D Polygon Clipping Class

, 28 Mar 2003
An article on 2-D Polygon Clipping
polyclipdemo.zip
PolyClipDemo
PolyClipDemo.clw
PolyClipDemo.dsw
PolyClipDemo.dsp
PolyClipDemo.plg
PolyClipDemo.opt
res
PolyClipDemoDoc.ico
PolyClipDemo.ico
Toolbar.bmp
polyclipdemo1.zip
res
PolyClipDemo.ico
PolyClipDemoDoc.ico
Toolbar.bmp
polyclipdemoapp.zip
polyclipdemoapp1.zip
1// PolyClipDemoView.cpp : implementation of the CPolyClipDemoView class
//

#include "stdafx.h"
#include "PolyClipDemo.h"

#include "PolyClipDemoDoc.h"
#include "PolyClipDemoView.h"

#include "PolygonClip.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define NumberOfLines 10
#define NumberOfVerticies 9		// one more than the actual number (See below)
	
/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView

IMPLEMENT_DYNCREATE(CPolyClipDemoView, CView)

BEGIN_MESSAGE_MAP(CPolyClipDemoView, CView)
	//{{AFX_MSG_MAP(CPolyClipDemoView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView construction/destruction

CPolyClipDemoView::CPolyClipDemoView()
{
	// TODO: add construction code here
	m_pPolygonClip = 0;

}

CPolyClipDemoView::~CPolyClipDemoView()
{
}

BOOL CPolyClipDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView drawing

void CPolyClipDemoView::OnDraw(CDC* pDC)
{
	CPolyClipDemoDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// The code below is far from fancy, but it serves
	// to illustrate the idea...most of this shouldn't be
	// in OnDraw() -> Lines and polygons shouldn't be
	// generated here (slows things down during drawing)
	// but I'm lazy and all the important stuff can be found here
	// so it makes it easier to see what's happenin'
	double *pLineX1, *pLineX2, *pLineY1, *pLineY2;	
	double *pPolyVertsX, *pPolyVertsY;

	pLineX1 = new double[NumberOfLines];
	pLineX2 = new double[NumberOfLines];

	pLineY1 = new double[NumberOfLines];
	pLineY2 = new double[NumberOfLines];

	pPolyVertsX = new double[NumberOfVerticies];
	pPolyVertsY = new double[NumberOfVerticies];

	// Arbitrary origin for the lines
	double LineOrigin(100);

	// Generate some line coordinates and fill arrays
	for (unsigned int LineIndex = 0; LineIndex < 10; LineIndex++)
	{
		ASSERT(LineIndex < NumberOfLines);

		if (LineIndex < 5)		// Make horizontal lines
		{
			*(pLineX1 + LineIndex) = 100;
			*(pLineY1 + LineIndex) = LineOrigin;

			*(pLineX2 + LineIndex) = 1024 /*GetSystemMetrics(SM_CXSCREEN)*/ - 500;
			*(pLineY2 + LineIndex) = LineOrigin;
		}
		else					// Make vertical lines
		{
			*(pLineX1 + LineIndex) = LineOrigin - 120;
			*(pLineY1 + LineIndex) = 100;

			*(pLineX2 + LineIndex) = LineOrigin - 120;
			*(pLineY2 + LineIndex) = 768 /*GetSystemMetrics(SM_CYSCREEN)*/ - 200;
		}

		LineOrigin += 50;
		
		pDC->MoveTo(*(pLineX1 + LineIndex), *(pLineY1 + LineIndex));
		pDC->LineTo(*(pLineX2 + LineIndex), *(pLineY2 + LineIndex));
	}
	
	// And now the polygon...
	for (unsigned int VertexIndex = 0; VertexIndex < 9; VertexIndex++)
	{
		ASSERT(VertexIndex < NumberOfVerticies);
		switch (VertexIndex) 
		{
			case 0:		// Vertex 1
				*(pPolyVertsX + VertexIndex) = 160;
				*(pPolyVertsY + VertexIndex) = 160;
				break;
			case 1:		// Vertex 2
				*(pPolyVertsX + VertexIndex) = 190;
				*(pPolyVertsY + VertexIndex) = 160;
				break;
			case 2:		// Vertex 3
				*(pPolyVertsX + VertexIndex) = 190;
				*(pPolyVertsY + VertexIndex) = 220;
				break;
			case 3:		// Vertex 4
				*(pPolyVertsX + VertexIndex) = 225;
				*(pPolyVertsY + VertexIndex) = 220;
				break;
			case 4:		// etc...
				*(pPolyVertsX + VertexIndex) = 225;
				*(pPolyVertsY + VertexIndex) = 160;
				break;
			case 5:		
				*(pPolyVertsX + VertexIndex) = 1024/*GetSystemMetrics(SM_CXSCREEN)*/ - 550;
				*(pPolyVertsY + VertexIndex) = 160;
				break;
			case 6:		
				*(pPolyVertsX + VertexIndex) = 1024 /*GetSystemMetrics(SM_CXSCREEN)*/ - 550;
				*(pPolyVertsY + VertexIndex) = 500;
				break;
			case 7:		
				*(pPolyVertsX + VertexIndex) = 160;
				*(pPolyVertsY + VertexIndex) = 500;
				break;
			case 8:		// Close the polygon by ending up at the 1st point
				*(pPolyVertsX + VertexIndex) = 160;
				*(pPolyVertsY + VertexIndex) = 160;
				break;
			default:	// Error
				AfxMessageBox("Error.\n Cannot assign vertex.");		
				AfxAbort();  // Cheesy bail-out
		}
	}
	
	CPen aPen;
	aPen.CreatePen(PS_SOLID, PenSize, RGB(255, 0, 0));	
	CPen* pOldPen = pDC->SelectObject(&aPen);
	
	// Draw the polygon lines so we can see it
	for (unsigned int i = 0; i < (NumberOfVerticies - 1); i++)
	{
		ASSERT(i < VertexIndex);
		
		pDC->MoveTo(*(pPolyVertsX + i), *(pPolyVertsY + i));
		pDC->LineTo(*(pPolyVertsX + (i + 1)), *(pPolyVertsY + (i + 1)));
	}
	
	pDC->SelectObject(pOldPen);

	//////////////////////////////////
	//    BEGIN POLYGON CLIPPING	//
	//////////////////////////////////
	m_pPolygonClip = new CPolygonClip(NumberOfVerticies, NumberOfLines);
	ASSERT(m_pPolygonClip != NULL);

	unsigned int* pnSignChanges = 0;
	
	// Calculate the determinants
	pnSignChanges = m_pPolygonClip->CalcSiDeterm(pLineX1, pLineY1, 
												 pLineX2, pLineY2, 
												 pPolyVertsX, pPolyVertsY);

	// Find maximum number of intersections
	unsigned int nNumChanges = m_pPolygonClip->FindArrayMax(pnSignChanges);

	// Calculate line/polygon intersections
	bool bSuccess = m_pPolygonClip->CalculateIntersections(pLineX1, pLineX2,
														   pLineY1, pLineY2, 
														   pPolyVertsX, pPolyVertsY,
														   nNumChanges);
	// should include some other error 
	// handling routine...try/catch, etc...
	ASSERT(bSuccess);		

	// Draw the intersection points
	m_pPolygonClip->Draw(pDC);
	//////////////////////////////////
	//    END POLYGON CLIPPING		//
	//////////////////////////////////


	// Free the heap
	delete[] pLineX1;
	delete[] pLineX2;
	delete[] pLineY1;
	delete[] pLineY2;
	delete[] pPolyVertsX;
	delete[] pPolyVertsY;

	// Don't forget...
	delete m_pPolygonClip;

}

/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView printing

BOOL CPolyClipDemoView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CPolyClipDemoView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CPolyClipDemoView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView diagnostics

#ifdef _DEBUG
void CPolyClipDemoView::AssertValid() const
{
	CView::AssertValid();
}

void CPolyClipDemoView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CPolyClipDemoDoc* CPolyClipDemoView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPolyClipDemoDoc)));
	return (CPolyClipDemoDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPolyClipDemoView message handlers

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)

Share

About the Author

73Zeppelin
Other
Anonymous Proxy Anonymous Proxy
No Biography provided

| Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 29 Mar 2003
Article Copyright 2003 by 73Zeppelin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid