From 02f1dacc3d84a42f9359aedb0cc98ca4a6161d57 Mon Sep 17 00:00:00 2001 From: Karl Wright Date: Tue, 19 Apr 2016 09:09:40 -0400 Subject: [PATCH] LUCENE-7192: Catch the case where we have two points in the same poly that are not adjacent but identical. --- .../spatial3d/geom/GeoPolygonFactory.java | 131 +++++++++--------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java index 8cb3386190a..6cc42573652 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java @@ -229,73 +229,78 @@ public class GeoPolygonFactory { // Check if the extension of currentPath to considerPointIndex is workable final GeoPoint considerStartPoint = currentPath.lastPoint; final GeoPoint considerEndPoint = points.get(considerPointIndex); - // Create a plane including these two - final Plane considerPlane = new Plane(considerStartPoint, considerEndPoint); - boolean isChoiceLegal = true; - //System.err.println(" considering "+considerStartPoint+" to "+considerEndPoint); - if (isChoiceLegal) { - // Consider the previous plane/point - if (currentPath.lastPlane != null) { - if (currentPath.lastPlane.evaluateIsZero(considerEndPoint)) { - //System.err.println(" coplanar with last plane"); - // no good - isChoiceLegal = false; - } else if (considerPlane.evaluateIsZero(currentPath.previous.lastPoint)) { - //System.err.println(" last point coplanar with this plane"); - isChoiceLegal = false; - } - } - } - - if (isChoiceLegal && considerPointIndex == startPointIndex) { - // Verify that the first plane (already recorded) works together with the last plane - final SafePath firstPlaneEndpoint = currentPath.findFirstEndpoint(); - if (firstPlaneEndpoint == null) { - //System.err.println(" path not long enough"); - isChoiceLegal = false; - } else { - if (firstPlaneEndpoint.lastPlane.evaluateIsZero(considerStartPoint)) { - //System.err.println(" last point is coplanar with start plane"); - isChoiceLegal = false; - } else if (considerPlane.evaluateIsZero(firstPlaneEndpoint.lastPoint)) { - //System.err.println(" first point is coplanar with last plane"); - isChoiceLegal = false; - } - } - } - - if (isChoiceLegal) { - // All points between the start and end, if any, must be on the plane. - int checkIndex = getLegalIndex(currentPath.lastPointIndex + 1, points.size()); - while (checkIndex != considerPointIndex) { - if (!considerPlane.evaluateIsZero(points.get(checkIndex))) { - // This possibility is no good. But does it say anything about other possibilities? I think - // it may mean we don't have to consider any further extensions; gotta work that through - // mathematically though before coding it. - //System.err.println(" interior point not coplanar with trial plane"); - isChoiceLegal = false; - break; - //return null; - } - checkIndex = getLegalIndex(checkIndex + 1, points.size()); - } - } - - final int nextPointIndex = getLegalIndex(considerPointIndex + 1, points.size()); - if (isChoiceLegal) { - // Extend the path and call ourselves recursively. - if (considerPointIndex == startPointIndex) { - // Current path has been validated; return it - return currentPath; + if (!considerStartPoint.isNumericallyIdentical(considerEndPoint)) { + // Create a plane including these two + final Plane considerPlane = new Plane(considerStartPoint, considerEndPoint); + + boolean isChoiceLegal = true; + + //System.err.println(" considering "+considerStartPoint+" to "+considerEndPoint); + if (isChoiceLegal) { + // Consider the previous plane/point + if (currentPath.lastPlane != null) { + if (currentPath.lastPlane.evaluateIsZero(considerEndPoint)) { + //System.err.println(" coplanar with last plane"); + // no good + isChoiceLegal = false; + } else if (considerPlane.evaluateIsZero(currentPath.previous.lastPoint)) { + //System.err.println(" last point coplanar with this plane"); + isChoiceLegal = false; + } + } } - //System.err.println(" adding to path: "+considerEndPoint+"; "+considerPlane); - final SafePath newPath = new SafePath(currentPath, considerEndPoint, considerPointIndex, considerPlane); - final SafePath result = findSafePath(newPath, points, nextPointIndex, startPointIndex); - if (result != null) { - return result; + + if (isChoiceLegal && considerPointIndex == startPointIndex) { + // Verify that the first plane (already recorded) works together with the last plane + final SafePath firstPlaneEndpoint = currentPath.findFirstEndpoint(); + if (firstPlaneEndpoint == null) { + //System.err.println(" path not long enough"); + isChoiceLegal = false; + } else { + if (firstPlaneEndpoint.lastPlane.evaluateIsZero(considerStartPoint)) { + //System.err.println(" last point is coplanar with start plane"); + isChoiceLegal = false; + } else if (considerPlane.evaluateIsZero(firstPlaneEndpoint.lastPoint)) { + //System.err.println(" first point is coplanar with last plane"); + isChoiceLegal = false; + } + } } + + if (isChoiceLegal) { + // All points between the start and end, if any, must be on the plane. + int checkIndex = getLegalIndex(currentPath.lastPointIndex + 1, points.size()); + while (checkIndex != considerPointIndex) { + if (!considerPlane.evaluateIsZero(points.get(checkIndex))) { + // This possibility is no good. But does it say anything about other possibilities? I think + // it may mean we don't have to consider any further extensions; gotta work that through + // mathematically though before coding it. + //System.err.println(" interior point not coplanar with trial plane"); + isChoiceLegal = false; + break; + //return null; + } + checkIndex = getLegalIndex(checkIndex + 1, points.size()); + } + } + + if (isChoiceLegal) { + // Extend the path and call ourselves recursively. + if (considerPointIndex == startPointIndex) { + // Current path has been validated; return it + return currentPath; + } + //System.err.println(" adding to path: "+considerEndPoint+"; "+considerPlane); + final SafePath newPath = new SafePath(currentPath, considerEndPoint, considerPointIndex, considerPlane); + final SafePath result = findSafePath(newPath, points, nextPointIndex, startPointIndex); + if (result != null) { + return result; + } + } + } + if (considerPointIndex == startPointIndex) { break; }