LUCENE-7970: Handle the case where we generate only a pair of identical planes, as might happen when the center is near a pole.

This commit is contained in:
Karl Wright 2017-09-26 03:20:32 -04:00
parent f8f19562ee
commit 49583ed13d
1 changed files with 20 additions and 10 deletions

View File

@ -119,8 +119,9 @@ class GeoExactCircle extends GeoBaseCircle {
this.notableEdgePoints = null; this.notableEdgePoints = null;
} else { } else {
this.circlePlanes = new ArrayList<>(); this.circlePlanes = new ArrayList<>();
this.notableEdgePoints = new ArrayList<>(); // If it turns out that there's only one circle plane, this array will be populated but unused
this.eitherBounds = new HashMap<>(); final List<GeoPoint[]> notableEdgePoints = new ArrayList<>();
// We construct approximation planes until we have a low enough error estimate // We construct approximation planes until we have a low enough error estimate
final List<ApproximationSlice> slices = new ArrayList<>(100); final List<ApproximationSlice> slices = new ArrayList<>(100);
// Construct four cardinal points, and then we'll build the first two planes // Construct four cardinal points, and then we'll build the first two planes
@ -154,9 +155,11 @@ class GeoExactCircle extends GeoBaseCircle {
final GeoPoint interpPoint2 = planetModel.surfacePointOnBearing(center, cutoffAngle, interpPoint2Bearing); final GeoPoint interpPoint2 = planetModel.surfacePointOnBearing(center, cutoffAngle, interpPoint2Bearing);
// Is this point on the plane? (that is, is the approximation good enough?) // Is this point on the plane? (that is, is the approximation good enough?)
if (Math.abs(thisSlice.plane.evaluate(interpPoint1)) < actualAccuracy && Math.abs(thisSlice.plane.evaluate(interpPoint2)) < actualAccuracy) { if (Math.abs(thisSlice.plane.evaluate(interpPoint1)) < actualAccuracy && Math.abs(thisSlice.plane.evaluate(interpPoint2)) < actualAccuracy) {
// Good enough; add it to the list of planes // Good enough; add it to the list of planes, unless it was identical to the previous plane
if (circlePlanes.size() == 0 || !circlePlanes.get(circlePlanes.size()-1).isNumericallyIdentical(thisSlice.plane)) {
circlePlanes.add(thisSlice.plane); circlePlanes.add(thisSlice.plane);
notableEdgePoints.add(new GeoPoint[]{thisSlice.endPoint1, thisSlice.endPoint2}); notableEdgePoints.add(new GeoPoint[]{thisSlice.endPoint1, thisSlice.endPoint2});
}
} else { } else {
// Split the plane into two, and add it back to the end // Split the plane into two, and add it back to the end
slices.add(new ApproximationSlice(center, slices.add(new ApproximationSlice(center,
@ -173,6 +176,12 @@ class GeoExactCircle extends GeoBaseCircle {
//System.out.println("Number of planes needed: "+circlePlanes.size()); //System.out.println("Number of planes needed: "+circlePlanes.size());
// Compute bounds // Compute bounds
if (circlePlanes.size() == 1) {
this.eitherBounds = null;
this.notableEdgePoints = null;
} else {
this.notableEdgePoints = notableEdgePoints;
this.eitherBounds = new HashMap<>(circlePlanes.size());
for (int i = 0; i < circlePlanes.size(); i++) { for (int i = 0; i < circlePlanes.size(); i++) {
final SidedPlane thisPlane = circlePlanes.get(i); final SidedPlane thisPlane = circlePlanes.get(i);
final SidedPlane previousPlane = (i == 0)?circlePlanes.get(circlePlanes.size()-1):circlePlanes.get(i-1); final SidedPlane previousPlane = (i == 0)?circlePlanes.get(circlePlanes.size()-1):circlePlanes.get(i-1);
@ -181,6 +190,7 @@ class GeoExactCircle extends GeoBaseCircle {
} }
} }
} }
}
/** /**