You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2018/02/15 10:07:19 UTC
[2/5] [math] MATH-1437: adding more tests to PolygonsSetTest;
tests rely on the fix for MATH-1450
MATH-1437: adding more tests to PolygonsSetTest; tests rely on the fix for MATH-1450
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/b295635a
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/b295635a
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/b295635a
Branch: refs/heads/master
Commit: b295635a87da0c20e5e2495103d4877ef0187d4d
Parents: cfe0502
Author: darkma773r <ma...@hotmail.com>
Authored: Sun Feb 11 13:26:42 2018 -0500
Committer: darkma773r <ma...@hotmail.com>
Committed: Sun Feb 11 13:26:42 2018 -0500
----------------------------------------------------------------------
.../math4/geometry/GeometryTestUtils.java | 34 +-
.../euclidean/twod/PolygonsSetTest.java | 1058 ++++++++++++------
2 files changed, 752 insertions(+), 340 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b295635a/src/test/java/org/apache/commons/math4/geometry/GeometryTestUtils.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/geometry/GeometryTestUtils.java b/src/test/java/org/apache/commons/math4/geometry/GeometryTestUtils.java
index 74f2beb..edb34e8 100644
--- a/src/test/java/org/apache/commons/math4/geometry/GeometryTestUtils.java
+++ b/src/test/java/org/apache/commons/math4/geometry/GeometryTestUtils.java
@@ -19,6 +19,7 @@ package org.apache.commons.math4.geometry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
@@ -83,6 +84,24 @@ public class GeometryTestUtils {
Assert.assertEquals(msg, expected.getZ(), actual.getZ(), tolerance);
}
+ /** Asserts that the given value is positive infinity.
+ * @param value
+ */
+ public static void assertPositiveInfinity(double value) {
+ String msg = "Expected value to be positive infinity but was " + value;
+ Assert.assertTrue(msg, Double.isInfinite(value));
+ Assert.assertTrue(msg, value > 0);
+ }
+
+ /** Asserts that the given value is negative infinity..
+ * @param value
+ */
+ public static void assertNegativeInfinity(double value) {
+ String msg = "Expected value to be negative infinity but was " + value;
+ Assert.assertTrue(msg, Double.isInfinite(value));
+ Assert.assertTrue(msg, value < 0);
+ }
+
/** Prints a string representation of the given 1D {@link BSPTree} to
* the console. This is intended for quick debugging of small trees.
* @param tree
@@ -188,7 +207,20 @@ public class GeometryTestUtils {
}
}
- write(node.getClass().getSimpleName() + "@" + System.identityHashCode(node) + " | ");
+ write(nodeIdString(node) + " | ");
+ }
+
+ /** Returns a short string identifier for the given node.
+ * @param node
+ * @return
+ */
+ protected String nodeIdString(BSPTree<S> node) {
+ String str = Objects.toString(node);
+ int idx = str.lastIndexOf('.');
+ if (idx > -1) {
+ return str.substring(idx + 1, str.length());
+ }
+ return str;
}
/** Adds the given string to the output.
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b295635a/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 94a7157..408614b 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
@@ -17,185 +17,479 @@
package org.apache.commons.math4.geometry.euclidean.twod;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import org.apache.commons.math3.util.Precision;
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;
-import org.apache.commons.math4.geometry.euclidean.twod.PolygonsSet;
-import org.apache.commons.math4.geometry.euclidean.twod.SubLine;
-import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
+import org.apache.commons.math4.geometry.euclidean.oned.Interval;
+import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet;
import org.apache.commons.math4.geometry.partitioning.BSPTree;
import org.apache.commons.math4.geometry.partitioning.BSPTreeVisitor;
import org.apache.commons.math4.geometry.partitioning.BoundaryProjection;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
+import org.apache.commons.math4.geometry.partitioning.Region.Location;
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 {
+ private static final double TEST_TOLERANCE = 1e-10;
+
+ @Test
+ public void testFull() {
+ // act
+ PolygonsSet poly = new PolygonsSet(TEST_TOLERANCE);
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ Assert.assertEquals(0.0, poly.getBoundarySize(), TEST_TOLERANCE);
+ Assert.assertEquals(0, poly.getVertices().length);
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertTrue(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
+ Cartesian2D.ZERO,
+ new Cartesian2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+ for (double y = -1; y < 1; y += 0.1) {
+ for (double x = -1; x < 1; x += 0.1) {
+ GeometryTestUtils.assertNegativeInfinity(poly.projectToBoundary(new Cartesian2D(x, y)).getOffset());
+ }
+ }
+ }
+
+ @Test
+ public void testEmpty() {
+ // act
+ PolygonsSet poly = (PolygonsSet) new RegionFactory<Euclidean2D>().getComplement(new PolygonsSet(TEST_TOLERANCE));
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ Assert.assertEquals(0.0, poly.getSize(), TEST_TOLERANCE);
+ Assert.assertEquals(0.0, poly.getBoundarySize(), TEST_TOLERANCE);
+ Assert.assertEquals(0, poly.getVertices().length);
+ Assert.assertTrue(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
+ Cartesian2D.ZERO,
+ new Cartesian2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+
+ for (double y = -1; y < 1; y += 0.1) {
+ for (double x = -1; x < 1; x += 0.1) {
+ GeometryTestUtils.assertPositiveInfinity(poly.projectToBoundary(new Cartesian2D(x, y)).getOffset());
+ }
+ }
+ }
+
+ @Test
+ public void testInfiniteLines_single() {
+ // arrange
+ Line line = new Line(new Cartesian2D(0, 0), new Cartesian2D(1, 1), TEST_TOLERANCE);
+
+ List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
+ boundaries.add(line.wholeHyperplane());
+
+ // act
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ line.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line.toSpace(new Cartesian1D(Float.MAX_VALUE))
+ }
+ }, poly.getVertices());
+
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(1, -1),
+ new Cartesian2D(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(-1, 1),
+ new Cartesian2D(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+ checkPoints(Region.Location.BOUNDARY, poly, Cartesian2D.ZERO);
+ }
+
@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);
+ Line line1 = new Line(new Cartesian2D(0, 0), new Cartesian2D(1, 1), TEST_TOLERANCE);
+ Line line2 = new Line(new Cartesian2D(1, -1), new Cartesian2D(0, 0), TEST_TOLERANCE);
List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
boundaries.add(line1.wholeHyperplane());
boundaries.add(line2.wholeHyperplane());
// act
- PolygonsSet poly = new PolygonsSet(boundaries, 1e-10);
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
// 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);
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
- 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);
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ line2.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line2.toSpace(new Cartesian1D(Float.MAX_VALUE))
+ }
+ }, poly.getVertices());
- checkPoints(Region.Location.INSIDE, poly, new Cartesian2D[] {
+ checkPoints(Region.Location.INSIDE, poly,
new Cartesian2D(-1, 0),
- new Cartesian2D(-Float.MAX_VALUE, Float.MAX_VALUE / 2.0)
- });
- checkPoints(Region.Location.OUTSIDE, poly, new Cartesian2D[] {
+ new Cartesian2D(-Float.MAX_VALUE, Float.MAX_VALUE / 2.0));
+ checkPoints(Region.Location.OUTSIDE, poly,
new Cartesian2D(1, 0),
- new Cartesian2D(Float.MAX_VALUE, Float.MAX_VALUE / 2.0)
- });
- checkPoints(Region.Location.BOUNDARY, poly, new Cartesian2D[] { Cartesian2D.ZERO });
+ new Cartesian2D(Float.MAX_VALUE, Float.MAX_VALUE / 2.0));
+ checkPoints(Region.Location.BOUNDARY, poly, Cartesian2D.ZERO);
}
@Test
- public void testSimplyConnected() {
- Cartesian2D[][] vertices = new Cartesian2D[][] {
- new Cartesian2D[] {
- new Cartesian2D(36.0, 22.0),
- new Cartesian2D(39.0, 32.0),
- new Cartesian2D(19.0, 32.0),
- new Cartesian2D( 6.0, 16.0),
- new Cartesian2D(31.0, 10.0),
- new Cartesian2D(42.0, 16.0),
- new Cartesian2D(34.0, 20.0),
- new Cartesian2D(29.0, 19.0),
- new Cartesian2D(23.0, 22.0),
- new Cartesian2D(33.0, 25.0)
+ public void testInfiniteLines_twoParallel_facingIn() {
+ // arrange
+ Line line1 = new Line(new Cartesian2D(1, 1), new Cartesian2D(0, 1), TEST_TOLERANCE);
+ Line line2 = new Line(new Cartesian2D(0, -1), new Cartesian2D(1, -1), TEST_TOLERANCE);
+
+ List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
+ boundaries.add(line1.wholeHyperplane());
+ boundaries.add(line2.wholeHyperplane());
+
+ // act
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ line1.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line1.toSpace(new Cartesian1D(Float.MAX_VALUE))
+ },
+ {
+ null,
+ line2.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line2.toSpace(new Cartesian1D(Float.MAX_VALUE))
}
- };
- PolygonsSet set = buildSet(vertices);
- Assert.assertEquals(Region.Location.OUTSIDE, set.checkPoint(new Cartesian2D(50.0, 30.0)));
- checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
- new Cartesian2D(30.0, 15.0),
- new Cartesian2D(15.0, 20.0),
- new Cartesian2D(24.0, 25.0),
- new Cartesian2D(35.0, 30.0),
- new Cartesian2D(19.0, 17.0)
- });
- checkPoints(Region.Location.OUTSIDE, set, new Cartesian2D[] {
- new Cartesian2D(50.0, 30.0),
- new Cartesian2D(30.0, 35.0),
- new Cartesian2D(10.0, 25.0),
- new Cartesian2D(10.0, 10.0),
- new Cartesian2D(40.0, 10.0),
- new Cartesian2D(50.0, 15.0),
- new Cartesian2D(30.0, 22.0)
- });
- checkPoints(Region.Location.BOUNDARY, set, new Cartesian2D[] {
- new Cartesian2D(30.0, 32.0),
- new Cartesian2D(34.0, 20.0)
- });
- checkVertices(set.getVertices(), vertices);
+ }, poly.getVertices());
+
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(0, 0),
+ new Cartesian2D(0, 0.9),
+ new Cartesian2D(0, -0.9));
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(0, 1.1),
+ new Cartesian2D(0, -1.1));
+ checkPoints(Region.Location.BOUNDARY, poly,
+ new Cartesian2D(0, 1),
+ new Cartesian2D(0, -1));
}
@Test
- public void testBox() {
- PolygonsSet box = new PolygonsSet(0, 2, -1, 1, 1.0e-10);
- Assert.assertEquals(4.0, box.getSize(), 1.0e-10);
- Assert.assertEquals(8.0, box.getBoundarySize(), 1.0e-10);
+ public void testInfiniteLines_twoParallel_facingOut() {
+ // arrange
+ Line line1 = new Line(new Cartesian2D(0, 1), new Cartesian2D(1, 1), TEST_TOLERANCE);
+ Line line2 = new Line(new Cartesian2D(1, -1), new Cartesian2D(0, -1), TEST_TOLERANCE);
+
+ List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
+ boundaries.add(line1.wholeHyperplane());
+ boundaries.add(line2.wholeHyperplane());
+
+ // act
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ line1.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line1.toSpace(new Cartesian1D(Float.MAX_VALUE))
+ },
+ {
+ null,
+ line2.toSpace(new Cartesian1D(-Float.MAX_VALUE)),
+ line2.toSpace(new Cartesian1D(Float.MAX_VALUE))
+ }
+ }, poly.getVertices());
+
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(0, 0),
+ new Cartesian2D(0, 0.9),
+ new Cartesian2D(0, -0.9));
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(0, 1.1),
+ new Cartesian2D(0, -1.1));
+ checkPoints(Region.Location.BOUNDARY, poly,
+ new Cartesian2D(0, 1),
+ new Cartesian2D(0, -1));
}
@Test
- public void testInfinite() {
- PolygonsSet box = new PolygonsSet(new BSPTree<Euclidean2D>(Boolean.TRUE), 1.0e-10);
- Assert.assertTrue(Double.isInfinite(box.getSize()));
+ public void testMixedFiniteAndInfiniteLines_explicitInfiniteBoundaries() {
+ // arrange
+ Line line1 = new Line(new Cartesian2D(3, 3), new Cartesian2D(0, 3), TEST_TOLERANCE);
+ Line line2 = new Line(new Cartesian2D(0, -3), new Cartesian2D(3, -3), TEST_TOLERANCE);
+
+ List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
+ boundaries.add(line1.wholeHyperplane());
+ boundaries.add(line2.wholeHyperplane());
+ boundaries.add(buildSegment(new Cartesian2D(0, 3), new Cartesian2D(0, -3)));
+
+ // act
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
+
+ // assert
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ new Cartesian2D(1, 3), // dummy point
+ new Cartesian2D(0, 3),
+ new Cartesian2D(0, -3),
+ new Cartesian2D(1, -3) // dummy point
+ }
+ }, poly.getVertices());
+
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(0.1, 2.9),
+ new Cartesian2D(0.1, 0),
+ new Cartesian2D(0.1, -2.9));
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(0, 3.1),
+ new Cartesian2D(-0.5, 0),
+ new Cartesian2D(0, -3.1));
+ checkPoints(Region.Location.BOUNDARY, poly,
+ new Cartesian2D(3, 3),
+ new Cartesian2D(0, 0),
+ new Cartesian2D(3, -3));
}
+ // The polygon in this test is created from finite boundaries but the generated
+ // loop still begins and ends with infinite lines. This is because the boundaries
+ // used as input do not form a closed region, therefore the region itself is unclosed.
+ // In other words, the boundaries used as input only define the region, not the points
+ // returned from the getVertices() method.
@Test
- public void testSingleInfiniteLine() {
+ public void testMixedFiniteAndInfiniteLines_impliedInfiniteBoundaries() {
// arrange
- double tolerance = 1e-10;
- Line line = new Line(new Cartesian2D(0, 0), new Cartesian2D(1, 1), tolerance);
+ Line line = new Line(new Cartesian2D(3, 0), new Cartesian2D(3, 3), TEST_TOLERANCE);
List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
- boundaries.add(line.wholeHyperplane());
+ boundaries.add(buildSegment(new Cartesian2D(0, 3), new Cartesian2D(0, 0)));
+ boundaries.add(buildSegment(new Cartesian2D(0, 0), new Cartesian2D(3, 0)));
+ boundaries.add(new SubLine(line, new IntervalsSet(0, Double.POSITIVE_INFINITY, TEST_TOLERANCE)));
// act
- PolygonsSet polygon = new PolygonsSet(boundaries, tolerance);
+ PolygonsSet poly = new PolygonsSet(boundaries, TEST_TOLERANCE);
// assert
- Assert.assertTrue(Double.isInfinite(polygon.getSize()));
+ Assert.assertEquals(TEST_TOLERANCE, poly.getTolerance(), Precision.EPSILON);
+ GeometryTestUtils.assertPositiveInfinity(poly.getSize());
+ GeometryTestUtils.assertPositiveInfinity(poly.getBoundarySize());
+ Assert.assertFalse(poly.isEmpty());
+ Assert.assertFalse(poly.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ null,
+ new Cartesian2D(0, 1), // dummy point
+ new Cartesian2D(0, 0),
+ new Cartesian2D(3, 0),
+ new Cartesian2D(3, 1) // dummy point
+ }
+ }, poly.getVertices());
+
+ checkPoints(Region.Location.INSIDE, poly,
+ new Cartesian2D(0.1, Float.MAX_VALUE),
+ new Cartesian2D(0.1, 0.1),
+ new Cartesian2D(1.5, 0.1),
+ new Cartesian2D(2.9, 0.1),
+ new Cartesian2D(2.9, Float.MAX_VALUE));
+ checkPoints(Region.Location.OUTSIDE, poly,
+ new Cartesian2D(-0.1, Float.MAX_VALUE),
+ new Cartesian2D(-0.1, 0.1),
+ new Cartesian2D(1.5, -0.1),
+ new Cartesian2D(3.1, 0.1),
+ new Cartesian2D(3.1, Float.MAX_VALUE));
+ checkPoints(Region.Location.BOUNDARY, poly,
+ new Cartesian2D(0, 1),
+ new Cartesian2D(1, 0),
+ new Cartesian2D(3, 1));
+ }
- Cartesian2D[][] vertices = polygon.getVertices();
- Assert.assertEquals(1, vertices.length);
+ @Test
+ public void testBox() {
+ // act
+ PolygonsSet box = new PolygonsSet(0, 2, -1, 1, TEST_TOLERANCE);
- Cartesian2D[] loop = vertices[0];
- Assert.assertEquals(3, loop.length);
- Assert.assertEquals(null, loop[0]);
- checkPointsEqual(line.toSpace(new Cartesian1D(-Float.MAX_VALUE)), loop[1], tolerance);
- checkPointsEqual(line.toSpace(new Cartesian1D(Float.MAX_VALUE)), loop[2], tolerance);
+ // assert
+ Assert.assertEquals(4.0, box.getSize(), TEST_TOLERANCE);
+ Assert.assertEquals(8.0, box.getBoundarySize(), TEST_TOLERANCE);
+ Assert.assertFalse(box.isEmpty());
+ Assert.assertFalse(box.isFull());
+ GeometryTestUtils.assertVectorEquals(new Cartesian2D(1, 0), (Cartesian2D) box.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ new Cartesian2D(2, -1),
+ new Cartesian2D(2, 1),
+ new Cartesian2D(0, 1),
+ new Cartesian2D(0, -1)
+ }
+ }, box.getVertices());
+
+ checkPoints(Region.Location.INSIDE, box,
+ new Cartesian2D(0.1, 0),
+ new Cartesian2D(1.9, 0),
+ new Cartesian2D(1, 0.9),
+ new Cartesian2D(1, -0.9));
+ checkPoints(Region.Location.OUTSIDE, box,
+ new Cartesian2D(-0.1, 0),
+ new Cartesian2D(2.1, 0),
+ new Cartesian2D(1, -1.1),
+ new Cartesian2D(1, 1.1));
+ checkPoints(Region.Location.BOUNDARY, box,
+ new Cartesian2D(0, 0),
+ new Cartesian2D(2, 0),
+ new Cartesian2D(1, 1),
+ new Cartesian2D(1, -1));
}
@Test
- public void testMixOfFiniteAndInfiniteBoundaries() {
+ public void testInvertedBox() {
// arrange
- double tolerance = 1e-10;
-
- Line line = new Line(new Cartesian2D(1, 0), new Cartesian2D(1, 1), tolerance);
-
List<SubHyperplane<Euclidean2D>> boundaries = new ArrayList<SubHyperplane<Euclidean2D>>();
- boundaries.add(buildSegment(new Cartesian2D(0, 1), new Cartesian2D(0, 0)));
- boundaries.add(buildSegment(new Cartesian2D(0, 0), new Cartesian2D(1, 0)));
- boundaries.add(new SubLine(line, new IntervalsSet(0, Double.POSITIVE_INFINITY, tolerance)));
+ boundaries.add(buildSegment(new Cartesian2D(0, -1), new Cartesian2D(0, 1)));
+ boundaries.add(buildSegment(new Cartesian2D(2, 1), new Cartesian2D(2, -1)));
+ boundaries.add(buildSegment(new Cartesian2D(0, 1), new Cartesian2D(2, 1)));
+ boundaries.add(buildSegment(new Cartesian2D(2, -1), new Cartesian2D(0, -1)));
// act
- PolygonsSet polygon = new PolygonsSet(boundaries, tolerance);
+ PolygonsSet box = new PolygonsSet(boundaries, TEST_TOLERANCE);
// assert
- Assert.assertTrue(Double.isInfinite(polygon.getSize()));
+ GeometryTestUtils.assertPositiveInfinity(box.getSize());
+ Assert.assertEquals(8.0, box.getBoundarySize(), TEST_TOLERANCE);
+ Assert.assertFalse(box.isEmpty());
+ Assert.assertFalse(box.isFull());
+ GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) box.getBarycenter(), TEST_TOLERANCE);
+
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ new Cartesian2D(0, -1),
+ new Cartesian2D(0, 1),
+ new Cartesian2D(2, 1),
+ new Cartesian2D(2, -1)
+ }
+ }, box.getVertices());
+
+ checkPoints(Region.Location.OUTSIDE, box,
+ new Cartesian2D(0.1, 0),
+ new Cartesian2D(1.9, 0),
+ new Cartesian2D(1, 0.9),
+ new Cartesian2D(1, -0.9));
+ checkPoints(Region.Location.INSIDE, box,
+ new Cartesian2D(-0.1, 0),
+ new Cartesian2D(2.1, 0),
+ new Cartesian2D(1, -1.1),
+ new Cartesian2D(1, 1.1));
+ checkPoints(Region.Location.BOUNDARY, box,
+ new Cartesian2D(0, 0),
+ new Cartesian2D(2, 0),
+ new Cartesian2D(1, 1),
+ new Cartesian2D(1, -1));
+ }
- Cartesian2D[][] vertices = polygon.getVertices();
- Assert.assertEquals(1, vertices.length);
+ @Test
+ public void testSimplyConnected() {
+ // arrange
+ Cartesian2D[][] vertices = new Cartesian2D[][] {
+ new Cartesian2D[] {
+ new Cartesian2D(36.0, 22.0),
+ new Cartesian2D(39.0, 32.0),
+ new Cartesian2D(19.0, 32.0),
+ new Cartesian2D( 6.0, 16.0),
+ new Cartesian2D(31.0, 10.0),
+ new Cartesian2D(42.0, 16.0),
+ new Cartesian2D(34.0, 20.0),
+ new Cartesian2D(29.0, 19.0),
+ new Cartesian2D(23.0, 22.0),
+ new Cartesian2D(33.0, 25.0)
+ }
+ };
+
+ // act
+ PolygonsSet set = buildSet(vertices);
+
+ // assert
+ checkPoints(Region.Location.INSIDE, set,
+ new Cartesian2D(30.0, 15.0),
+ new Cartesian2D(15.0, 20.0),
+ new Cartesian2D(24.0, 25.0),
+ new Cartesian2D(35.0, 30.0),
+ new Cartesian2D(19.0, 17.0));
+ checkPoints(Region.Location.OUTSIDE, set,
+ new Cartesian2D(50.0, 30.0),
+ new Cartesian2D(30.0, 35.0),
+ new Cartesian2D(10.0, 25.0),
+ new Cartesian2D(10.0, 10.0),
+ new Cartesian2D(40.0, 10.0),
+ new Cartesian2D(50.0, 15.0),
+ new Cartesian2D(30.0, 22.0));
+ checkPoints(Region.Location.BOUNDARY, set,
+ new Cartesian2D(30.0, 32.0),
+ new Cartesian2D(34.0, 20.0));
- Cartesian2D[] loop = vertices[0];
- Assert.assertEquals(5, loop.length);
- Assert.assertEquals(null, loop[0]);
- checkPointsEqual(new Cartesian2D(0, 1), loop[1], tolerance);
- checkPointsEqual(new Cartesian2D(0, 0), loop[2], tolerance);
- checkPointsEqual(new Cartesian2D(1, 0), loop[3], tolerance);
- checkPointsEqual(new Cartesian2D(1, 0), loop[4], tolerance);
+ checkVertexLoopsEquivalent(vertices, set.getVertices());
}
@Test
public void testStair() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -212,74 +506,18 @@ public class PolygonsSetTest {
}
};
- PolygonsSet set = buildSet(vertices);
- checkVertices(set.getVertices(), vertices);
-
- Assert.assertEquals(1.1 + 0.95 * FastMath.sqrt(2.0), set.getSize(), 1.0e-10);
-
- }
-
- @Test
- public void testEmpty() {
// act
- PolygonsSet poly = (PolygonsSet) new RegionFactory<Euclidean2D>().getComplement(new PolygonsSet(1e-10));
-
- // assert
- Assert.assertEquals(1e-10, poly.getTolerance(), Precision.EPSILON);
- Assert.assertEquals(0.0, poly.getSize(), 1e-10);
- Assert.assertEquals(0.0, poly.getBoundarySize(), 1e-10);
- Assert.assertEquals(0, poly.getVertices().length);
- Assert.assertTrue(poly.isEmpty());
- Assert.assertFalse(poly.isFull());
- GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), 1e-10);
-
- checkPoints(Region.Location.OUTSIDE, poly, new Cartesian2D[] {
- new Cartesian2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
- Cartesian2D.ZERO,
- new Cartesian2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)});
-
- double offset;
- for (double y = -1; y < 1; y += 0.1) {
- for (double x = -1; x < 1; x += 0.1) {
- offset = poly.projectToBoundary(new Cartesian2D(x, y)).getOffset();
- Assert.assertTrue(offset > 0);
- Assert.assertTrue(Double.isInfinite(offset));
- }
- }
- }
-
- @Test
- public void testFull() {
- // act
- PolygonsSet poly = new PolygonsSet(1e-10);
+ PolygonsSet set = buildSet(vertices);
// assert
- Assert.assertEquals(1e-10, poly.getTolerance(), Precision.EPSILON);
- Assert.assertTrue(poly.getSize() > 0);
- Assert.assertTrue(Double.isInfinite(poly.getSize()));
- Assert.assertEquals(0.0, poly.getBoundarySize(), 1e-10);
- Assert.assertEquals(0, poly.getVertices().length);
- Assert.assertFalse(poly.isEmpty());
- Assert.assertTrue(poly.isFull());
- GeometryTestUtils.assertVectorEquals(Cartesian2D.NaN, (Cartesian2D) poly.getBarycenter(), 1e-10);
-
- checkPoints(Region.Location.INSIDE, poly, new Cartesian2D[] {
- new Cartesian2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY),
- Cartesian2D.ZERO,
- new Cartesian2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)});
+ checkVertexLoopsEquivalent(vertices, set.getVertices());
- double offset;
- for (double y = -1; y < 1; y += 0.1) {
- for (double x = -1; x < 1; x += 0.1) {
- offset = poly.projectToBoundary(new Cartesian2D(x, y)).getOffset();
- Assert.assertTrue(offset < 0);
- Assert.assertTrue(Double.isInfinite(offset));
- }
- }
+ Assert.assertEquals(1.1 + 0.95 * FastMath.sqrt(2.0), set.getSize(), TEST_TOLERANCE);
}
@Test
public void testHole() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(0.0, 0.0),
@@ -293,7 +531,11 @@ public class PolygonsSetTest {
new Cartesian2D(1.0, 1.0)
}
};
+
+ // act
PolygonsSet set = buildSet(vertices);
+
+ // assert
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(0.5, 0.5),
new Cartesian2D(1.5, 0.5),
@@ -319,7 +561,7 @@ public class PolygonsSetTest {
new Cartesian2D(1.5, 3.0),
new Cartesian2D(3.0, 3.0)
});
- checkVertices(set.getVertices(), vertices);
+ checkVertexLoopsEquivalent(vertices, set.getVertices());
for (double x = -0.999; x < 3.999; x += 0.11) {
Cartesian2D v = new Cartesian2D(x, x + 0.5);
@@ -327,37 +569,36 @@ public class PolygonsSetTest {
Assert.assertTrue(projection.getOriginal() == v);
Cartesian2D p = (Cartesian2D) projection.getProjected();
if (x < -0.5) {
- Assert.assertEquals(0.0, p.getX(), 1.0e-10);
- Assert.assertEquals(0.0, p.getY(), 1.0e-10);
- Assert.assertEquals(+v.distance(Cartesian2D.ZERO), projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(0.0, p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(0.0, p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(+v.distance(Cartesian2D.ZERO), projection.getOffset(), TEST_TOLERANCE);
} else if (x < 0.5) {
- Assert.assertEquals(0.0, p.getX(), 1.0e-10);
- Assert.assertEquals(v.getY(), p.getY(), 1.0e-10);
- Assert.assertEquals(-v.getX(), projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(0.0, p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(v.getY(), p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(-v.getX(), projection.getOffset(), TEST_TOLERANCE);
} else if (x < 1.25) {
- Assert.assertEquals(1.0, p.getX(), 1.0e-10);
- Assert.assertEquals(v.getY(), p.getY(), 1.0e-10);
- Assert.assertEquals(v.getX() - 1.0, projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(1.0, p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(v.getY(), p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(v.getX() - 1.0, projection.getOffset(), TEST_TOLERANCE);
} else if (x < 2.0) {
- Assert.assertEquals(v.getX(), p.getX(), 1.0e-10);
- Assert.assertEquals(2.0, p.getY(), 1.0e-10);
- Assert.assertEquals(2.0 - v.getY(), projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(v.getX(), p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(2.0, p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(2.0 - v.getY(), projection.getOffset(), TEST_TOLERANCE);
} else if (x < 3.0) {
- Assert.assertEquals(v.getX(), p.getX(), 1.0e-10);
- Assert.assertEquals(3.0, p.getY(), 1.0e-10);
- Assert.assertEquals(v.getY() - 3.0, projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(v.getX(), p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(3.0, p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(v.getY() - 3.0, projection.getOffset(), TEST_TOLERANCE);
} else {
- Assert.assertEquals(3.0, p.getX(), 1.0e-10);
- Assert.assertEquals(3.0, p.getY(), 1.0e-10);
- Assert.assertEquals(+v.distance(new Cartesian2D(3, 3)), projection.getOffset(), 1.0e-10);
+ Assert.assertEquals(3.0, p.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(3.0, p.getY(), TEST_TOLERANCE);
+ Assert.assertEquals(+v.distance(new Cartesian2D(3, 3)), projection.getOffset(), TEST_TOLERANCE);
}
-
}
-
}
@Test
public void testDisjointPolygons() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(0.0, 1.0),
@@ -369,7 +610,11 @@ public class PolygonsSetTest {
new Cartesian2D(3.0, 1.0)
}
};
+
+ // act
PolygonsSet set = buildSet(vertices);
+
+ // assert
Assert.assertEquals(Region.Location.INSIDE, set.checkPoint(new Cartesian2D(1.0, 1.5)));
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(1.0, 1.5),
@@ -386,11 +631,12 @@ public class PolygonsSetTest {
new Cartesian2D(3.5, 0.5),
new Cartesian2D(0.0, 1.0)
});
- checkVertices(set.getVertices(), vertices);
+ checkVertexLoopsEquivalent(vertices, set.getVertices());
}
@Test
public void testOppositeHyperplanes() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(1.0, 0.0),
@@ -401,12 +647,17 @@ public class PolygonsSetTest {
new Cartesian2D(0.0, 1.0)
}
};
+
+ // act
PolygonsSet set = buildSet(vertices);
- checkVertices(set.getVertices(), vertices);
+
+ // assert
+ checkVertexLoopsEquivalent(vertices, set.getVertices());
}
@Test
public void testSingularPoint() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -419,12 +670,30 @@ public class PolygonsSetTest {
new Cartesian2D( 0.0, -1.0)
}
};
+
+ // act
PolygonsSet set = buildSet(vertices);
- checkVertices(set.getVertices(), vertices);
+
+ // assert
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
+ {
+ new Cartesian2D( 0.0, 0.0),
+ new Cartesian2D( 1.0, 0.0),
+ new Cartesian2D( 1.0, 1.0),
+ new Cartesian2D( 0.0, 1.0)
+ },
+ {
+ new Cartesian2D( 0.0, 0.0),
+ new Cartesian2D(-1.0, 0.0),
+ new Cartesian2D(-1.0, -1.0),
+ new Cartesian2D( 0.0, -1.0)
+ }
+ }, set.getVertices());
}
@Test
public void testLineIntersection() {
+ // arrange
Cartesian2D[][] vertices = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -437,43 +706,46 @@ public class PolygonsSetTest {
new Cartesian2D( 0.0, 2.0)
}
};
+
+ // act
PolygonsSet set = buildSet(vertices);
- Line l1 = new Line(new Cartesian2D(-1.5, 0.0), FastMath.PI / 4, 1.0e-10);
+ // assert
+ Line l1 = new Line(new Cartesian2D(-1.5, 0.0), FastMath.PI / 4, TEST_TOLERANCE);
SubLine s1 = (SubLine) set.intersection(l1.wholeHyperplane());
List<Interval> i1 = ((IntervalsSet) s1.getRemainingRegion()).asList();
Assert.assertEquals(2, i1.size());
Interval v10 = i1.get(0);
Cartesian2D p10Lower = l1.toSpace(new Cartesian1D(v10.getInf()));
- Assert.assertEquals(0.0, p10Lower.getX(), 1.0e-10);
- Assert.assertEquals(1.5, p10Lower.getY(), 1.0e-10);
+ Assert.assertEquals(0.0, p10Lower.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(1.5, p10Lower.getY(), TEST_TOLERANCE);
Cartesian2D p10Upper = l1.toSpace(new Cartesian1D(v10.getSup()));
- Assert.assertEquals(0.5, p10Upper.getX(), 1.0e-10);
- Assert.assertEquals(2.0, p10Upper.getY(), 1.0e-10);
+ Assert.assertEquals(0.5, p10Upper.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(2.0, p10Upper.getY(), TEST_TOLERANCE);
Interval v11 = i1.get(1);
Cartesian2D p11Lower = l1.toSpace(new Cartesian1D(v11.getInf()));
- Assert.assertEquals(1.0, p11Lower.getX(), 1.0e-10);
- Assert.assertEquals(2.5, p11Lower.getY(), 1.0e-10);
+ Assert.assertEquals(1.0, p11Lower.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(2.5, p11Lower.getY(), TEST_TOLERANCE);
Cartesian2D p11Upper = l1.toSpace(new Cartesian1D(v11.getSup()));
- Assert.assertEquals(1.5, p11Upper.getX(), 1.0e-10);
- Assert.assertEquals(3.0, p11Upper.getY(), 1.0e-10);
+ Assert.assertEquals(1.5, p11Upper.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(3.0, p11Upper.getY(), TEST_TOLERANCE);
- Line l2 = new Line(new Cartesian2D(-1.0, 2.0), 0, 1.0e-10);
+ Line l2 = new Line(new Cartesian2D(-1.0, 2.0), 0, TEST_TOLERANCE);
SubLine s2 = (SubLine) set.intersection(l2.wholeHyperplane());
List<Interval> i2 = ((IntervalsSet) s2.getRemainingRegion()).asList();
Assert.assertEquals(1, i2.size());
Interval v20 = i2.get(0);
Cartesian2D p20Lower = l2.toSpace(new Cartesian1D(v20.getInf()));
- Assert.assertEquals(1.0, p20Lower.getX(), 1.0e-10);
- Assert.assertEquals(2.0, p20Lower.getY(), 1.0e-10);
+ Assert.assertEquals(1.0, p20Lower.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(2.0, p20Lower.getY(), TEST_TOLERANCE);
Cartesian2D p20Upper = l2.toSpace(new Cartesian1D(v20.getSup()));
- Assert.assertEquals(3.0, p20Upper.getX(), 1.0e-10);
- Assert.assertEquals(2.0, p20Upper.getY(), 1.0e-10);
-
+ Assert.assertEquals(3.0, p20Upper.getX(), TEST_TOLERANCE);
+ Assert.assertEquals(2.0, p20Upper.getY(), TEST_TOLERANCE);
}
@Test
public void testUnlimitedSubHyperplane() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(0.0, 0.0),
@@ -492,12 +764,15 @@ public class PolygonsSetTest {
};
PolygonsSet set2 = buildSet(vertices2);
+ // act
PolygonsSet set =
(PolygonsSet) new RegionFactory<Euclidean2D>().union(set1.copySelf(),
set2.copySelf());
- checkVertices(set1.getVertices(), vertices1);
- checkVertices(set2.getVertices(), vertices2);
- checkVertices(set.getVertices(), new Cartesian2D[][] {
+
+ // assert
+ checkVertexLoopsEquivalent(vertices1, set1.getVertices());
+ checkVertexLoopsEquivalent(vertices2, set2.getVertices());
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(0.0, 0.0),
new Cartesian2D(1.6, 0.0),
@@ -507,12 +782,12 @@ public class PolygonsSetTest {
new Cartesian2D(1.4, 1.5),
new Cartesian2D(0.0, 3.5)
}
- });
-
+ }, set.getVertices());
}
@Test
public void testUnion() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -531,11 +806,15 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
+
+ // act
PolygonsSet set = (PolygonsSet) new RegionFactory<Euclidean2D>().union(set1.copySelf(),
set2.copySelf());
- checkVertices(set1.getVertices(), vertices1);
- checkVertices(set2.getVertices(), vertices2);
- checkVertices(set.getVertices(), new Cartesian2D[][] {
+
+ // assert
+ checkVertexLoopsEquivalent(vertices1, set1.getVertices());
+ checkVertexLoopsEquivalent(vertices2, set2.getVertices());
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
new Cartesian2D( 2.0, 0.0),
@@ -546,7 +825,8 @@ public class PolygonsSetTest {
new Cartesian2D( 1.0, 2.0),
new Cartesian2D( 0.0, 2.0)
}
- });
+ }, set.getVertices());
+
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(1.0, 1.0),
new Cartesian2D(0.5, 0.5),
@@ -572,11 +852,11 @@ public class PolygonsSetTest {
new Cartesian2D(2.5, 1.0),
new Cartesian2D(3.0, 2.5)
});
-
}
@Test
public void testIntersection() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -595,18 +875,23 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
+
+ // act
PolygonsSet set = (PolygonsSet) new RegionFactory<Euclidean2D>().intersection(set1.copySelf(),
set2.copySelf());
- checkVertices(set1.getVertices(), vertices1);
- checkVertices(set2.getVertices(), vertices2);
- checkVertices(set.getVertices(), new Cartesian2D[][] {
+
+ // assert
+ checkVertexLoopsEquivalent(vertices1, set1.getVertices());
+ checkVertexLoopsEquivalent(vertices2, set2.getVertices());
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 1.0, 1.0),
new Cartesian2D( 2.0, 1.0),
new Cartesian2D( 2.0, 2.0),
new Cartesian2D( 1.0, 2.0)
}
- });
+ }, set.getVertices());
+
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(1.5, 1.5)
});
@@ -626,6 +911,7 @@ public class PolygonsSetTest {
@Test
public void testXor() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -644,11 +930,15 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
+
+ // act
PolygonsSet set = (PolygonsSet) new RegionFactory<Euclidean2D>().xor(set1.copySelf(),
set2.copySelf());
- checkVertices(set1.getVertices(), vertices1);
- checkVertices(set2.getVertices(), vertices2);
- checkVertices(set.getVertices(), new Cartesian2D[][] {
+
+ // assert
+ checkVertexLoopsEquivalent(vertices1, set1.getVertices());
+ checkVertexLoopsEquivalent(vertices2, set2.getVertices());
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
new Cartesian2D( 2.0, 0.0),
@@ -665,7 +955,8 @@ public class PolygonsSetTest {
new Cartesian2D( 2.0, 2.0),
new Cartesian2D( 2.0, 1.0)
}
- });
+ }, set.getVertices());
+
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(0.5, 0.5),
new Cartesian2D(2.5, 2.5),
@@ -697,6 +988,7 @@ public class PolygonsSetTest {
@Test
public void testDifference() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
@@ -715,11 +1007,15 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
+
+ // act
PolygonsSet set = (PolygonsSet) new RegionFactory<Euclidean2D>().difference(set1.copySelf(),
set2.copySelf());
- checkVertices(set1.getVertices(), vertices1);
- checkVertices(set2.getVertices(), vertices2);
- checkVertices(set.getVertices(), new Cartesian2D[][] {
+
+ // assert
+ checkVertexLoopsEquivalent(vertices1, set1.getVertices());
+ checkVertexLoopsEquivalent(vertices2, set2.getVertices());
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.0, 0.0),
new Cartesian2D( 2.0, 0.0),
@@ -728,7 +1024,8 @@ public class PolygonsSetTest {
new Cartesian2D( 1.0, 2.0),
new Cartesian2D( 0.0, 2.0)
}
- });
+ }, set.getVertices());
+
checkPoints(Region.Location.INSIDE, set, new Cartesian2D[] {
new Cartesian2D(0.5, 0.5),
new Cartesian2D(0.5, 1.5),
@@ -760,6 +1057,7 @@ public class PolygonsSetTest {
@Test
public void testEmptyDifference() {
+ // arrange
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D( 0.5, 3.5),
@@ -778,21 +1076,28 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
- Assert.assertTrue(new RegionFactory<Euclidean2D>().difference(set1.copySelf(), set2.copySelf()).isEmpty());
+
+ // act
+ PolygonsSet diff = (PolygonsSet) new RegionFactory<Euclidean2D>().difference(set1.copySelf(), set2.copySelf());
+
+ // assert
+ Assert.assertEquals(0.0, diff.getSize(), TEST_TOLERANCE);
+ Assert.assertTrue(diff.isEmpty());
}
@Test
public void testChoppedHexagon() {
+ // arrange
double pi6 = FastMath.PI / 6.0;
double sqrt3 = FastMath.sqrt(3.0);
SubLine[] hyp = {
- new Line(new Cartesian2D( 0.0, 1.0), 5 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D(-sqrt3, 1.0), 7 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D(-sqrt3, 1.0), 9 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D(-sqrt3, 0.0), 11 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D( 0.0, 0.0), 13 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D( 0.0, 1.0), 3 * pi6, 1.0e-10).wholeHyperplane(),
- new Line(new Cartesian2D(-5.0 * sqrt3 / 6.0, 0.0), 9 * pi6, 1.0e-10).wholeHyperplane()
+ new Line(new Cartesian2D( 0.0, 1.0), 5 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D(-sqrt3, 1.0), 7 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D(-sqrt3, 1.0), 9 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D(-sqrt3, 0.0), 11 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D( 0.0, 0.0), 13 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D( 0.0, 1.0), 3 * pi6, TEST_TOLERANCE).wholeHyperplane(),
+ new Line(new Cartesian2D(-5.0 * sqrt3 / 6.0, 0.0), 9 * pi6, TEST_TOLERANCE).wholeHyperplane()
};
hyp[1] = (SubLine) hyp[1].split(hyp[0].getHyperplane()).getMinus();
hyp[2] = (SubLine) hyp[2].split(hyp[1].getHyperplane()).getMinus();
@@ -804,22 +1109,26 @@ public class PolygonsSetTest {
for (int i = hyp.length - 1; i >= 0; --i) {
tree = new BSPTree<>(hyp[i], new BSPTree<Euclidean2D>(Boolean.FALSE), tree, null);
}
- PolygonsSet set = new PolygonsSet(tree, 1.0e-10);
+ PolygonsSet set = new PolygonsSet(tree, TEST_TOLERANCE);
SubLine splitter =
- new Line(new Cartesian2D(-2.0 * sqrt3 / 3.0, 0.0), 9 * pi6, 1.0e-10).wholeHyperplane();
+ new Line(new Cartesian2D(-2.0 * sqrt3 / 3.0, 0.0), 9 * pi6, TEST_TOLERANCE).wholeHyperplane();
+
+ // act
PolygonsSet slice =
new PolygonsSet(new BSPTree<>(splitter,
set.getTree(false).split(splitter).getPlus(),
new BSPTree<Euclidean2D>(Boolean.FALSE), null),
- 1.0e-10);
+ TEST_TOLERANCE);
+
+ // assert
Assert.assertEquals(Region.Location.OUTSIDE,
slice.checkPoint(new Cartesian2D(0.1, 0.5)));
- Assert.assertEquals(11.0 / 3.0, slice.getBoundarySize(), 1.0e-10);
-
+ Assert.assertEquals(11.0 / 3.0, slice.getBoundarySize(), TEST_TOLERANCE);
}
@Test
public void testConcentric() {
+ // arrange
double h = FastMath.sqrt(3.0) / 2.0;
Cartesian2D[][] vertices1 = new Cartesian2D[][] {
new Cartesian2D[] {
@@ -845,11 +1154,14 @@ public class PolygonsSetTest {
}
};
PolygonsSet set2 = buildSet(vertices2);
+
+ // act/assert
Assert.assertTrue(set2.contains(set1));
}
@Test
public void testBug20040520() {
+ // arrange
BSPTree<Euclidean2D> a0 =
new BSPTree<>(buildSegment(new Cartesian2D(0.85, -0.05),
new Cartesian2D(0.90, -0.10)),
@@ -933,10 +1245,12 @@ public class PolygonsSetTest {
new Cartesian2D(1.0, -0.10)),
new BSPTree<Euclidean2D>(Boolean.FALSE), b5, null);
+ // act
PolygonsSet c =
- (PolygonsSet) new RegionFactory<Euclidean2D>().union(new PolygonsSet(a9, 1.0e-10),
- new PolygonsSet(b6, 1.0e-10));
+ (PolygonsSet) new RegionFactory<Euclidean2D>().union(new PolygonsSet(a9, TEST_TOLERANCE),
+ new PolygonsSet(b6, TEST_TOLERANCE));
+ // assert
checkPoints(Region.Location.INSIDE, c, new Cartesian2D[] {
new Cartesian2D(0.83, -0.06),
new Cartesian2D(0.83, -0.15),
@@ -960,8 +1274,7 @@ public class PolygonsSetTest {
new Cartesian2D(0.93, -0.15)
});
- checkVertices(c.getVertices(),
- new Cartesian2D[][] {
+ checkVertexLoopsEquivalent(new Cartesian2D[][] {
new Cartesian2D[] {
new Cartesian2D(0.85, -0.15),
new Cartesian2D(0.90, -0.20),
@@ -972,29 +1285,28 @@ public class PolygonsSetTest {
new Cartesian2D(0.82, -0.05),
new Cartesian2D(0.82, -0.18),
}
- });
-
+ }, c.getVertices());
}
@Test
public void testBug20041003() {
-
+ // arrange
Line[] l = {
new Line(new Cartesian2D(0.0, 0.625000007541172),
- new Cartesian2D(1.0, 0.625000007541172), 1.0e-10),
+ new Cartesian2D(1.0, 0.625000007541172), TEST_TOLERANCE),
new Line(new Cartesian2D(-0.19204433621902645, 0.0),
- new Cartesian2D(-0.19204433621902645, 1.0), 1.0e-10),
+ new Cartesian2D(-0.19204433621902645, 1.0), TEST_TOLERANCE),
new Line(new Cartesian2D(-0.40303524786887, 0.4248364535319128),
- new Cartesian2D(-1.12851149797877, -0.2634107480798909), 1.0e-10),
+ new Cartesian2D(-1.12851149797877, -0.2634107480798909), TEST_TOLERANCE),
new Line(new Cartesian2D(0.0, 2.0),
- new Cartesian2D(1.0, 2.0), 1.0e-10)
+ new Cartesian2D(1.0, 2.0), TEST_TOLERANCE)
};
BSPTree<Euclidean2D> node1 =
new BSPTree<>(new SubLine(l[0],
new IntervalsSet(intersectionAbscissa(l[0], l[1]),
intersectionAbscissa(l[0], l[2]),
- 1.0e-10)),
+ TEST_TOLERANCE)),
new BSPTree<Euclidean2D>(Boolean.TRUE),
new BSPTree<Euclidean2D>(Boolean.FALSE),
null);
@@ -1002,14 +1314,14 @@ public class PolygonsSetTest {
new BSPTree<>(new SubLine(l[1],
new IntervalsSet(intersectionAbscissa(l[1], l[2]),
intersectionAbscissa(l[1], l[3]),
- 1.0e-10)),
+ TEST_TOLERANCE)),
node1,
new BSPTree<Euclidean2D>(Boolean.FALSE),
null);
BSPTree<Euclidean2D> node3 =
new BSPTree<>(new SubLine(l[2],
new IntervalsSet(intersectionAbscissa(l[2], l[3]),
- Double.POSITIVE_INFINITY, 1.0e-10)),
+ Double.POSITIVE_INFINITY, TEST_TOLERANCE)),
node2,
new BSPTree<Euclidean2D>(Boolean.FALSE),
null);
@@ -1019,22 +1331,27 @@ public class PolygonsSetTest {
new BSPTree<Euclidean2D>(Boolean.FALSE),
null);
- PolygonsSet set = new PolygonsSet(node4, 1.0e-10);
- Assert.assertEquals(0, set.getVertices().length);
+ // act
+ PolygonsSet set = new PolygonsSet(node4, TEST_TOLERANCE);
+ // assert
+ Assert.assertEquals(0, set.getVertices().length);
}
@Test
public void testSqueezedHexa() {
- PolygonsSet set = new PolygonsSet(1.0e-10,
+ // act
+ PolygonsSet set = new PolygonsSet(TEST_TOLERANCE,
new Cartesian2D(-6, -4), new Cartesian2D(-8, -8), new Cartesian2D( 8, -8),
new Cartesian2D( 6, -4), new Cartesian2D(10, 4), new Cartesian2D(-10, 4));
+
+ // assert
Assert.assertEquals(Location.OUTSIDE, set.checkPoint(new Cartesian2D(0, 6)));
}
@Test
public void testIssue880Simplified() {
-
+ // arrange
Cartesian2D[] vertices1 = new Cartesian2D[] {
new Cartesian2D( 90.13595870833188, 38.33604606376991),
new Cartesian2D( 90.14047850603913, 38.34600084496253),
@@ -1045,7 +1362,11 @@ public class PolygonsSetTest {
new Cartesian2D( 90.09081227075944, 38.37526295920463),
new Cartesian2D( 90.09081378927135, 38.375193883266434)
};
- PolygonsSet set1 = new PolygonsSet(1.0e-10, vertices1);
+
+ // act
+ PolygonsSet set1 = new PolygonsSet(TEST_TOLERANCE, vertices1);
+
+ // assert
Assert.assertEquals(Location.OUTSIDE, set1.checkPoint(new Cartesian2D(90.12, 38.32)));
Assert.assertEquals(Location.OUTSIDE, set1.checkPoint(new Cartesian2D(90.135, 38.355)));
@@ -1209,9 +1530,10 @@ public class PolygonsSetTest {
@Test
public void testTooThinBox() {
+ // act/assert
Assert.assertEquals(0.0,
- new PolygonsSet(0.0, 0.0, 0.0, 10.3206397147574, 1.0e-10).getSize(),
- 1.0e-10);
+ new PolygonsSet(0.0, 0.0, 0.0, 10.3206397147574, TEST_TOLERANCE).getSize(),
+ TEST_TOLERANCE);
}
@Test
@@ -1219,7 +1541,7 @@ public class PolygonsSetTest {
// the following is a wrong usage of the constructor.
// as explained in the javadoc, the failure is NOT detected at construction
// time but occurs later on
- PolygonsSet ps = new PolygonsSet(new BSPTree<Euclidean2D>(), 1.0e-10);
+ PolygonsSet ps = new PolygonsSet(new BSPTree<Euclidean2D>(), TEST_TOLERANCE);
Assert.assertNotNull(ps);
try {
ps.getSize();
@@ -1231,26 +1553,29 @@ public class PolygonsSetTest {
@Test
public void testIssue1162() {
- PolygonsSet p = new PolygonsSet(1.0e-10,
+ // arrange
+ PolygonsSet p = new PolygonsSet(TEST_TOLERANCE,
new Cartesian2D(4.267199999996532, -11.928637756014894),
new Cartesian2D(4.267200000026445, -14.12360595809307),
new Cartesian2D(9.144000000273694, -14.12360595809307),
new Cartesian2D(9.144000000233383, -11.928637756020067));
- PolygonsSet w = new PolygonsSet(1.0e-10,
+ PolygonsSet w = new PolygonsSet(TEST_TOLERANCE,
new Cartesian2D(2.56735636510452512E-9, -11.933116461089332),
new Cartesian2D(2.56735636510452512E-9, -12.393225665247766),
new Cartesian2D(2.56735636510452512E-9, -27.785625665247778),
new Cartesian2D(4.267200000030211, -27.785625665247778),
new Cartesian2D(4.267200000030211, -11.933116461089332));
+ // act/assert
Assert.assertFalse(p.contains(w));
-
}
@Test
- public void testThinRectangle() {
+ public void testThinRectangle_toleranceLessThanWidth_resultIsAccurate() {
+ // if tolerance is smaller than rectangle width, the rectangle is computed accurately
+ // arrange
RegionFactory<Euclidean2D> factory = new RegionFactory<>();
Cartesian2D pA = new Cartesian2D(0.0, 1.0);
Cartesian2D pB = new Cartesian2D(0.0, 0.0);
@@ -1264,39 +1589,56 @@ public class PolygonsSetTest {
new Line(pC, pD, 1.0 / 256),
new Line(pD, pA, 1.0 / 256)
};
+
+ // act
Region<Euclidean2D> accuratePolygon = factory.buildConvex(h1);
- Assert.assertEquals(1.0 / 64.0, accuratePolygon.getSize(), 1.0e-10);
- Assert.assertTrue(Double.isInfinite(new RegionFactory<Euclidean2D>().getComplement(accuratePolygon).getSize()));
- Assert.assertEquals(2 * (1.0 + 1.0 / 64.0), accuratePolygon.getBoundarySize(), 1.0e-10);
+ // assert
+ Assert.assertEquals(1.0 / 64.0, accuratePolygon.getSize(), TEST_TOLERANCE);
+ GeometryTestUtils.assertPositiveInfinity(new RegionFactory<Euclidean2D>().getComplement(accuratePolygon).getSize());
+ Assert.assertEquals(2 * (1.0 + 1.0 / 64.0), accuratePolygon.getBoundarySize(), TEST_TOLERANCE);
+ }
+
+ @Test
+ public void testThinRectangle_toleranceGreaterThanWidth_resultIsDegenerate() {
// if tolerance is larger than rectangle width, the rectangle degenerates
// as of 3.3, its two long edges cannot be distinguished anymore and this part of the test did fail
// this has been fixed in 3.4 (issue MATH-1174)
+
+ // arrange
+ RegionFactory<Euclidean2D> factory = new RegionFactory<>();
+ Cartesian2D pA = new Cartesian2D(0.0, 1.0);
+ Cartesian2D pB = new Cartesian2D(0.0, 0.0);
+ Cartesian2D pC = new Cartesian2D(1.0 / 64.0, 0.0);
+ Cartesian2D pD = new Cartesian2D(1.0 / 64.0, 1.0);
+
Hyperplane<Euclidean2D>[] h2 = new Line[] {
- new Line(pA, pB, 1.0 / 16),
- new Line(pB, pC, 1.0 / 16),
- new Line(pC, pD, 1.0 / 16),
- new Line(pD, pA, 1.0 / 16)
- };
+ new Line(pA, pB, 1.0 / 16),
+ new Line(pB, pC, 1.0 / 16),
+ new Line(pC, pD, 1.0 / 16),
+ new Line(pD, pA, 1.0 / 16)
+ };
+
+ // act
Region<Euclidean2D> degeneratedPolygon = factory.buildConvex(h2);
- Assert.assertEquals(0.0, degeneratedPolygon.getSize(), 1.0e-10);
- Assert.assertTrue(degeneratedPolygon.isEmpty());
+ // assert
+ Assert.assertEquals(0.0, degeneratedPolygon.getSize(), TEST_TOLERANCE);
+ Assert.assertTrue(degeneratedPolygon.isEmpty());
}
- @SuppressWarnings("unchecked")
- @Test(expected=MathIllegalArgumentException.class)
+ @Test(expected = MathIllegalArgumentException.class)
public void testInconsistentHyperplanes() {
- double tolerance = 1.0e-10;
+ // act
+ double tolerance = TEST_TOLERANCE;
new RegionFactory<Euclidean2D>().buildConvex(new Line(new Cartesian2D(0, 0), new Cartesian2D(0, 1), tolerance),
new Line(new Cartesian2D(1, 1), new Cartesian2D(1, 0), tolerance));
}
@Test
public void testBoundarySimplification() {
-
// a simple square will result in a 4 cuts and 5 leafs tree
- PolygonsSet square = new PolygonsSet(1.0e-10,
+ PolygonsSet square = new PolygonsSet(TEST_TOLERANCE,
new Cartesian2D(0, 0),
new Cartesian2D(1, 0),
new Cartesian2D(1, 1),
@@ -1325,7 +1667,6 @@ public class PolygonsSetTest {
Cartesian2D[][] splitBoundary = splitSquare.getVertices();
Assert.assertEquals(1, splitBoundary.length);
Assert.assertEquals(4, splitBoundary[0].length);
-
}
private static class Counter {
@@ -1360,7 +1701,6 @@ public class PolygonsSetTest {
public int getLeafNodes() {
return leafNodes;
}
-
}
private PolygonsSet buildSet(Cartesian2D[][] vertices) {
@@ -1371,11 +1711,11 @@ public class PolygonsSetTest {
edges.add(buildSegment(vertices[i][j], vertices[i][(j + 1) % l]));
}
}
- return new PolygonsSet(edges, 1.0e-10);
+ return new PolygonsSet(edges, TEST_TOLERANCE);
}
private SubHyperplane<Euclidean2D> buildLine(Cartesian2D start, Cartesian2D end) {
- return new Line(start, end, 1.0e-10).wholeHyperplane();
+ return new Line(start, end, TEST_TOLERANCE).wholeHyperplane();
}
private double intersectionAbscissa(Line l0, Line l1) {
@@ -1385,80 +1725,120 @@ public class PolygonsSetTest {
private SubHyperplane<Euclidean2D> buildHalfLine(Cartesian2D start, Cartesian2D end,
boolean startIsVirtual) {
- Line line = new Line(start, end, 1.0e-10);
+ Line line = new Line(start, end, TEST_TOLERANCE);
double lower = startIsVirtual ? Double.NEGATIVE_INFINITY : (line.toSubSpace(start)).getX();
double upper = startIsVirtual ? (line.toSubSpace(end)).getX() : Double.POSITIVE_INFINITY;
- return new SubLine(line, new IntervalsSet(lower, upper, 1.0e-10));
+ return new SubLine(line, new IntervalsSet(lower, upper, TEST_TOLERANCE));
}
private SubHyperplane<Euclidean2D> buildSegment(Cartesian2D start, Cartesian2D end) {
- Line line = new Line(start, end, 1.0e-10);
+ Line line = new Line(start, end, TEST_TOLERANCE);
double lower = (line.toSubSpace(start)).getX();
double upper = (line.toSubSpace(end)).getX();
- return new SubLine(line, new IntervalsSet(lower, upper, 1.0e-10));
- }
-
- private void checkPointsEqual(Cartesian2D expected, Cartesian2D actual, double tolerance) {
- Assert.assertEquals(expected.getX(), actual.getX(), tolerance);
- Assert.assertEquals(expected.getY(), actual.getY(), tolerance);
+ return new SubLine(line, new IntervalsSet(lower, upper, TEST_TOLERANCE));
}
- private void checkPoints(Region.Location expected, PolygonsSet set,
- Cartesian2D[] points) {
+ private void checkPoints(Region.Location expected, PolygonsSet poly, Cartesian2D ... points) {
for (int i = 0; i < points.length; ++i) {
- Assert.assertEquals(expected, set.checkPoint(points[i]));
+ Assert.assertEquals("Incorrect location for " + points[i], expected, poly.checkPoint(points[i]));
}
}
- private boolean checkInSegment(Cartesian2D p,
- Cartesian2D p1, Cartesian2D p2,
- double tolerance) {
- Line line = new Line(p1, p2, 1.0e-10);
- if (line.getOffset(p) < tolerance) {
- double x = (line.toSubSpace(p)).getX();
- double x1 = (line.toSubSpace(p1)).getX();
- double x2 = (line.toSubSpace(p2)).getX();
- return (((x - x1) * (x - x2) <= 0.0)
- || (p1.distance(p) < tolerance)
- || (p2.distance(p) < tolerance));
- } else {
- return false;
- }
- }
+ /** Asserts that the two arrays of vertex loops have equivalent content.
+ * @param expectedLoops
+ * @param actualLoops
+ */
+ private void checkVertexLoopsEquivalent(Cartesian2D[][] expectedLoops, Cartesian2D[][] actualLoops) {
+ Assert.assertEquals("Expected vertices array to have length of " + expectedLoops.length + " but was " + actualLoops.length,
+ expectedLoops.length, actualLoops.length);
+
+ // go through each loop in the expected array and try to find a match in the actual array
+ for (Cartesian2D[] expectedLoop : expectedLoops) {
+ boolean foundMatch = false;
+ for (Cartesian2D[] actualLoop : actualLoops) {
+ if (vertexLoopsEquivalent(expectedLoop, actualLoop, TEST_TOLERANCE)) {
+ foundMatch = true;
+ break;
+ }
+ }
- private void checkVertices(Cartesian2D[][] rebuiltVertices,
- Cartesian2D[][] vertices) {
-
- // each rebuilt vertex should be in a segment joining two original vertices
- for (int i = 0; i < rebuiltVertices.length; ++i) {
- for (int j = 0; j < rebuiltVertices[i].length; ++j) {
- boolean inSegment = false;
- Cartesian2D p = rebuiltVertices[i][j];
- for (int k = 0; k < vertices.length; ++k) {
- Cartesian2D[] loop = vertices[k];
- int length = loop.length;
- for (int l = 0; (! inSegment) && (l < length); ++l) {
- inSegment = checkInSegment(p, loop[l], loop[(l + 1) % length], 1.0e-10);
- }
+ if (!foundMatch) {
+ StringBuilder sb = new StringBuilder();
+ for (Cartesian2D[] actualLoop : actualLoops) {
+ sb.append(Arrays.toString(actualLoop));
+ sb.append(", ");
}
- Assert.assertTrue(inSegment);
+ if (sb.length() > 0) {
+ sb.delete(sb.length() - 2, sb.length());
+ }
+ Assert.fail("Failed to find vertex loop " + Arrays.toString(expectedLoop) + " in loop array [" +
+ sb.toString() + "].");
}
}
+ }
- // each original vertex should have a corresponding rebuilt vertex
- for (int k = 0; k < vertices.length; ++k) {
- for (int l = 0; l < vertices[k].length; ++l) {
- double min = Double.POSITIVE_INFINITY;
- for (int i = 0; i < rebuiltVertices.length; ++i) {
- for (int j = 0; j < rebuiltVertices[i].length; ++j) {
- min = FastMath.min(vertices[k][l].distance(rebuiltVertices[i][j]),
- min);
+ /** Returns true if the two sets of vertices can be considered equivalent using the given
+ * tolerance. For open loops, (i.e. ones that start with null) this means that the two loops
+ * must have the exact same elements in the exact same order. For closed loops, equivalent
+ * means that one of the loops can be rotated to match the other (e.g. [3, 1, 2] is equivalent
+ * to [1, 2, 3]).
+ * @param a
+ * @param b
+ * @param tolerance
+ * @return
+ */
+ private boolean vertexLoopsEquivalent(Cartesian2D[] a, Cartesian2D[] b, double tolerance) {
+ if (a.length == b.length) {
+ if (a.length < 1) {
+ // the loops are empty
+ return true;
+ }
+ if (a[0] == null || b[0] == null) {
+ // at least one of the loops is unclosed, so there is only one
+ // possible sequence that could match
+ return vertexLoopsEqual(a, 0, b, 0, tolerance);
+ }
+ else {
+ // the loops are closed so they could be equivalent but
+ // start at different vertices
+ for (int i=0; i<a.length; ++i) {
+ if (vertexLoopsEqual(a, 0, b, i, tolerance)) {
+ return true;
}
}
- Assert.assertEquals(0.0, min, 1.0e-10);
}
}
+ return false;
}
+ /** Returns true if the two vertex loops have the same elements, starting
+ * from the given indices and allowing loop-around.
+ * @param a
+ * @param aStartIdx
+ * @param b
+ * @param bStartIdx
+ * @param tolerance
+ * @return
+ */
+ private boolean vertexLoopsEqual(Cartesian2D[] a, int aStartIdx,
+ Cartesian2D[] b, int bStartIdx, double tolerance) {
+
+ int len = a.length;
+
+ Cartesian2D ptA;
+ Cartesian2D ptB;
+ for (int i=0; i<len; ++i) {
+ ptA = a[(i + aStartIdx) % len];
+ ptB = b[(i + bStartIdx) % len];
+
+ if (!((ptA == null && ptB == null) ||
+ (Precision.equals(ptA.getX(), ptB.getX(), tolerance) &&
+ Precision.equals(ptA.getY(), ptB.getY(), tolerance)))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}