I have a convex polygon (typically just a rotated square), and I know all of 4 points. How do I determine if a given point (yellow/green) is inside the polygon?
The java.awt.Polygon
class has a number of contains(...)
methods if you use Polygon objects to represent your polygon.
Say, x[] is the array of x points and y[] is the array of y points.
You are meant to return 1 if the point exists in the polygon and 2 if not. where (planeX,planeY) is the point you need to check.
//check like this
return new Polygon(x,y,x.length).contains(planeX, planeY)?1:2;
Assuming that your point is at Y coordinate y, simply calculate the x positions where each of the polygon's (non-horizontal) lines cross y. Count the number of x positions that are less than the x position of your point. If the number of x positions is odd, your point is inside the polygon. Note: this works for all polygons, not just convex. Think of it this way: draw a line from infinitely far away straight in to your point. When that line crosses a polygon line, it is now inside the polygon. Cross the line again, outside. Cross again, inside (and so forth). Hope this helps!
Just to add a (simple) Java implementation of the original code in C from code suggested by @Dean Povey (I don't know why @Dean Povey is referring to a large implementation):
static boolean pnpoly(double[] vertx, double[] verty, double testx, double testy)
{
int nvert = vertx.length;
int i, j;
boolean c = false;
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 did not change the case to comply with Java rule to show the minimal changes required. I have also tested it in simple cases and it works fine.
Check to see if it's on the same side of the 4 half-planes defined by the lines that contain the line segments that make up the sides of the quad.
Here is a good explanation.
This page: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html shows how to do this for any polygon.
I have a Java implementation of this, but it is too big to post here in its entirety. However, you should be able to work it out:
class Boundary {
private final Point[] points; // Points making up the boundary
...
/**
* Return true if the given point is contained inside the boundary.
* See: http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
* @param test The point to check
* @return true if the point is inside the boundary, false otherwise
*
*/
public boolean contains(Point test) {
int i;
int j;
boolean result = false;
for (i = 0, j = points.length - 1; i < points.length; j = i++) {
if ((points[i].y > test.y) != (points[j].y > test.y) &&
(test.x < (points[j].x - points[i].x) * (test.y - points[i].y) / (points[j].y-points[i].y) + points[i].x)) {
result = !result;
}
}
return result;
}
}
And here is a sketch of the Point class
/**
* Two dimensional cartesian point.
*/
public class Point {
public final double x;
public final double y;
...
}