Repository: commons-math Updated Branches: refs/heads/master 036a2cae2 -> a37dcb93b
MATH-1447: adding check for infinite lines when filtering spurious vertices in PolygonsSet vertex loop creation Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/74133837 Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/74133837 Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/74133837 Branch: refs/heads/master Commit: 74133837585f81d1c6434ce32f73fc8694d5f132 Parents: 036a2ca Author: darkma773r <[email protected]> Authored: Thu Feb 1 23:06:47 2018 -0500 Committer: Gilles <[email protected]> Committed: Fri Feb 2 17:13:22 2018 +0100 ---------------------------------------------------------------------- .../geometry/euclidean/twod/PolygonsSet.java | 4 ++ .../euclidean/twod/PolygonsSetTest.java | 43 ++++++++++++++++++++ 2 files changed, 47 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/74133837/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java index 8d5c7b9..9975a04 100644 --- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java +++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java @@ -870,11 +870,15 @@ public class PolygonsSet extends AbstractRegion<Euclidean2D, Euclidean1D> { // we need at least 2 segments in order for one of the contained vertices // to be unnecessary if (loop.size() > 1) { + // Go through the list and compare each segment with the next + // one in line. We can remove the shared vertex if the segments + // are not infinite and they lie on the same line. for (int i = 0; i < loop.size(); ++i) { final Segment previous = loop.get(i); int j = (i + 1) % loop.size(); final Segment next = loop.get(j); if (next != null && + previous.getStart() != null && next.getEnd() != null && Precision.equals(previous.getLine().getAngle(), next.getLine().getAngle(), Precision.EPSILON)) { // the vertex between the two edges is a spurious one // replace the two segments by a single one http://git-wip-us.apache.org/repos/asf/commons-math/blob/74133837/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSetTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSetTest.java b/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSetTest.java index 1385d4a..1ee2ccb 100644 --- a/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSetTest.java +++ b/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSetTest.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.commons.math4.exception.MathIllegalArgumentException; import org.apache.commons.math4.geometry.euclidean.oned.Interval; import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet; +import org.apache.commons.math4.geometry.GeometryTestUtils; import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D; import org.apache.commons.math4.geometry.euclidean.twod.Euclidean2D; import org.apache.commons.math4.geometry.euclidean.twod.Line; @@ -37,12 +38,54 @@ import org.apache.commons.math4.geometry.partitioning.RegionFactory; import org.apache.commons.math4.geometry.partitioning.SubHyperplane; import org.apache.commons.math4.geometry.partitioning.Region.Location; import org.apache.commons.math4.util.FastMath; +import org.apache.commons.numbers.core.Precision; import org.junit.Assert; import org.junit.Test; public class PolygonsSetTest { @Test + public void testInfiniteLines_twoIntersecting() { + // arrange + Line line1 = new Line(new Cartesian2D(0, 0), new Cartesian2D(1, 1), 1e-10); + Line line2 = new Line(new Cartesian2D(1, -1), new Cartesian2D(0, 0), 1e-10); + + List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>(); + boundaries.add(line1.wholeHyperplane()); + boundaries.add(line2.wholeHyperplane()); + + // act + PolygonsSet poly = new PolygonsSet(boundaries, 1e-10); + + // assert + Assert.assertEquals(1e-10, poly.getTolerance(), Precision.EPSILON); + Assert.assertEquals(Double.POSITIVE_INFINITY, poly.getSize(), 1e-10); + Assert.assertEquals(Double.POSITIVE_INFINITY, poly.getBoundarySize(), 1e-10); + Assert.assertEquals(false, poly.isEmpty()); + Assert.assertEquals(false, poly.isFull()); + GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), 1e-10); + + Cartesian2D[][] vertices = poly.getVertices(); + Assert.assertEquals(1, vertices.length); + + Cartesian2D[] loop = vertices[0]; + Assert.assertEquals(3, loop.length); + Assert.assertEquals(null, loop[0]); + GeometryTestUtils.assertVectorEquals(line2.toSpace(new Cartesian1D(-Float.MAX_VALUE)), loop[1], 1e-10); + GeometryTestUtils.assertVectorEquals(line2.toSpace(new Cartesian1D(Float.MAX_VALUE)), loop[2], 1e-10); + + checkPoints(Region.Location.INSIDE, poly, new Cartesian2D[] { + new Cartesian2D(-1, 0), + new Cartesian2D(-Float.MAX_VALUE, Float.MAX_VALUE / 2.0) + }); + checkPoints(Region.Location.OUTSIDE, poly, new Cartesian2D[] { + new Cartesian2D(1, 0), + new Cartesian2D(Float.MAX_VALUE, Float.MAX_VALUE / 2.0) + }); + checkPoints(Region.Location.BOUNDARY, poly, new Cartesian2D[] { Cartesian2D.ZERO }); + } + + @Test public void testSimplyConnected() { Cartesian2D[][] vertices = new Cartesian2D[][] { new Cartesian2D[] {
