Determining if a point lies on the interior of a polygonWritten by Paul BourkeNovember 1987 Solution 1 (2D) The following is a simple solution to the problem often encountered in computergraphics, determining whether or not a point (x,y) lies inside or outside a 2Dpolygonally bounded plane. This is necessary for example in applications suchas polygon filling on raster devices. hatching in drafting software, anddetermining the intersection of multiple polygons. Consider a polygon made up of N vertices (xi,yi) where i ranges from 0 to N-1.The last vertex (xN,yN) is assumed to be the same as the first vertex (x0,y0),that is, the polygon is closed. To determine the status of a point (xp,yp)consider a horizontal ray emanating from (xp,yp) and to the right. If thenumber of times this ray intersects the line segments making up the polygon iseven then the point is outside the polygon. Whereas if the number ofintersections is odd then the point (xp,yp) lies inside the polygon. Thefollowing shows the ray for some sample points and should make the techniqueclear. Note: for the purposes of this discussion 0 will be considered even, the testfor even or odd will be based on modulus 2, that is, if the number ofintersections modulus 2 is 0 then the number is even, if it is 1 then it isodd. The only trick is what happens in the special cases when an edge or vertex ofthe polygon lies on the ray from (xp,yp). The possible situations are illustrated below. The thick lines above are not considered as valid intersections, the thin linesdo count as intersections. Ignoring the case of an edge lying along the ray oran edge ending on the ray ensures that the endpoints are only counted once. Note that this algorithm also works for polygons with holes as illustratedbelow The following C function returns INSIDE or OUTSIDE indicating the status of apoint P with respect to a polygon with N points. #define MIN(x,y) (x < y ? x : y) #define MAX(x,y) (x > y ? x : y) #define INSIDE 0 #define OUTSIDE 1 typedef struct { double x,y; } Point; int InsidePolygon(Point *polygon,int N,Point p) { int counter = 0; int i; double xinters; Point p1,p2; p1 = polygon[0]; for (i=1;i<=N;i++) { p2 = polygon[i % N]; if (p.y > MIN(p1.y,p2.y)) { if (p.y <= MAX(p1.y,p2.y)) { if (p.x <= MAX(p1.x,p2.x)) { if (p1.y != p2.y) { xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x; if (p1.x == p2.x || p.x <= xinters) counter++; } } } } p1 = p2; } if (counter % 2 == 0) return(OUTSIDE); else return(INSIDE); } The following code is by Randolph Franklin, it returns 1 for interiorpoints and 0 for exterior points. int pnpoly(int npol, float *xp, float *yp, float x, float y) { int i, j, c = 0; for (i = 0, j = npol-1; i < npol; j = i++) { if ((((yp[i] <= y) && (y < yp[j])) || ((yp[j] <= y) && (y < yp[i]))) && (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) c = !c; } return c; } Contribution by Alexander Motrichuk:InsidePolygonWithBounds.cpp. Contribution written in c# by Jerry Knauss: contains.c#. Solution 2 (2D)Another solution forwarded by Philippe Reverdy is to compute the sum of the angles made between the test point and each pair of pointsmaking up the polygon. If this sum is 2pi then the point is an interiorpoint, if 0 then the point is an exterior point. This also works forpolygons with holes given the polygon is defined with a path made up ofcoincident edges intoand out of the hole as is common practice in many CAD packages. The inside/outside test might then be defined in C astypedef struct { int h,v; } Point; int InsidePolygon(Point *polygon,int n,Point p) { int i; double angle=0; Point p1,p2; for (i=0;i Solution 3 (2D) There are other solutions to this problem for polygons with special attributes. If the polygon is convex then onecan consider the polygon as a "path" from the first vertex. A point is on theinterior of this polygons if it is always on the same side of all the linesegments making up the path. Given a line segment between P0 (x0,y0) and P1 (x1,y1), another point P (x,y) has the following relationship to the line segment. Computeif it is less than 0 then P is to the right of the line segment, if greater than 0 it is to the left, if equal to 0 then it lies on the line segment.
The following code snippet returns the angle sum between thetest point q and all the vertex pairs. Note that the angle sumis returned in radians. typedef struct { double x,y,z; } XYZ; #define EPSILON 0.0000001 #define MODULUS(p) (sqrt(p.x*p.x + p.y*p.y + p.z*p.z)) #define TWOPI 6.283185307179586476925287 #define RTOD 57.2957795 double CalcAngleSum(XYZ q,XYZ *p,int n) { int i; double m1,m2; double anglesum=0,costheta; XYZ p1,p2; for (i=0;i |