From b7db0ef8509b94d50c992cad7d4d156d565d32cd Mon Sep 17 00:00:00 2001 From: charras Date: Sun, 12 Oct 2008 15:29:43 +0000 Subject: [PATCH] updating polygon lib code. A bug removed. --- pcbnew/zones_test_and_combine_areas.cpp | 16 +- polygon/PolyLine.cpp | 183 ++++++------ polygon/PolyLine.h | 4 +- polygon/math_for_graphics.cpp | 1 - polygon/polygon_test_point_inside.cpp | 355 ++++++++++++++++++++++++ polygon/polygon_test_point_inside.h | 19 ++ 6 files changed, 461 insertions(+), 117 deletions(-) create mode 100644 polygon/polygon_test_point_inside.cpp create mode 100644 polygon/polygon_test_point_inside.h diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index b4fbb9addc..77ad12936b 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -169,16 +169,8 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) int y2i = p->GetY( is2 ); int x2f = p->GetX( is2_next ); int y2f = p->GetY( is2_next ); - int ret = FindSegmentIntersections( x1i, - y1i, - x1f, - y1f, - style, - x2i, - y2i, - x2f, - y2f, - style2 ); + int ret = FindSegmentIntersections( x1i, y1i, x1f, y1f, style, + x2i, y2i, x2f, y2f, style2 ); if( ret ) { // intersection between non-adjacent sides @@ -246,8 +238,6 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" ); str += wxT( "Manual correction is recommended." ); wxMessageBox( str ); - -// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState; } return -1; // arcs intersect with other sides, error } @@ -427,8 +417,6 @@ int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtilit curr_area->m_Netname.GetData() ); str += wxT( "Therefore, these areas can't be combined." ); wxMessageBox( str ); - -// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState; } } } diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 2b4e510961..e5167f7e45 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -30,10 +30,11 @@ CPolyLine::CPolyLine() CPolyLine::~CPolyLine() { Undraw(); - if ( m_Kbool_Poly_Engine ) + if( m_Kbool_Poly_Engine ) delete m_Kbool_Poly_Engine; } + /** Function NormalizeWithKbool * Use the Kbool Library to clip contours: if outlines are crossing, the self-crossing polygon * is converted to non self-crossing polygon by adding extra points at the crossing locations @@ -83,8 +84,8 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo hole_array.push_back( hole ); while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // store hole { - int x = (int)m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int)m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); hole->push_back( x ); hole->push_back( y ); } @@ -99,8 +100,8 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo bool first = true; while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) { // foreach point in the polygon - int x = (int)m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int)m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); if( first ) { first = false; @@ -116,13 +117,13 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo } else if( aExtraPolyList ) // a new outside contour is found: create a new CPolyLine { - polyline = new CPolyLine; // create new poly + polyline = new CPolyLine; // create new poly aExtraPolyList->push_back( polyline ); // put it in array bool first = true; - while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour + while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour { - int x = (int)m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int)m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); if( first ) { first = false; @@ -227,8 +228,8 @@ int CPolyLine::AddPolygonsToBoolEng( Bool_Engine* aBooleng, { while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) { - int x = (int)m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int)m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); aBooleng->AddPoint( x, y ); count++; } @@ -259,7 +260,7 @@ int CPolyLine::AddPolygonsToBoolEng( Bool_Engine* aBooleng, * @return error: 0 if Ok, 1 if error */ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector * arc_array, - bool aConvertHoles ) + bool aConvertHoles ) { if( m_Kbool_Poly_Engine ) { @@ -300,8 +301,8 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< { while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) { - int x = (int)m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int)m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); booleng->AddPoint( x, y ); } @@ -563,12 +564,12 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) } - int CPolyLine::NormalizeAreaOutlines( std::vector * pa, bool bRetainArcs ) { return NormalizeWithKbool( pa, bRetainArcs ); } + // Restore arcs to a polygon where they were replaced with steps // If pa != NULL, also use polygons in pa array // @@ -1215,20 +1216,20 @@ void CPolyLine::Hatch() if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) ) { ok = FindLineSegmentIntersection( a, slope, - corner[ic].x, corner[ic].y, - corner[i_start_contour].x, - corner[i_start_contour].y, - side_style[ic], - &x, &y, &x2, &y2 ); + corner[ic].x, corner[ic].y, + corner[i_start_contour].x, + corner[i_start_contour].y, + side_style[ic], + &x, &y, &x2, &y2 ); i_start_contour = ic + 1; } else { ok = FindLineSegmentIntersection( a, slope, - corner[ic].x, corner[ic].y, - corner[ic + 1].x, corner[ic + 1].y, - side_style[ic], - &x, &y, &x2, &y2 ); + corner[ic].x, corner[ic].y, + corner[ic + 1].x, corner[ic + 1].y, + side_style[ic], + &x, &y, &x2, &y2 ); } if( ok ) { @@ -1302,7 +1303,7 @@ void CPolyLine::Hatch() double y2 = yy[ip + 1] - dx * slope; m_HatchLines.push_back( CSegment( xx[ip], yy[ip], to_int( x1 ), to_int( y1 ) ) ); m_HatchLines.push_back( CSegment( xx[ip + 1], yy[ip + 1], to_int( x2 ), - to_int( y2 ) ) ); + to_int( y2 ) ) ); } } } @@ -1314,27 +1315,26 @@ void CPolyLine::Hatch() // test to see if a point is inside polyline // -bool CPolyLine::TestPointInside( int x, int y ) +bool CPolyLine::TestPointInside( int px, int py ) { - enum { - MAXPTS = 100 - }; if( !GetClosed() ) wxASSERT( 0 ); // define line passing through (x,y), with slope = 2/3; // get intersection points - double xx[MAXPTS], yy[MAXPTS]; + int xx, yy; double slope = (double) 2.0 / 3.0; - double a = y - slope * x; + double a = py - slope * px; int nloops = 0; int npts; + bool inside = false; // make this a loop so if my homebrew algorithm screws up, we try it again do { // now find all intersection points of line with polyline sides - npts = 0; + npts = 0; + inside = false; for( int icont = 0; icont px ) + inside = not inside; npts++; - wxASSERT( npts px ) + inside = not inside; npts++; - wxASSERT( npts x ) - ncount++; - } - - if( ncount % 2 ) - return TRUE; - else - return FALSE; + return inside; } // test to see if a point is inside polyline contour // -bool CPolyLine::TestPointInsideContour( int icont, int x, int y ) +bool CPolyLine::TestPointInsideContour( int icont, int px, int py ) { if( icont >= GetNumContours() ) return FALSE; - - enum { - MAXPTS = 100 - }; if( !GetClosed() ) wxASSERT( 0 ); - // define line passing through (x,y), with slope = 2/3; - // get intersection points - double xx[MAXPTS], yy[MAXPTS]; +// define line passing through (x,y), with slope = 2/3; +// get intersection points + int xx, yy; double slope = (double) 2.0 / 3.0; - double a = y - slope * x; + double a = py - slope * px; int nloops = 0; int npts; + bool inside = false; - // make this a loop so if my homebrew algorithm screws up, we try it again +// make this a loop so if my homebrew algorithm screws up, we try it again do { // now find all intersection points of line with polyline sides - npts = 0; + npts = 0; + inside = false; int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); for( int ic = istart; ic<=iend; ic++ ) @@ -1429,29 +1420,35 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y ) int ok; if( ic == istart ) ok = FindLineSegmentIntersection( a, slope, - corner[iend].x, corner[iend].y, - corner[istart].x, corner[istart].y, - side_style[corner.size() - 1], - &x, &y, &x2, &y2 ); + corner[iend].x, corner[iend].y, + corner[istart].x, corner[istart].y, + side_style[iend], + &x, &y, &x2, &y2 ); else ok = FindLineSegmentIntersection( a, slope, - corner[ic - 1].x, corner[ic - 1].y, - corner[ic].x, corner[ic].y, - side_style[ic - 1], - &x, &y, &x2, &y2 ); + corner[ic - 1].x, corner[ic - 1].y, + corner[ic].x, corner[ic].y, + side_style[ic - 1], + &x, &y, &x2, &y2 ); if( ok ) { - xx[npts] = (int) x; - yy[npts] = (int) y; + xx = (int) x; + yy = (int) y; npts++; - wxASSERT( npts px ) + inside = not inside; } if( ok == 2 ) { - xx[npts] = (int) x2; - yy[npts] = (int) y2; + xx = (int) x2; + yy = (int) y2; npts++; - wxASSERT( npts px ) + inside = not inside; } } @@ -1461,20 +1458,7 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y ) wxASSERT( npts % 2==0 ); // odd number of intersection points, error - // count intersection points to right of (x,y), if odd (x,y) is inside polyline - int ncount = 0; - for( int ip = 0; ip x ) - ncount++; - } - - if( ncount % 2 ) - return TRUE; - else - return FALSE; + return inside; } @@ -1545,7 +1529,6 @@ void CPolyLine::SetEndContour( int ic, bool end_contour ) } - void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ) { // get radius diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index 7b4a2719f0..db0ab950e6 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -47,10 +47,10 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); #define to_int( x ) (int) round( (x) ) #ifndef min -#define min( x1, x2 ) ( (x1) > (x2) ) ? (x2) : (x1) +#define min( x1, x2 ) ( (x1) > (x2) ? (x2) : (x1) ) #endif #ifndef max -#define max( x1, x2 ) ( (x1) > (x2) ) ? (x1) : (x2) +#define max( x1, x2 ) ( (x1) > (x2) ? (x1) : (x2) ) #endif class CRect diff --git a/polygon/math_for_graphics.cpp b/polygon/math_for_graphics.cpp index 7bace1e7fd..428c8e3b5e 100644 --- a/polygon/math_for_graphics.cpp +++ b/polygon/math_for_graphics.cpp @@ -639,7 +639,6 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y int * x, int * y, double * d ) { double a, b, dist; - // first, test for intersection if( x1i == x1f && x2i == x2f ) { diff --git a/polygon/polygon_test_point_inside.cpp b/polygon/polygon_test_point_inside.cpp new file mode 100644 index 0000000000..ef5bc9e2c9 --- /dev/null +++ b/polygon/polygon_test_point_inside.cpp @@ -0,0 +1,355 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: polygon_test_point_inside.cpp +///////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "PolyLine.h" + +using namespace std; + +/* this algo uses the the Jordan curve theorem to find if a point is inside or outside a polygon: + * It run a semi-infinite line horizontally (increasing x, fixed y) + * out from the test point, and count how many edges it crosses. + * At each crossing, the ray switches between inside and outside. + * If odd nimber, the test point is inside the polygon + * This is called the Jordan curve theorem, or sometimes referred to as the "even-odd" test. + */ + +/* 2 versions are given. + * the second version is GPL (currently used) + * the first version is for explanations and tests (used to test the second version) + * both use the same algorithm. +*/ +#if 0 + +/* This text and the algorithm come from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html + * + * PNPOLY - Point Inclusion in Polygon Test + * W. Randolph Franklin (WRF) + * + * Table of Contents + * + * 1. The C Code <#The C Code> + * 2. The Method <#The Method> + * 3. Originality <#Originality> + * 4. The Inequality Tests are Tricky <#The Inequality Tests are Tricky> + * 5. C Semantics <#C Semantics> + * 6. Point on a (Boundary) Edge <#Point on an Edge> + * 7. Multiple Components and Holes <#Listing the Vertices> + * 8. Testing Which One of Many Polygons Contains the Point <#Testing a + * Point Against Many Polygons> + * 9. Explanation of /"for (i = 0, j = nvert-1; i < nvert; j = i++)"/ + * <#Explanation> + * 10. Fortran Code for the Point in Polygon Test <#Fortran Code for the + * Point in Polygon Test> + * 11. Converting the Code to All Integers <#Converting the Code to All + * Integers> + * 12. License to Use <#License to Use> + * + * The C Code + * + * Here is the code, for reference. Excluding lines with only braces, there + * are only /7 lines/ of code. + * + * int pnpoly(int nvert, float *vertx, float *verty, float ref_pointX, float ref_pointY) + * { + * int i, j, c = 0; + * for (i = 0, j = nvert-1; i < nvert; j = i++) { + * if ( ((verty[i]>ref_pointY) != (verty[j]>ref_pointY)) && + * (ref_pointX < (vertx[j]-vertx[i]) * (ref_pointY-verty[i]) / (verty[j]-verty[i]) + vertx[i]) ) + * c = !c; + * } + * return c; + * } + * + * Argument Meaning + * nvert Number of vertices in the polygon. Whether to repeat the first + * vertex at the end is discussed below. + * vertx, verty Arrays containing the x- and y-coordinates of the + * polygon's vertices. + * ref_pointX, ref_pointY X- and y-coordinate of the test point. + * + * + * The Method + * + * I run a semi-infinite ray horizontally (increasing x, fixed y) out from + * the test point, and count how many edges it crosses. At each crossing, + * the ray switches between inside and outside. This is called the /Jordan + * curve theorem/. + * + * The case of the ray going thru a vertex is handled correctly via a + * careful selection of inequalities. Don't mess with this code unless + * you're familiar with the idea of /Simulation of Simplicity/. This + * pretends to shift the ray infinitesimally to one side so that it either + * clearly intersects, or clearly doesn't touch. Since this is merely a + * conceptual, infinitesimal, shift, it never creates an intersection that + * didn't exist before, and never destroys an intersection that clearly + * existed before. + * + * The ray is tested against each edge thus: + * + * 1. Is the point in the half-plane below the extended edge? and + * 2. Is the point's X coordinate within the edge's X-range? + * + * Handling endpoints here is tricky. + * + * + * Originality + * + * I make no claim to having invented the idea. However in 1970, I did + * produce the Fortran code given below on my own, and include it in a + * package of cartographic SW publicly-distributed by David Douglas, Dept + * of Geography, Simon Fraser U and U of Ottawa. + * + * Earlier implementations of point-in-polygon testing presumably exist, + * tho the code might never have been released. Pointers to prior art, + * especially publicly available code, are welcome. One early publication, + * which doesn't handle the point on an edge, and has a typo, is this: + * + * M Shimrat, "Algorithm 112, Position of Point Relative to Polygon", + * /Comm. ACM/ 5(8), Aug 1962, p 434. + * + * A well-written recent summary is this: + * + * E Haines, /Point in Polygon Strategies/, + * http://www.acm.org/pubs/tog/editors/erich/ptinpoly/, 1994. + * + * + * The Inequality Tests are Tricky + * + * If translating the program to another language, be sure to get the + * inequalities in the conditional correct. They were carefully chosen to + * make the program work correctly when the point is vertically below a vertex. + * + * Several people have thought that my program was wrong, when really + * /they/ had gotten the inequalities wrong. + * + * + * C Semantics + * + * My code uses the fact that, in the C language, when executing the code + |a&&b|, if |a| is false, then |b| must not be evaluated. If your + * compiler doesn't do this, then it's not implementing C, and you will get + * a divide-by-zero, i.a., when the test point is vertically in line with a + * vertical edge. When translating this code to another language with + * different semantics, then you must implement this test explicitly. + * + * + * Point on a (Boundary) Edge + * + * PNPOLY partitions the plane into points inside the polygon and points + * outside the polygon. Points that are on the boundary are classified as + * either inside or outside. + * + * 1. + * + * Any particular point is always classified consistently the same + * way. In the following figure, consider what PNPOLY would say when + * the red point, /P/, is tested against the two triangles, /T_L / + * and /T_R /. Depending on internal roundoff errors, PNPOLY may say + * that /P/ is in /T_L / or in /T_R /. However it will always give + * the same answer when /P/ is tested against those triangles. That + * is, if PNPOLY finds that /P/ is in /T_L /, then it will find that + * /P/ is not /T_R /. If PNPOLY finds that /P/ is not in /T_L /, then + * it will find that /P/ is in /T_R /. + * + * 2. If you want to know when a point is exactly on the boundary, you + * need another program. This is only one of many functions that + * PNPOLY lacks; it also doesn't predict tomorrow's weather. You are + * free to extend PNPOLY's source code. + * + * 3. The first reason for this is the numerical analysis position that + * you should not be testing exact equality unless your input is + * exact. Even then, computational roundoff error would often make + * the result wrong. + * + * 4. The second reason is that, if you partition a region of the plane + * into polygons, i.e., form a planar graph, then PNPOLY will locate + * each point into exactly one polygon. In other words, PNPOLY + * considers each polygon to be topologically a semi-open set. This + * makes things simpler, i.e., causes fewer special cases, if you use + * PNPOLY as part of a larger system. Examples of this include + * locating a point in a planar graph, and intersecting two planar + * graphs. + * + * + * Explanation of /"for (i = 0, j = nvert-1; i < nvert; j = i++)"/ + * + * The intention is to execute the loop for each i from 0 to nvert-1. For + * each iteration, j is i-1. However that wraps, so if i=0 then j=nvert-1. + * Therefore the current edge runs between verts j and i, and the loop is + * done once per edge. In detail: + * + * 1. Start by setting i and j: + * i = 0 + * j = nvert-1 + * 2. If i You may use my material for non-profit research + * and education, provided that you credit me, and link back to my home page. + * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html, + * 05/20/2008 20:36:42 + */ + +bool TestPointInsidePolygon( std::vector aPolysList, + int istart, + int iend, + int refx, + int refy ) + +/** Function TestPointInsidePolygon + * test if a point is inside or outside a polygon. + * @param aPolysList: the list of polygons + * @param istart: the starting point of a given polygon in m_FilledPolysList. + * @param iend: the ending point of the polygon in m_FilledPolysList. + * @param refx, refy: the point coordinate to test + * @return true if the point is inside, false for outside + */ +{ + double ref_pointX = refx; + double ref_pointY = refy; + + bool inside = false; + + for( int ii = istart, jj = iend; ii <= iend; jj = ii++ ) + { + double seg_startX, seg_startY; // starting point for the segment to test + seg_startX = aPolysList[ii].x; + seg_startY = aPolysList[ii].y; + double seg_endX, seg_endY; // ending point for the segment to test + seg_endX = aPolysList[jj].x; + seg_endY = aPolysList[jj].y; + if( ( ( seg_startY > ref_pointY ) != (seg_endY > ref_pointY ) ) + && (ref_pointX < + (seg_endX - + seg_startX) * (ref_pointY - seg_startY) / (seg_endY - seg_startY) + seg_startX) ) + inside = not inside; + } + + return inside; +} + + +#else + +/* this algo come from freePCB. + */ + +bool TestPointInsidePolygon( std::vector aPolysList, + int istart, + int iend, + int refx, + int refy ) + +/** Function TestPointInsidePolygon + * test if a point is inside or outside a polygon. + * if a point is on a outline segment, it is considered outside the polygon + * @param aPolysList: the list of polygons + * @param istart: the starting point of a given polygon in m_FilledPolysList. + * @param iend: the ending point of the polygon in m_FilledPolysList. + * @param refx,refy: the point coordinate to test + * @return true if the point is inside, false for outside + * this algorithm come from FreePCB. + */ +{ + #define OUTSIDE_IF_ON_SIDE 0 // = 1 if we consider point on a side outside the polygon + // define line passing through (x,y), with slope = 0 (horizontal line) + // get intersection points + // count intersection points to right of (x,y), if odd (x,y) is inside polyline + int xx, yy; + double slope = 0; + double a = refy - slope * refx; + int ics, ice; + bool inside = false; + + // find all intersection points of line with polyline sides + for( ics = istart, ice = iend; ics <= iend; ice = ics++ ) + { + double x, y, x2, y2; + int ok = FindLineSegmentIntersection( a, slope, + aPolysList[ics].x, aPolysList[ics].y, + aPolysList[ice].x, aPolysList[ice].y, + 0, + &x, &y, + &x2, &y2 ); + if( ok ) + { + xx = (int) x; + yy = (int) y; +#if OUTSIDE_IF_ON_SIDE + if( xx == refx && yy == refy ) + return false; // (x,y) is on a side, call it outside + else +#endif + if( xx > refx ) + inside = not inside; + } + if( ok == 2 ) + { + xx = (int) x2; + yy = (int) y2; +#if OUTSIDE_IF_ON_SIDE + if( xx == refx && yy == refy ) + return false; // (x,y) is on a side, call it outside + else +#endif + if( xx > refx ) + inside = not inside; + } + } + + return inside; +} + + +#endif diff --git a/polygon/polygon_test_point_inside.h b/polygon/polygon_test_point_inside.h new file mode 100644 index 0000000000..89d22da25c --- /dev/null +++ b/polygon/polygon_test_point_inside.h @@ -0,0 +1,19 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: polygon_test_point_inside.h +///////////////////////////////////////////////////////////////////////////// + +using namespace std; + +/** Function TestPointInsidePolygon + * test if a point is inside or outside a polygon. + * @param aPolysList: the list of polygons + * @param istart: the starting point of a given polygon in m_FilledPolysList. + * @param iend: the ending point of the polygon in m_FilledPolysList. + * @param refx, refy: the point coordinate to test + * @return true if the point is inside, false for outside + */ +bool TestPointInsidePolygon( std::vector aPolysList, + int istart, + int iend, + int refx, + int refy);