mirror of https://github.com/apache/lucene.git
LUCENE-8245: Use strict bounds checking for edge planes when assessing envelope crossings. It's the only way to insure we don't overdetect or underdetect such intersections.
This commit is contained in:
parent
017f59bae5
commit
832e89748e
|
@ -971,12 +971,14 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
|||
*/
|
||||
private int countCrossings(final Edge edge,
|
||||
final Plane envelopePlane, final Membership envelopeBound) {
|
||||
final GeoPoint[] intersections = edge.plane.findIntersections(planetModel, envelopePlane, edge.startPlane, edge.endPlane, envelopeBound);
|
||||
final GeoPoint[] intersections = edge.plane.findIntersections(planetModel, envelopePlane, envelopeBound);
|
||||
int crossings = 0;
|
||||
if (intersections != null) {
|
||||
for (final GeoPoint intersection : intersections) {
|
||||
// It's unique, so assess it
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
if (edge.startPlane.strictlyWithin(intersection) && edge.endPlane.strictlyWithin(intersection)) {
|
||||
// It's unique, so assess it
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crossings;
|
||||
|
@ -1062,12 +1064,14 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
|||
*/
|
||||
private int countCrossings(final Edge edge,
|
||||
final Plane envelopePlane, final Membership envelopeBound1, final Membership envelopeBound2) {
|
||||
final GeoPoint[] intersections = edge.plane.findIntersections(planetModel, envelopePlane, edge.startPlane, edge.endPlane, envelopeBound1, envelopeBound2);
|
||||
final GeoPoint[] intersections = edge.plane.findIntersections(planetModel, envelopePlane, envelopeBound1, envelopeBound2);
|
||||
int crossings = 0;
|
||||
if (intersections != null) {
|
||||
for (final GeoPoint intersection : intersections) {
|
||||
// It's unique, so assess it
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
if (edge.startPlane.strictlyWithin(intersection) && edge.endPlane.strictlyWithin(intersection)) {
|
||||
// It's unique, so assess it
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crossings;
|
||||
|
@ -1381,35 +1385,39 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
|||
private int countCrossings(final Edge edge,
|
||||
final Plane travelEnvelopePlane, final Membership travelEnvelopeBound1, final Membership travelEnvelopeBound2,
|
||||
final Plane testPointEnvelopePlane, final Membership testPointEnvelopeBound1, final Membership testPointEnvelopeBound2) {
|
||||
final GeoPoint[] travelIntersections = edge.plane.findIntersections(planetModel, travelEnvelopePlane, edge.startPlane, edge.endPlane, travelEnvelopeBound1, travelEnvelopeBound2);
|
||||
final GeoPoint[] testPointIntersections = edge.plane.findIntersections(planetModel, testPointEnvelopePlane, edge.startPlane, edge.endPlane, testPointEnvelopeBound1, testPointEnvelopeBound2);
|
||||
final GeoPoint[] travelIntersections = edge.plane.findIntersections(planetModel, travelEnvelopePlane, travelEnvelopeBound1, travelEnvelopeBound2);
|
||||
final GeoPoint[] testPointIntersections = edge.plane.findIntersections(planetModel, testPointEnvelopePlane, testPointEnvelopeBound1, testPointEnvelopeBound2);
|
||||
int crossings = 0;
|
||||
if (travelIntersections != null) {
|
||||
for (final GeoPoint intersection : travelIntersections) {
|
||||
// Make sure it's not a dup
|
||||
boolean notDup = true;
|
||||
if (testPointIntersections != null) {
|
||||
for (final GeoPoint otherIntersection : testPointIntersections) {
|
||||
if (intersection.isNumericallyIdentical(otherIntersection)) {
|
||||
//System.out.println(" Points "+intersection+" and "+otherIntersection+" are duplicates");
|
||||
notDup = false;
|
||||
break;
|
||||
if (edge.startPlane.strictlyWithin(intersection) && edge.endPlane.strictlyWithin(intersection)) {
|
||||
// Make sure it's not a dup
|
||||
boolean notDup = true;
|
||||
if (testPointIntersections != null) {
|
||||
for (final GeoPoint otherIntersection : testPointIntersections) {
|
||||
if (edge.startPlane.strictlyWithin(otherIntersection) && edge.endPlane.strictlyWithin(otherIntersection) && intersection.isNumericallyIdentical(otherIntersection)) {
|
||||
//System.out.println(" Points "+intersection+" and "+otherIntersection+" are duplicates");
|
||||
notDup = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!notDup) {
|
||||
continue;
|
||||
}
|
||||
// It's unique, so assess it
|
||||
//System.out.println(" Assessing travel envelope intersection point "+intersection+"...");
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
}
|
||||
if (!notDup) {
|
||||
continue;
|
||||
}
|
||||
// It's unique, so assess it
|
||||
//System.out.println(" Assessing travel envelope intersection point "+intersection+"...");
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
}
|
||||
}
|
||||
if (testPointIntersections != null) {
|
||||
for (final GeoPoint intersection : testPointIntersections) {
|
||||
// It's unique, so assess it
|
||||
//System.out.println(" Assessing testpoint envelope intersection point "+intersection+"...");
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
if (edge.startPlane.strictlyWithin(intersection) && edge.endPlane.strictlyWithin(intersection)) {
|
||||
// It's unique, so assess it
|
||||
//System.out.println(" Assessing testpoint envelope intersection point "+intersection+"...");
|
||||
crossings += edgeCrossesEnvelope(edge.plane, intersection)?1:0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crossings;
|
||||
|
|
|
@ -234,6 +234,18 @@ public class SidedPlane extends Plane implements Membership {
|
|||
return sigNum == this.sigNum;
|
||||
}
|
||||
|
||||
public boolean strictlyWithin(final Vector v) {
|
||||
double evalResult = evaluate(v.x, v.y, v.z);
|
||||
double sigNum = Math.signum(evalResult);
|
||||
return sigNum == 0.0 || sigNum == this.sigNum;
|
||||
}
|
||||
|
||||
public boolean strictlyWithin(double x, double y, double z) {
|
||||
double evalResult = evaluate(x, y, z);
|
||||
double sigNum = Math.signum(evalResult);
|
||||
return sigNum == 0.0 || sigNum == this.sigNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
|
|
@ -1428,7 +1428,6 @@ shape:
|
|||
}
|
||||
|
||||
@Test
|
||||
//@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8245")
|
||||
public void testComplexPolygonPlaneOutsideWorld() {
|
||||
List<GeoPoint> points = new ArrayList<>();
|
||||
points.add(new GeoPoint(PlanetModel.SPHERE, -0.5, -0.5));
|
||||
|
@ -1503,7 +1502,6 @@ shape:
|
|||
}
|
||||
|
||||
@Test
|
||||
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8245")
|
||||
public void testLUCENE8245() {
|
||||
//POLYGON((-70.19447784626787 -83.117346007187,0.0 2.8E-322,-139.99870438810106 7.994601469571884,-143.14292702670522 -18.500141088122664,-158.7373186858464 -35.42942085357812,-70.19447784626787 -83.117346007187))
|
||||
final List<GeoPoint> points = new ArrayList<>();
|
||||
|
|
|
@ -24,6 +24,8 @@ import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
|||
import com.carrotsearch.randomizedtesting.generators.BiasedNumbers;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
|
||||
|
||||
/**
|
||||
* Random test for polygons.
|
||||
*/
|
||||
|
@ -92,7 +94,7 @@ public class RandomGeoPolygonTest extends RandomGeo3dShapeGenerator {
|
|||
* biased doubles.
|
||||
*/
|
||||
@Test
|
||||
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8245")
|
||||
//@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8245")
|
||||
@Repeat(iterations = 10)
|
||||
public void testComparePolygons() {
|
||||
final PlanetModel planetModel = randomPlanetModel();
|
||||
|
|
Loading…
Reference in New Issue