PolygonBound.contains() fix (#4553)

* PolygonBound.contains() fix

* style fix

* code refactor and dependency-reduced-pom.xml deletion

* refactor bug fix

* requested changes

* method extraction

* formatting issues fix
This commit is contained in:
Michał Misiewicz 2017-07-20 09:12:46 +02:00 committed by Roman Leventov
parent 0b85c60869
commit b4230ebb3c
2 changed files with 60 additions and 5 deletions

View File

@ -124,11 +124,21 @@ public class PolygonBound extends RectangularBound
int j = polyCorners - 1;
boolean oddNodes = false;
for (int i = 0; i < polyCorners; i++) {
if ((ordinate[i] < coords[1] && ordinate[j] >= coords[1]
|| ordinate[j] < coords[1] && ordinate[i] >= coords[1])
&& (abscissa[i] <= coords[0] || abscissa[j] <= coords[0])) {
if (abscissa[i] + (coords[1] - ordinate[i]) / (ordinate[j] - ordinate[i]) * (abscissa[j] - abscissa[i])
< coords[0]) {
if (abscissa[i] == coords[0] && ordinate[i] == coords[1]) {
return true;
}
if (isPointLayingOnHorizontalBound(i, j, coords)) {
return true;
}
if (between(ordinate[i], ordinate[j], coords[1]) && (abscissa[j] <= coords[0] || abscissa[i] <= coords[0])) {
float intersectionPointX = abscissa[i] + (coords[1] - ordinate[i]) / (ordinate[j] - ordinate[i]) * (abscissa[j] - abscissa[i]);
if (intersectionPointX == coords[0]) {
return true;
} else if (intersectionPointX < coords[0]) {
oddNodes = !oddNodes;
}
}
@ -137,6 +147,20 @@ public class PolygonBound extends RectangularBound
return oddNodes;
}
private boolean isPointLayingOnHorizontalBound(int i, int j, float[] coords)
{
return ordinate[i] == ordinate[j] && ordinate[j] == coords[1] && between(abscissa[i], abscissa[j], coords[0]);
}
private static boolean between(float a, float b, float x)
{
if (a <= b) {
return a <= x && x <= b;
} else {
return b <= x && x <= a;
}
}
@Override
public Iterable<ImmutablePoint> filter(Iterable<ImmutablePoint> points)
{

View File

@ -46,4 +46,35 @@ public class PolygonBoundTest
PolygonBound.from(new float[]{1F, 2F, 3F}, new float[]{0F, 2F, 0F}, 2).getCacheKey()
));
}
@Test
public void testContains()
{
final PolygonBound triangle = PolygonBound.from(new float[]{1f, 4f, 7f}, new float[]{ 1f, 4f, 1f});
final float delta = 1e-5f;
Assert.assertTrue(triangle.contains(new float[]{1f, 1f}));
Assert.assertFalse(triangle.contains(new float[]{1f, 1f - delta}));
Assert.assertFalse(triangle.contains(new float[]{1f, 1f + delta}));
Assert.assertTrue(triangle.contains(new float[]{1f + delta, 1f}));
Assert.assertFalse(triangle.contains(new float[]{1f - delta, 1f}));
Assert.assertTrue(triangle.contains(new float[]{1f + delta, 1f}));
Assert.assertFalse(triangle.contains(new float[]{1f - delta, 1f}));
Assert.assertTrue(triangle.contains(new float[]{5f, 1f}));
Assert.assertFalse(triangle.contains(new float[]{1f, 5f}));
Assert.assertTrue(triangle.contains(new float[]{3f, 2f}));
final PolygonBound rightTriangle = PolygonBound.from(new float[]{1f, 1f, 5f}, new float[]{ 1f, 5f, 1f});
Assert.assertTrue(rightTriangle.contains(new float[]{1f, 5f}));
Assert.assertTrue(rightTriangle.contains(new float[]{2f, 4f}));
Assert.assertTrue(rightTriangle.contains(new float[]{2f - delta , 4f}));
Assert.assertFalse(rightTriangle.contains(new float[]{2f + delta, 4f}));
Assert.assertTrue(rightTriangle.contains(new float[]{2f, 4f - delta}));
Assert.assertFalse(rightTriangle.contains(new float[]{2f, 4f + delta}));
Assert.assertTrue(rightTriangle.contains(new float[]{3f - delta, 3f}));
Assert.assertFalse(rightTriangle.contains(new float[]{3f + delta, 3f}));
Assert.assertTrue(rightTriangle.contains(new float[]{3f, 3f - delta}));
Assert.assertFalse(rightTriangle.contains(new float[]{3f, 3f + delta}));
}
}