Reputation:
I'm working on an open source tracking and geofence software application and am having a bit of difficulty figuring out the math for the geofencing.
I need to determine whether or not a coordinate exists inside of a polygon. However, the tricky part is that the polygon has no set number of sides. I need to be able to calculate for fifty sides or for five sides.
My research says that the easiest way is to take my point (which I'll call x) and a point outside the polygon (call it y) and determine if line ((xx, xy), (yx, yy)) intersects with the polygon's boundaries. If it intersects an odd number of times, point x must be inside the polygon.
Knowing that, however, I cannot figure out how to express this in an algorithm.. I obviously will need to loop through the various lines constructing the polygon but the check I do eludes me. Can anyone be of assistance? Please know that I'm not asking for the solution necessarily. Anything that will help me figure it out the answer is an enormous help.
Much appreciated.
Upvotes: 8
Views: 10600
Reputation: 22424
See here
Basically there is an approach (I think its the Jordan Curve Theorem) that counts the number of times a ray intersects the line segments making up the polygon. If the result is even then the point is outside the polygon otherwise the point lies inside the polygon.
HTH
EDIT There is another SO question that relates to this question that can be found here
Upvotes: 7
Reputation: 1
Try this,
public static bool PointinPolygon( Point[] points, Point p )
{
bool result = false;
for( int i = 0; i < points.Length - 1; i++ )
{
if( ( ( ( points[ i + 1 ].Y <= p.Y ) && ( p.Y < points[ i ].Y ) ) || ( ( points[ i ].Y <= p.Y ) && ( p.Y < points[ i + 1 ].Y ) ) ) && ( p.X < ( points[ i ].X - points[ i + 1 ].X ) * ( p.Y - points[ i + 1 ].Y ) / ( points[ i ].Y - points[ i + 1 ].Y ) + points[ i + 1 ].X ) )
{
result = !result;
}
}
return result;
}
Upvotes: 0
Reputation: 1243
Justin,
You may also need to better define "outside the polygon" to construct a segment.
Take the min & max of all the x & y coordinates and construct a rectangle (xmin,ymin),(xmax,ymin),(xmax,ymax),(xmin,ymax). Any point outside the rectangle would definitely be outside the polygon - then continue as others have shown above. Each polygon segment and the constructed line is defined by an equation y = ax + b and, for each segment, a range xlo and xhi. Your constructed line either crosses a segment in the range or not. That is, the solution of the two simultaneous equations in the segment range either exists or not. Just count the number of solutions that exist to get the number of intersections.
Upvotes: 1
Reputation: 5767
One key here is to realize that you are free to choose any point Y that you like. A really nice choice is the point (xx, -infinity). In other words, the point directly down from the point in question and infinitely far away. Now the question becomes: how many of the polygon edges cross your X-coordinate below the point in question. So only line segments that straddle the X coordinate need to be considered.
If your point is P = (x,y), and segment end points are P1 = (x1,y1) and P2 = (x2,y2) the y coordinate of the segment where it crosses x is given by sy = (x-x1)*(y2-y1)/(x2-x1) + y1
Check if sy < y (only if x1 < x < x2 or x2 < x < x1). If there are an odd number of these then P is inside.
There are subtle issues with this when one of the verticies of the polygon is at exactly the same y position as the point in question. You'll have to be careful about that case.
Upvotes: 1
Reputation: 16007
I'll assume you're in a plane (2D).
Upvotes: 0