Click here to Skip to main content
15,896,348 members
Articles / Desktop Programming / MFC

A General Polygon Management Routine

Rate me:
Please Sign up or sign in to vote.
4.25/5 (5 votes)
24 Oct 20015 min read 85.8K   1.4K   32  
A class to make handling polygons easier.
#include "stdafx.h"
#include "DoublePoint.h"
#include "Polygon.h"
#include "DtoR.h"
#include "rotate.h"
#include "SaveDC.h"

/****************************************************************************
*                                    round
* Inputs:
*       double v: input value 
* Result: int
*       
* Effect: 
*       �
****************************************************************************/

static int round(double v)
    {
     if(v < 0)
	return (int)(v - 0.5);
     else
	return (int)(v + 0.5);
    } // round

/****************************************************************************
*                             CPolygon::Read
* Inputs:
*       const CString & filename: File name
* Result: BOOL
*       TRUE if successful
*	FALSE if error
* Effect: 
*       Reads the data from the file into the raw coordinate array
****************************************************************************/

BOOL CPolygon::Read(const CString & filename)
    {
     points.RemoveAll();
     transformed.SetSize(0);
     CStdioFile f;
     if(!f.Open(filename, CFile::modeRead))
	return FALSE;

     heading = 0.0;
     scaling = 1.0;
     
     CString s;
     int i = 0;
     while(f.ReadString(s))
	{ /* add points */
         CDoublePoint pt;
	 pt.x = atoi(s);
	 int n = s.Find(',');
	 if(n < 0)
	    continue;
	 s = s.Mid(n+1);
	 pt.y = atoi(s);
         points.SetAtGrow(points.GetSize(), pt);
	} /* add points */
     f.Close();
     return TRUE;
    } // CPolygon::Read

/****************************************************************************
*                               CPolygon::Load
* Inputs:
*       LPCTSTR resname: Resource name
* Result: BOOL
*       TRUE if successful
*	FALSE if error
* Effect: 
*       Reads the points from the resource
****************************************************************************/

BOOL CPolygon::Load(LPCTSTR resname)
    {
     points.RemoveAll();
     transformed.SetSize(0);
     HRSRC res = ::FindResource(AfxGetInstanceHandle(),
				resname,
				_T("POINTS"));
     if(res == NULL)
	return FALSE;
     HGLOBAL p = ::LoadResource(AfxGetInstanceHandle(), res);
     if(p == NULL)
	return FALSE;
     LPVOID data = ::LockResource(p);
     
     DWORD len = ::SizeofResource(AfxGetInstanceHandle(), res);
     CString s((LPTSTR)data, len);
     while(s.GetLength() > 0)
	{ /* parse string */
	 CDoublePoint pt;
	 pt.x = atoi(s);
	 int n = s.Find(',');
	 if(n >= 0)
	    { /* has second value */
	     s = s.Mid(n+1);
	     pt.y = atoi(s);
	     points.Add(pt);
	    } /* has second value */
	 n = s.Find(_T('\n'));
	 if(n < 0)
	    break;
	 s = s.Mid(n+1);
	} /* parse string */
     return TRUE;
    } // CPolygon::Load

/****************************************************************************
*                               CPolygon::Load
* Inputs:
*       UINT resid: Resource id
* Result: BOOL
*       TRUE if it was able to read the resource
*	FALSE if it failed to read the resource
* Effect: 
*       Reads the text, stored as a resource of ID "POINTS"
****************************************************************************/

BOOL CPolygon::Load(UINT resid)
    {
     return Load(MAKEINTRESOURCE(resid));
    } // CPolygon::Load

/****************************************************************************
*                           CPolygon::Transform
* Inputs:
*       double angle: Desired transformation angle
*	double scaling: Scaling factor to apply
*       BOOL force: (default FALSE): set TRUE to force transformation
* Result: void
*       
* Effect: 
*       Transforms the coordinates from virtual space to real rotational space
****************************************************************************/

CRect CPolygon::Transform(double angle, double scale, BOOL force /* = FALSE */)
    {
     //--------------------------------------
     // The coordinate space we are using
     // is assumed to be that of the mapped
     // space, that is
     //        +y
     //        |
     //   -x --+-- +x
     //        |
     //        -y

     CRect bb(INT_MAX,INT_MIN,INT_MIN,INT_MAX);
     if(!force &&
	angle == heading && // always an int converted to a double
	scale == scaling && // always integer ratio
	transformed.GetSize() == points.GetSize())
	return CRect(0,0,0,0); // nothing to do
     scaling = scale;
     heading = angle;

     transformed.SetSize(points.GetSize());
     for(int i = 0; i < points.GetSize(); i++)
	{ /* transform points */
	 CDoublePoint newpoint = rotate(points[i], -angle, scale);
	 transformed[i].x = (int)newpoint.x;
	 transformed[i].y = (int)newpoint.y;
	 bb.left = min(transformed[i].x, bb.left);
	 bb.right = max(transformed[i].x, bb.right);
	 bb.top = max(transformed[i].y, bb.top);
	 bb.bottom = min(transformed[i].y, bb.bottom);
	} /* transform points */
     return bb;
    } // CPolygon::Transform

/****************************************************************************
*                             CPolygon::Draw
* Inputs:
*       CDC & dc: DC to use
* Result: CRect
*       The bounding area of the aircraft, in client coordinates
* Effect: 
*       Draws the image
* Notes:
*	The image is drawn with the pen and brush selected into the DC at
*	the time this method is called
****************************************************************************/

void CPolygon::Draw(CDC & dc, CDoublePoint pt)
    {
     CSaveDC sdc(dc);
     CPoint org = dc.GetWindowOrg();
     CRect r;
     dc.SetWindowOrg(-(int)pt.x, -(int)pt.y);
     CPoint * pointarray = transformed.GetData();
     dc.Polygon(pointarray, transformed.GetSize());
    } // CPolygon::Draw

/****************************************************************************
*                            CPolygon::GetInputBB
* Result: CRect
*       Rectangle representing the boudning box of the static input data
****************************************************************************/

CRect CPolygon::GetInputBB()
    {
     CRect r;
     r.SetRectEmpty();
     for(int i = 0; i < points.GetSize(); i++)
	{ /* compute bound */
	 int n = round(points[i].x);
	 if(n < r.left)
	    r.left = n;
	 if(n > r.right)
	    r.right = n;
	 n = round(points[i].y);
	 if(n < r.bottom)
	    r.bottom = n;
	 if(n > r.top)
	    r.top = n;
	} /* compute bound */
     return r;
    } // CPolygon::GetInputBB

/****************************************************************************
*                              CPolygon::GetRgn
* Result: CRgn *
*       Pointer to a region object which represents the region
* Effect: 
*       Creates a polygon region based on the transformed points
****************************************************************************/

CRgn * CPolygon::GetRgn()
    {
     CRgn * rgn = new CRgn;
     rgn->CreatePolygonRgn(transformed.GetData(), points.GetSize(), ALTERNATE);
     return rgn;
    } // CPolygon::GetRgn

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Retired
United States United States
PhD, Computer Science, Carnegie Mellon University, 1975
Certificate in Forensic Science and the Law, Duquesne University, 2008

Co-Author, [i]Win32 Programming[/i]

Comments and Discussions