javaGeom icon indicating copy to clipboard operation
javaGeom copied to clipboard

LinearRing.isInside SimplePolgon2d.contains : incorrect for anti-clockwise case

Open dsmith82 opened this issue 8 years ago • 1 comments

The isInside and contains methods have the following test

if (area > 0) {
    	return winding == 1;
} else {
    	return winding == 0;
}

I believe the code should be

if (area > 0) {
   return winding == 1;
 } else {
  return winding == -1;
}

This can be tested with the following simple example

		double[] xcoords0 = {0.0, 0.0, 10.0, 10.0, 0.0};
		double[] ycoords0 = {0.0, 10.0, 10.0, 0.0, 0.0};
		LinearRing2D ringCW = new LinearRing2D(xcoords0, ycoords0);

		// anti-clockwise 
		double[] xcoords1 = {0.0, 10.0, 10.0, 0.0, 0.0};
		double[] ycoords1 = {0.0, 0.0, 10.0, 10.0, 0.0};
		LinearRing2D ringACW = new LinearRing2D(xcoords1, ycoords1);

		System.out.println(ringCW.isInside(1.0, 1.0));
		System.out.println(ringCW.isInside(10.5, 10.5));
		
		System.out.println(ringACW.isInside(1.0, 1.0));
		System.out.println(ringACW.isInside(10.5, 10.5));

dsmith82 avatar Dec 11 '17 06:12 dsmith82

Hi, sorry for the long delay, I have less time for the javageom project recently.

concerning the issue, I first thought this was a bug, but this is in fact the choice of convention for determining whether a point is inside a linear ring or not.

  • for CCW rings, with positiive area (the "regular" ones, here ringACW), the convention is to be inside if the winding number is exactly one.
  • for CW rings (here ringCW), with negative area, the "inside" result should be the reverse as in the CCW case. This is what I could obtain with your example.

The choice of this convention make it more convenient to work with multiple polygons, but I agree this is not the most intuitive one.

best, David

dlegland avatar Aug 14 '19 06:08 dlegland