You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2018/03/31 15:43:38 UTC

lucene-solr:branch_7x: LUCENE-7642: Take the slightly more cautious approach of introducing a plane method for functional identicality.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_7x 2a0094621 -> 2452d6261


LUCENE-7642: Take the slightly more cautious approach of introducing a plane method for functional identicality.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2452d626
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2452d626
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2452d626

Branch: refs/heads/branch_7x
Commit: 2452d6261b3e908af2ba31367ba8022fb936b904
Parents: 2a00946
Author: Karl Wright <Da...@gmail.com>
Authored: Sat Mar 31 11:42:32 2018 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Sat Mar 31 11:43:31 2018 -0400

----------------------------------------------------------------------
 .../spatial3d/geom/GeoPolygonFactory.java       |  2 +-
 .../org/apache/lucene/spatial3d/geom/Plane.java | 40 +++++++++++++++++++-
 2 files changed, 39 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2452d626/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
----------------------------------------------------------------------
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 43ae32f..0bbae80 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
@@ -1239,7 +1239,7 @@ public class GeoPolygonFactory {
       final Edge newLastEdge = edgeBuffer.getNext(lastEdge);
       // Planes that are almost identical cannot be properly handled by the standard polygon logic.  Detect this case and, if found,
       // give up on the tiling -- we'll need to create a large poly instead.
-      if (lastEdge.plane.isNumericallyIdentical(newLastEdge.plane) /*isNearlyIdentical(lastEdge.plane, newLastEdge.plane) */) {
+      if (lastEdge.plane.isFunctionallyIdentical(newLastEdge.plane)) {
         throw new TileException("Two adjacent edge planes are effectively parallel despite filtering; give up on tiling");
       }
       if (Plane.arePointsCoplanar(lastEdge.startPoint, lastEdge.endPoint, newLastEdge.endPoint)) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2452d626/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
index f4d6103..fe3418c 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
@@ -2345,6 +2345,43 @@ public class Plane extends Vector {
   }
 
   /**
+   * Returns true if this plane and the other plane are functionally identical within the margin of error.
+   * Functionally identical means that the planes are so close to parallel that many aspects of planar math,
+   * like intersections, no longer have answers to within the required precision.
+   * @param p is the plane to compare against.
+   * @return true if the planes are functionally identical.
+   */
+  public boolean isFunctionallyIdentical(final Plane p) {
+    // We can get the correlation by just doing a parallel plane check.  That's basically finding
+    // out if the magnitude of the cross-product is "zero".
+    final double cross1 = this.y * p.z - this.z * p.y;
+    final double cross2 = this.z * p.x - this.x * p.z;
+    final double cross3 = this.x * p.y - this.y * p.x;
+    //System.out.println("cross product magnitude = "+(cross1 * cross1 + cross2 * cross2 + cross3 * cross3));
+    // Should be MINIMUM_RESOLUTION_SQUARED, but that gives us planes that are *almost* parallel, and those are problematic too,
+    // so we have a tighter constraint on parallelism in this method.
+    if (cross1 * cross1 + cross2 * cross2 + cross3 * cross3 >= MINIMUM_RESOLUTION) {
+      return false;
+    }
+    
+    // Now, see whether the parallel planes are in fact on top of one another.
+    // The math:
+    // We need a single point that fulfills:
+    // Ax + By + Cz + D = 0
+    // Pick:
+    // x0 = -(A * D) / (A^2 + B^2 + C^2)
+    // y0 = -(B * D) / (A^2 + B^2 + C^2)
+    // z0 = -(C * D) / (A^2 + B^2 + C^2)
+    // Check:
+    // A (x0) + B (y0) + C (z0) + D =? 0
+    // A (-(A * D) / (A^2 + B^2 + C^2)) + B (-(B * D) / (A^2 + B^2 + C^2)) + C (-(C * D) / (A^2 + B^2 + C^2)) + D ?= 0
+    // -D [ A^2 / (A^2 + B^2 + C^2) + B^2 / (A^2 + B^2 + C^2) + C^2 / (A^2 + B^2 + C^2)] + D ?= 0
+    // Yes.
+    final double denom = 1.0 / (p.x * p.x + p.y * p.y + p.z * p.z);
+    return evaluateIsZero(-p.x * p.D * denom, -p.y * p.D * denom, -p.z * p.D * denom);
+  }
+  
+  /**
    * Returns true if this plane and the other plane are identical within the margin of error.
    * @param p is the plane to compare against.
    * @return true if the planes are numerically identical.
@@ -2356,8 +2393,7 @@ public class Plane extends Vector {
     final double cross2 = this.z * p.x - this.x * p.z;
     final double cross3 = this.x * p.y - this.y * p.x;
     //System.out.println("cross product magnitude = "+(cross1 * cross1 + cross2 * cross2 + cross3 * cross3));
-    // Technically should be MINIMUM_RESOLUTION_SQUARED, but that gives us planes that are *almost* parallel, and those are problematic too
-    if (cross1 * cross1 + cross2 * cross2 + cross3 * cross3 >= MINIMUM_RESOLUTION) {
+    if (cross1 * cross1 + cross2 * cross2 + cross3 * cross3 >= MINIMUM_RESOLUTION_SQUARED) {
       return false;
     }
     /* Old method