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
|
* @return true if coordinate is in the boundary
|
||||||
*/
|
*/
|
||||||
public static boolean isInsideBoundary(GPSCoordinate coordinate, List<GPSCoordinate> boundary) {
|
public static boolean isInsideBoundary(GPSCoordinate coordinate, List<GPSCoordinate> boundary) {
|
||||||
double maxLatitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude();
|
int length = boundary.size();
|
||||||
double maxLongitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude();
|
|
||||||
double minLatitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude();
|
boolean inside = false;
|
||||||
double minLongitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude();
|
|
||||||
return isInsideBoundary(coordinate, boundary, new GPSCoordinate(minLatitude, minLongitude),
|
// Check if inside using ray casting algorithm
|
||||||
new GPSCoordinate(maxLatitude, maxLongitude));
|
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 maxLon = maxValues.getLongitude();
|
||||||
double coordinateLat = coordinate.getLatitude();
|
double coordinateLat = coordinate.getLatitude();
|
||||||
double coordinateLon = coordinate.getLongitude();
|
double coordinateLon = coordinate.getLongitude();
|
||||||
int length = boundary.size();
|
|
||||||
|
|
||||||
boolean inside = false;
|
|
||||||
|
|
||||||
// End computation early
|
// End computation early
|
||||||
if (coordinateLat <= minLat || coordinateLat >= maxLat || coordinateLon <= minLon || coordinateLon >= maxLon) {
|
if (coordinateLat <= minLat || coordinateLat >= maxLat || coordinateLon <= minLon || coordinateLon >= maxLon) {
|
||||||
return false;
|
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);
|
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
|
@Test
|
||||||
public void insideShapeWithObtuseAnglesTest() {
|
public void insideShapeWithObtuseAnglesTest() {
|
||||||
boundary.add(new GPSCoordinate(0, 0));
|
boundary.add(new GPSCoordinate(0, 0));
|
||||||
@@ -104,18 +86,21 @@ public class GPSCoordinateTest {
|
|||||||
assertFalse(inside);
|
assertFalse(inside);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -------
|
||||||
|
* | |
|
||||||
|
* * | |
|
||||||
|
* -------
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void edgeOfShapeWithObtuseAnglesTest() {
|
public void earlyTerminationTest() {
|
||||||
boundary.add(new GPSCoordinate(0, 0));
|
boundary.add(new GPSCoordinate(0, 0));
|
||||||
boundary.add(new GPSCoordinate(4, 4));
|
boundary.add(new GPSCoordinate(10, 0));
|
||||||
boundary.add(new GPSCoordinate(7, 2));
|
|
||||||
boundary.add(new GPSCoordinate(9, 5));
|
|
||||||
boundary.add(new GPSCoordinate(10, 10));
|
boundary.add(new GPSCoordinate(10, 10));
|
||||||
boundary.add(new GPSCoordinate(6, 6));
|
boundary.add(new GPSCoordinate(0, 10));
|
||||||
boundary.add(new GPSCoordinate(2, 10));
|
|
||||||
|
|
||||||
GPSCoordinate coordinate = new GPSCoordinate(2, 10);
|
GPSCoordinate coordinate = new GPSCoordinate(-2, 8);
|
||||||
boolean inside = GPSCoordinate.isInsideBoundary(coordinate, boundary);
|
boolean inside = GPSCoordinate.isInsideBoundary(coordinate, boundary, new GPSCoordinate(0, 0), new GPSCoordinate(10, 10));
|
||||||
assertFalse(inside);
|
assertFalse(inside);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user