This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-geometry.git

commit 2851d9532b441f3cc347187fcbdb60d223517b40
Author: Matt Juntunen <matt.juntu...@hotmail.com>
AuthorDate: Sat Feb 9 09:13:34 2019 -0500

    GEOMETRY-43: adding extra condition to Plane.firstIntersection() to avoid 
returning facets that are parallel to the test line
---
 .../geometry/euclidean/threed/PolyhedronsSet.java  |  5 +-
 .../euclidean/threed/PolyhedronsSetTest.java       | 77 +++++++++++++++++++++-
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
index 43d8ce6..c7f5f0a 100644
--- 
a/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
+++ 
b/commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSet.java
@@ -509,7 +509,10 @@ public class PolyhedronsSet extends 
AbstractRegion<Vector3D, Vector2D> {
         if (in) {
             // search in the cut hyperplane
             final SubHyperplane<Vector3D> facet = boundaryFacet(point, node);
-            if (facet != null) {
+
+            // only return the facet here if it exists and intersects the plane
+            // (ie, is not parallel it)
+            if (facet != null && plane.intersection(line) != null) {
                 return facet;
             }
         }
diff --git 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
index c2c528b..a635e46 100644
--- 
a/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
+++ 
b/commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/PolyhedronsSetTest.java
@@ -898,7 +898,7 @@ public class PolyhedronsSetTest {
 
     // issue GEOMETRY-38
     @Test
-    public void testFirstIntersection_linesPassThroughBoundaries() {
+    public void testFirstIntersection_linePassesThroughVertex() {
         // arrange
         Vector3D lowerCorner = Vector3D.ZERO;
         Vector3D upperCorner = Vector3D.of(1, 1, 1);
@@ -932,6 +932,81 @@ public class PolyhedronsSetTest {
                 ((Plane) 
downFromCenterResult.getHyperplane()).intersection(downDiagonal), TEST_EPS);
     }
 
+    // Issue GEOMETRY-43
+    @Test
+    public void testFirstIntersection_lineParallelToFace() {
+        // arrange - setup box
+        Vector3D lowerCorner = Vector3D.ZERO;
+        Vector3D upperCorner = Vector3D.of(1, 1, 1);
+        Vector3D center = lowerCorner.lerp(upperCorner, 0.5);
+        List<SubHyperplane<Vector3D>> boundaries = createBoxBoundaries(center, 
1.0, TEST_EPS);
+        PolyhedronsSet polySet = new PolyhedronsSet(boundaries, 
TEST_PRECISION);
+
+        Vector3D firstPointOnLine = Vector3D.of(0.5, -1.0, 0);
+        Vector3D secondPointOnLine = Vector3D.of(0.5, 2.0, 0);
+        Line bottomLine = new Line(firstPointOnLine, secondPointOnLine, 
TEST_PRECISION);
+
+        Vector3D expectedIntersection1 = Vector3D.of(0.5, 0, 0.0);
+        Vector3D expectedIntersection2 = Vector3D.of(0.5, 1.0, 0.0);
+
+        // act/assert
+        SubPlane bottom = (SubPlane) 
polySet.firstIntersection(firstPointOnLine, bottomLine);
+        Assert.assertNotNull(bottom);
+        EuclideanTestUtils.assertCoordinatesEqual(expectedIntersection1,
+                ((Plane) bottom.getHyperplane()).intersection(bottomLine), 
TEST_EPS);
+
+        bottom = (SubPlane) polySet.firstIntersection(Vector3D.of(0.5, 0.1, 
0.0), bottomLine);
+        Assert.assertNotNull(bottom);
+        Vector3D intersection = ((Plane) 
bottom.getHyperplane()).intersection(bottomLine);
+        Assert.assertNotNull(intersection);
+        EuclideanTestUtils.assertCoordinatesEqual(expectedIntersection2, 
intersection, TEST_EPS);
+    }
+
+    @Test
+    public void testFirstIntersection_rayPointOnFace() {
+        // arrange
+        Vector3D lowerCorner = Vector3D.ZERO;
+        Vector3D upperCorner = Vector3D.of(1, 1, 1);
+        Vector3D center = lowerCorner.lerp(upperCorner, 0.5);
+        List<SubHyperplane<Vector3D>> boundaries = createBoxBoundaries(center, 
1.0, TEST_EPS);
+        PolyhedronsSet polySet = new PolyhedronsSet(boundaries, 
TEST_PRECISION);
+
+        Vector3D pt = Vector3D.of(0.5, 0.5, 0);
+        Line intoBoxLine = new Line(pt, pt.add(Vector3D.PLUS_Z), 
TEST_PRECISION);
+        Line outOfBoxLine = new Line(pt, pt.add(Vector3D.MINUS_Z), 
TEST_PRECISION);
+
+        // act/assert
+        SubPlane intoBoxResult = (SubPlane) polySet.firstIntersection(pt, 
intoBoxLine);
+        Vector3D intoBoxPt = ((Plane) 
intoBoxResult.getHyperplane()).intersection(intoBoxLine);
+        EuclideanTestUtils.assertCoordinatesEqual(pt, intoBoxPt, TEST_EPS);
+
+        SubPlane outOfBoxResult = (SubPlane) polySet.firstIntersection(pt, 
outOfBoxLine);
+        Vector3D outOfBoxPt = ((Plane) 
outOfBoxResult.getHyperplane()).intersection(outOfBoxLine);
+        EuclideanTestUtils.assertCoordinatesEqual(pt, outOfBoxPt, TEST_EPS);
+    }
+
+    @Test
+    public void testFirstIntersection_rayPointOnVertex() {
+        // arrange
+        Vector3D lowerCorner = Vector3D.ZERO;
+        Vector3D upperCorner = Vector3D.of(1, 1, 1);
+        Vector3D center = lowerCorner.lerp(upperCorner, 0.5);
+
+        List<SubHyperplane<Vector3D>> boundaries = createBoxBoundaries(center, 
1.0, TEST_EPS);
+        PolyhedronsSet polySet = new PolyhedronsSet(boundaries, 
TEST_PRECISION);
+
+        Line intoBoxLine = new Line(lowerCorner, upperCorner, TEST_PRECISION);
+        Line outOfBoxLine = intoBoxLine.revert();
+
+        // act/assert
+        SubPlane intoBoxResult = (SubPlane) 
polySet.firstIntersection(lowerCorner, intoBoxLine);
+        Vector3D intoBoxPt = ((Plane) 
intoBoxResult.getHyperplane()).intersection(intoBoxLine);
+        EuclideanTestUtils.assertCoordinatesEqual(lowerCorner, intoBoxPt, 
TEST_EPS);
+
+        SubPlane outOfBoxResult = (SubPlane) 
polySet.firstIntersection(lowerCorner, outOfBoxLine);
+        Vector3D outOfBoxPt = ((Plane) 
outOfBoxResult.getHyperplane()).intersection(outOfBoxLine);
+        EuclideanTestUtils.assertCoordinatesEqual(lowerCorner, outOfBoxPt, 
TEST_EPS);
+    }
 
     // Issue 1211
     // See https://issues.apache.org/jira/browse/MATH-1211

Reply via email to