Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Point in Polygon Algorithm

Tags:

c

algorithm

I saw the below algorithm works to check if a point is in a given polygon from this link:

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) {   int i, j, c = 0;   for (i = 0, j = nvert-1; i < nvert; j = i++) {     if ( ((verty[i]>testy) != (verty[j]>testy)) &&      (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )        c = !c;   }   return c; } 

I tried this algorithm and it actually works just perfect. But sadly I cannot understand it well after spending some time trying to get the idea of it.

So if someone is able to understand this algorithm, please explain it to me a little.

Thank you.

like image 708
Allan Jiang Avatar asked Jul 30 '12 06:07

Allan Jiang


People also ask

How do you find a point inside a polygon?

Draw a horizontal line to the right of each point and extend it to infinity. Count the number of times the line intersects with polygon edges. A point is inside the polygon if either count of intersections is odd or point lies on an edge of polygon. If none of the conditions is true, then point lies outside.

What are the points of a polygon called?

The segments of a polygonal circuit are called its edges or sides. The points where two edges meet are the polygon's vertices (singular: vertex) or corners.

Is point inside convex polygon?

A convex polygon is a simple polygon (with no self intersections) such that any line segment between two points inside of the polygon lies completely inside of it. The point will be inside a convex polygon if and only if it lies on the same side of the support line of each of the segments.

How do you know if a point is outside a polygon?

To determine the status of a point (xp,yp) consider a horizontal ray emanating from (xp,yp) and to the right. If the number of times this ray intersects the line segments making up the polygon is even then the point is outside the polygon.


2 Answers

The algorithm is ray-casting to the right. Each iteration of the loop, the test point is checked against one of the polygon's edges. The first line of the if-test succeeds if the point's y-coord is within the edge's scope. The second line checks whether the test point is to the left of the line (I think - I haven't got any scrap paper to hand to check). If that is true the line drawn rightwards from the test point crosses that edge.

By repeatedly inverting the value of c, the algorithm counts how many times the rightward line crosses the polygon. If it crosses an odd number of times, then the point is inside; if an even number, the point is outside.

I would have concerns with a) the accuracy of floating-point arithmetic, and b) the effects of having a horizontal edge, or a test point with the same y-coord as a vertex, though.

like image 130
Chowlett Avatar answered Sep 17 '22 15:09

Chowlett


Edit 1/30/2022: I wrote this answer 9 years ago when I was in college. People in the chat conversation are indicating it's not accurate. You should probably look elsewhere. 🤷‍♂️

Chowlett is correct in every way, shape, and form. The algorithm assumes that if your point is on the line of the polygon, then that is outside - for some cases, this is false. Changing the two '>' operators to '>=' and changing '<' to '<=' will fix that.

bool PointInPolygon(Point point, Polygon polygon) {   vector<Point> points = polygon.getPoints();   int i, j, nvert = points.size();   bool c = false;      for(i = 0, j = nvert - 1; i < nvert; j = i++) {     if( ( (points[i].y >= point.y ) != (points[j].y >= point.y) ) &&         (point.x <= (points[j].x - points[i].x) * (point.y - points[i].y) / (points[j].y - points[i].y) + points[i].x)       )       c = !c;   }      return c; } 
like image 39
Josh Avatar answered Sep 20 '22 15:09

Josh