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