Optimised boundary checking #story[873]
This commit is contained in:
@@ -79,12 +79,20 @@ public class GPSCoordinate {
|
||||
* @return true if coordinate is in the boundary
|
||||
*/
|
||||
public static boolean isInsideBoundary(GPSCoordinate coordinate, List<GPSCoordinate> boundary) {
|
||||
double maxLatitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude();
|
||||
double maxLongitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude();
|
||||
double minLatitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude();
|
||||
double minLongitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude();
|
||||
return isInsideBoundary(coordinate, boundary, new GPSCoordinate(minLatitude, minLongitude),
|
||||
new GPSCoordinate(maxLatitude, maxLongitude));
|
||||
int length = boundary.size();
|
||||
|
||||
boolean inside = false;
|
||||
|
||||
// Check if inside using ray casting algorithm
|
||||
for (int i = 0, j = length - 1; i < length; j = i++) {
|
||||
if (intersects(boundary.get(i), boundary.get(j), coordinate)) {
|
||||
inside = !inside;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return inside;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,24 +110,12 @@ public class GPSCoordinate {
|
||||
double maxLon = maxValues.getLongitude();
|
||||
double coordinateLat = coordinate.getLatitude();
|
||||
double coordinateLon = coordinate.getLongitude();
|
||||
int length = boundary.size();
|
||||
|
||||
boolean inside = false;
|
||||
|
||||
// End computation early
|
||||
if (coordinateLat <= minLat || coordinateLat >= maxLat || coordinateLon <= minLon || coordinateLon >= maxLon) {
|
||||
return false;
|
||||
} else {
|
||||
return isInsideBoundary(coordinate, boundary);
|
||||
}
|
||||
|
||||
// Check if inside using ray casting algorithm
|
||||
for (int i = 0, j = length - 1; i < length; j = i++) {
|
||||
if (intersects(boundary.get(i), boundary.get(j), coordinate)) {
|
||||
inside = !inside;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -56,24 +56,6 @@ public class GPSCoordinateTest {
|
||||
assertFalse(inside);
|
||||
}
|
||||
|
||||
/**
|
||||
* -------
|
||||
* | |
|
||||
* | |
|
||||
* *------
|
||||
*/
|
||||
@Test
|
||||
public void edgeSquareTest() {
|
||||
boundary.add(new GPSCoordinate(0, 0));
|
||||
boundary.add(new GPSCoordinate(10, 0));
|
||||
boundary.add(new GPSCoordinate(10, 10));
|
||||
boundary.add(new GPSCoordinate(0, 10));
|
||||
|
||||
GPSCoordinate coordinate = new GPSCoordinate(0, 0);
|
||||
boolean inside = GPSCoordinate.isInsideBoundary(coordinate, boundary);
|
||||
assertFalse(inside);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insideShapeWithObtuseAnglesTest() {
|
||||
boundary.add(new GPSCoordinate(0, 0));
|
||||
@@ -104,18 +86,21 @@ public class GPSCoordinateTest {
|
||||
assertFalse(inside);
|
||||
}
|
||||
|
||||
/**
|
||||
* -------
|
||||
* | |
|
||||
* * | |
|
||||
* -------
|
||||
*/
|
||||
@Test
|
||||
public void edgeOfShapeWithObtuseAnglesTest() {
|
||||
public void earlyTerminationTest() {
|
||||
boundary.add(new GPSCoordinate(0, 0));
|
||||
boundary.add(new GPSCoordinate(4, 4));
|
||||
boundary.add(new GPSCoordinate(7, 2));
|
||||
boundary.add(new GPSCoordinate(9, 5));
|
||||
boundary.add(new GPSCoordinate(10, 0));
|
||||
boundary.add(new GPSCoordinate(10, 10));
|
||||
boundary.add(new GPSCoordinate(6, 6));
|
||||
boundary.add(new GPSCoordinate(2, 10));
|
||||
boundary.add(new GPSCoordinate(0, 10));
|
||||
|
||||
GPSCoordinate coordinate = new GPSCoordinate(2, 10);
|
||||
boolean inside = GPSCoordinate.isInsideBoundary(coordinate, boundary);
|
||||
GPSCoordinate coordinate = new GPSCoordinate(-2, 8);
|
||||
boolean inside = GPSCoordinate.isInsideBoundary(coordinate, boundary, new GPSCoordinate(0, 0), new GPSCoordinate(10, 10));
|
||||
assertFalse(inside);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user