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


The following commit(s) were added to refs/heads/master by this push:
     new 78b5c21  GEOMETRY-63: simplifying 
AbstractConvexHyperplaneBoundedRegion.ConvexRegionBoundaryBuilder; adding 
assertions to WelzlEncloser2DTest test method
     new 7c5ff83  Merge branch 'GEOMETRY-63__Matt'
78b5c21 is described below

commit 78b5c21fcda551b032d09a5197d4344fc319a101
Author: Matt Juntunen <matt.juntu...@hotmail.com>
AuthorDate: Mon Feb 3 22:49:56 2020 -0500

    GEOMETRY-63: simplifying 
AbstractConvexHyperplaneBoundedRegion.ConvexRegionBoundaryBuilder; adding 
assertions to WelzlEncloser2DTest test method
---
 .../AbstractConvexHyperplaneBoundedRegion.java     | 121 +++++++++++++--------
 .../AbstractConvexHyperplaneBoundedRegionTest.java |   3 +-
 .../euclidean/twod/WelzlEncloser2DTest.java        |   8 +-
 3 files changed, 82 insertions(+), 50 deletions(-)

diff --git 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegion.java
 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegion.java
index 116c6a0..00fa774 100644
--- 
a/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegion.java
+++ 
b/commons-geometry-core/src/main/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegion.java
@@ -324,65 +324,90 @@ public abstract class 
AbstractConvexHyperplaneBoundedRegion<P extends Point<P>,
 
             final List<S> boundaries = new ArrayList<>();
 
-            // cut each hyperplane by every other hyperplane in order to get 
the subplane boundaries
-            boolean notConvex = false;
-            int outerIdx = 0;
-            ConvexSubHyperplane<P> subhp;
-
-            for (final Hyperplane<P> hp : bounds) {
-                ++outerIdx;
-                subhp = hp.span();
-
-                int innerIdx = 0;
-                for (final Hyperplane<P> splitter : bounds) {
-                    ++innerIdx;
-
-                    if (hp != splitter) {
-                        final Split<? extends ConvexSubHyperplane<P>> split = 
subhp.split(splitter);
-
-                        if (split.getLocation() == SplitLocation.NEITHER) {
-                            if (hp.similarOrientation(splitter)) {
-                                // two or more splitters are the equivalent; 
only
-                                // use the segment from the first one
-                                if (outerIdx > innerIdx) {
-                                    subhp = null;
-                                }
-                            } else {
-                                // two or more splitters are coincident and 
have opposite
-                                // orientations, meaning that no area is on 
the minus side
-                                // of both
-                                notConvex = true;
-                                break;
-                            }
-                        } else {
-                            subhp = subhp.split(splitter).getMinus();
-                        }
+            // cut each hyperplane by every other hyperplane in order to get 
the region boundaries
+            int boundIdx = 0;
+            ConvexSubHyperplane<P> boundary;
 
-                        if (subhp == null) {
-                            break;
-                        }
-                    } else if (outerIdx > innerIdx) {
+            for (final Hyperplane<P> currentBound : bounds) {
+                ++boundIdx;
+
+                boundary = splitBound(currentBound, bounds, boundIdx);
+                if (boundary != null) {
+                    boundaries.add(subhyperplaneType.cast(boundary));
+                }
+            }
+
+            if (boundIdx > 0 && boundaries.isEmpty()) {
+                // nothing was added
+                throw nonConvexException(bounds);
+            }
+
+            return boundaries;
+        }
+
+        /** Split the given bounding hyperplane by all of the other 
hyperplanes in the given collection, returning the
+         * remaining subhyperplane.
+         * @param currentBound the bound to split; this value is assumed to 
have come from {@code bounds}
+         * @param bounds collection of bounds to use to split {@code 
currentBound}
+         * @param currentBoundIdx the index of {@code currentBound} in {@code 
bounds}
+         * @return the part of {@code currentBound}'s subhyperplane that lies 
on the minus side of all of the
+         *      splitting hyperplanes
+         * @throws IllegalArgumentException if the hyperplanes do not form a 
convex region
+         */
+        private ConvexSubHyperplane<P> splitBound(final Hyperplane<P> 
currentBound,
+                final Iterable<? extends Hyperplane<P>> bounds, final int 
currentBoundIdx) {
+
+            ConvexSubHyperplane<P> boundary = currentBound.span();
+
+            int splitterIdx = 0;
+            for (final Hyperplane<P> splitter : bounds) {
+                ++splitterIdx;
+
+                if (currentBound == splitter) {
+                    // do not split the bound with itself
+
+                    if (currentBoundIdx > splitterIdx) {
                         // this hyperplane is duplicated in the list; skip all 
but the
                         // first insertion of its subhyperplane
-                        subhp = null;
-                        break;
+                        return null;
+                    }
+                } else {
+                    // split the subhyperplane
+                    final Split<? extends ConvexSubHyperplane<P>> split = 
boundary.split(splitter);
+
+                    if (split.getLocation() == SplitLocation.NEITHER) {
+                        // the subhyperplane lies directly on the splitter
+
+                        if (!currentBound.similarOrientation(splitter)) {
+                            // two or more splitters are coincident and have 
opposite
+                            // orientations, meaning that no area is on the 
minus side
+                            // of both
+                            throw nonConvexException(bounds);
+                        } else if (currentBoundIdx > splitterIdx) {
+                         // two or more hyperplanes are equivalent; only use 
the boundary
+                            // from the first one and return null for this one
+                            return null;
+                        }
+                    } else {
+                        // retain the minus portion of the split
+                        boundary = split.getMinus();
                     }
                 }
 
-                if (notConvex) {
+                if (boundary == null) {
                     break;
                 }
-
-                if (subhp != null) {
-                    boundaries.add(subhyperplaneType.cast(subhp));
-                }
             }
 
-            if (notConvex || (outerIdx > 0 && boundaries.isEmpty())) {
-                throw new IllegalArgumentException("Bounding hyperplanes do 
not produce a convex region: " + bounds);
-            }
+            return boundary;
+        }
 
-            return boundaries;
+        /** Return an exception indicating that the given collection of 
hyperplanes do not produce a convex region.
+         * @param bounds collection of hyperplanes
+         * @return an exception indicating that the given collection of 
hyperplanes do not produce a convex region
+         */
+        private IllegalArgumentException nonConvexException(final Iterable<? 
extends Hyperplane<P>> bounds) {
+            return new IllegalArgumentException("Bounding hyperplanes do not 
produce a convex region: " + bounds);
         }
     }
 }
diff --git 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
index 7cdfbcd..c67c46f 100644
--- 
a/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
+++ 
b/commons-geometry-core/src/test/java/org/apache/commons/geometry/core/partitioning/AbstractConvexHyperplaneBoundedRegionTest.java
@@ -480,7 +480,8 @@ public class AbstractConvexHyperplaneBoundedRegionTest {
             StubRegion.fromBounds(Arrays.asList(
                     TestLine.X_AXIS,
                     TestLine.Y_AXIS,
-                    new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, 
-1))));
+                    new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, 
-1)),
+                    new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, 
-2))));
         }, IllegalArgumentException.class);
     }
 
diff --git 
a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/euclidean/twod/WelzlEncloser2DTest.java
 
b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/euclidean/twod/WelzlEncloser2DTest.java
index 6fb32b7..4f92579 100755
--- 
a/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/euclidean/twod/WelzlEncloser2DTest.java
+++ 
b/commons-geometry-enclosing/src/test/java/org/apache/commons/geometry/enclosing/euclidean/twod/WelzlEncloser2DTest.java
@@ -24,6 +24,7 @@ import org.apache.commons.geometry.core.GeometryTestUtils;
 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
 import 
org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
 import org.apache.commons.geometry.enclosing.EnclosingBall;
+import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
 import org.apache.commons.geometry.euclidean.twod.Vector2D;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.simple.RandomSource;
@@ -130,7 +131,12 @@ public class WelzlEncloser2DTest {
         WelzlEncloser2D customPrecisionEncloser = new 
WelzlEncloser2D(precisionContext);
 
         // act
-        customPrecisionEncloser.enclose(points);
+        EnclosingBall<Vector2D> result = 
customPrecisionEncloser.enclose(points);
+
+        // assert
+        Assert.assertEquals(27.099954200964234, result.getRadius(), TEST_EPS);
+        
EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(296.0056977503686, 
53.469890753441945),
+                result.getCenter(), TEST_EPS);
     }
 
     private List<Vector2D> buildList(final double... coordinates) {

Reply via email to