I'm trying to solve the point-in-polygon problem but I'm facing a problem where the lower bounds of the polygon are not included but the higher bounds do.
I've been following the tutorial of inside code to determine if a point lies within the boundaries of a polygon which uses raycasting and counts if said point is crossing the contour (un)even times to determine if the point lies outside or inside the polygon. This is achieved by checking 2 conditions. One condition for the Y coordinate and the other for the X coordinate looping over each edge of the polygon.
In example below I'm using a polygon which is a square with size 3X3. I'm looping over all the coordinates to check if they are within the square but the problem I'm facing is that the coordinates containing '0' are not included but the coordinates containing '3' are. Ideally all coordinates ranging from x 0-3 and y 0-3 should be marked as within the polygon. I've changed the conditions from '<' to '<=' to include points on the contour instead of inside the polygon but to no avail.
public class PIP {
private final static int SIZE_X = 3;
private final static int SIZE_Y = 3;
public static void main(String[] args) {
final Polygon polygon = new Polygon();
polygon.addPoint(0, 0);
polygon.addPoint(SIZE_X, 0);
polygon.addPoint(SIZE_X, SIZE_Y);
polygon.addPoint(0, SIZE_Y);
for (int x = 0; x < SIZE_X + 1; x++) {
for (int y = 0; y < SIZE_Y + 1; y++) {
final boolean inPolygon = pointInPolygon(polygon, x, y);
System.out.println("Point " + x + ", " + y + " Is In Polygon: " + inPolygon);
}
}
}
public static boolean pointInPolygon(Polygon polygon, int xp, int yp) {
int numCross = 0;
for (int i = 0, j = polygon.npoints - 1; i < polygon.npoints; i++) {
final int x1 = polygon.xpoints[i];
final int y1 = polygon.ypoints[i];
final int x2 = polygon.xpoints[j];
final int y2 = polygon.ypoints[j];
if (((yp <= y1) != (yp <= y2)) && (xp <= x1 + ((yp - y1) / (y2 - y1)) * (x2 - x1))) {
numCross += 1;
}
j = i;
}
return numCross % 2 == 1;
}
}
The output of code above is as following:
Point 0, 0 Is In Polygon: false
Point 0, 1 Is In Polygon: false
Point 0, 2 Is In Polygon: false
Point 0, 3 Is In Polygon: false
Point 1, 0 Is In Polygon: false
Point 1, 1 Is In Polygon: true
Point 1, 2 Is In Polygon: true
Point 1, 3 Is In Polygon: true
Point 2, 0 Is In Polygon: false
Point 2, 1 Is In Polygon: true
Point 2, 2 Is In Polygon: true
Point 2, 3 Is In Polygon: true
Point 3, 0 Is In Polygon: false
Point 3, 1 Is In Polygon: true
Point 3, 2 Is In Polygon: true
Point 3, 3 Is In Polygon: true
I've solved this by checking first whether the point is on an edge (line) of the polygon instead if the point is inside the polygon. This is achieved by checking if the cross product of the current point and edge line is 0 which means the point is on the line. And secondly by checking if the coordinates of the current point are within the bounds of the 2 points of the edge. See answer of AnT stands with Russia here.