javaarraysgpspath-2d

Path2D -- .contain() not working


I am trying to see if a point is contained within a polygon using Path2D.

The last line, System.out.println(poly.contains(lat1, lon1)), prints "false" even though I know the coordinates(lat1, lon1) are within the polygon sapecified in "testBound". Is the ".contain()" not working? Am i missing something?

    package poly;

import java.awt.Polygon;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.Arrays;

public class Polygon3 {
public static final double lat1 = 40.1032946;
public static final double lon1 = -84.5110052;
public static final String testBound = "40.203294,-84.521005;40.203294,-84.501005;40.003294,-84.521005;40.003294,-84.501005";




public static void main(String[] args) {
    String[] test = testBound.split(";");
    ArrayList<Double> latList = new ArrayList<Double>();
    ArrayList<Double> lonList = new ArrayList<Double>();
    for(String t : test) {
        String[] latlng = t.split(",");
        latList.add(Double.parseDouble(latlng[0]));
        lonList.add(Double.parseDouble(latlng[1]));
    }
    System.out.println(latList);
    System.out.println(lonList);

    Double latpoints[] = latList.toArray(new Double[latList.size()]);
    Double lonpoints[] = lonList.toArray(new Double[lonList.size()]);
    System.out.println(latpoints);
    System.out.println(lonpoints);
    Path2D poly = new Path2D.Double();
    for(int i = 0; i < latpoints.length; i++) {
        poly.moveTo(latpoints[i], lonpoints[i]);
    }
    poly.closePath();
    String testing = poly.toString();
    System.out.println(testing);

    System.out.println(poly.contains(lat1, lon1));
}


}

Solution

  • How to create a polygon?

    To create a closed polygon you need to:

    1. use moveTo to move to the first point
    2. use lineTo to connect all the other points
    3. use closePath to connect the last point with the first one

    For example:

    for (int i = 0; i < latpoints.length; i++) {
        if (i == 0) {
            poly.moveTo(latpoints[i], lonpoints[i]);
        }
        else {
            poly.lineTo(latpoints[i], lonpoints[i]);
        }
    }
    poly.closePath();
    

    Why contains returns false?

    contains returns false because, due to the points order, you are not creating a square but an hourglass shape:

    3   1
    | X |
    4   2
    

    Since the point you are testing is in the center, it might not be considered inside the shape.

    If you swap the order of the third and forth point you are then creating a square:

    4 - 1
    |   |
    3 - 2
    

    and the point will be considered inside.