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?
For those who would like to understand how the method written by Dean Povey above works, here is the explanation:
The method looks at a "ray" that starts at the tested spot and extends to infinity to the right side of the X axis. For each polygon segment, it checks if the ray crosses it. If the total number of segment crossing is odd then the tested point is considered inside the polygon, otherwise - it is outside.
To understand the way the crossing is calculated, consider the following figure:
v2
o
/
/ c (intersection)
o--------x----------------------> to infinity
t /
/
/
o
v1
For the intersection to occur, tested.y must be between the y values of the segment's vertices (v1 and v2). This is the first condition of the if statement in the method. If this is what happens, then the horizontal line must intersect the segment. It only remains to establish whether the intersection happens to the right of the tested point or to the left of it. This requires finding the x coordinate of the intersection point, which is:
t.y - v1.y
c.x = v1.x + ----------- * (v2.x - v1.x)
v2.y - v1.y
All that remains to be done is examining the subtleties:
o o
| \ o
| A1 C1 \ /
| \ / C2
o--------x-----------x------------x--------> to infinity
/ / \
A2 / B1 / \ B2
/ / \
o / o
o
Now, to verify if it works, check for yourself what is returned for each of the 4 segments by the if condition in the method body. You should find that the segments above the ray (A1, C1, C2) receive a positive result, while those below it (A2, B1, B2) receive a negative one. This means that the A vertex contributes an odd number (1) to the crossing count, while B and C contribute an even number (0 and 2, respectively), which is exactly what is desired. A is indeed a real crossing of the polygon, while B and C are just two cases of "fly-by".
Polygon's abscissas x_array: Array[Integer]
Polygon's ordinates: y_array: Array[Integer]
Point: x: Integer, y: Integer
import java.awt.Polygon
import java.awt.Point
...
final boolean isInPolygon =
new Polygon(x_array,y_array,x_array.length).contains(new Point(x, y));
In this example we create an object java.awt.Polygon
and use the method contains to check if your coordinates are in the shape you designed.
I use the object java.awt.Point
to represent the coordinates to make the code elegant but that is optional, you can directly use .contains(x, y)