You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2015/09/06 20:21:50 UTC
[2/2] [math] Fixed split/side inconsistencies in BSP trees.
Fixed split/side inconsistencies in BSP trees.
JIRA: MATH-1266
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/2091cfba
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/2091cfba
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/2091cfba
Branch: refs/heads/master
Commit: 2091cfbabc4e4940f70c2628cadc08da0baaedc8
Parents: 870d11b
Author: Luc Maisonobe <lu...@apache.org>
Authored: Sun Sep 6 20:17:13 2015 +0200
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Sun Sep 6 20:17:13 2015 +0200
----------------------------------------------------------------------
src/changes/changes.xml | 3 +
.../math4/exception/util/LocalizedFormats.java | 1 +
.../euclidean/oned/SubOrientedPoint.java | 18 ++---
.../geometry/euclidean/threed/SubPlane.java | 50 ++------------
.../math4/geometry/euclidean/twod/SubLine.java | 33 ++-------
.../geometry/partitioning/AbstractRegion.java | 49 ++++++-------
.../partitioning/AbstractSubHyperplane.java | 4 --
.../math4/geometry/partitioning/BSPTree.java | 8 +--
.../geometry/partitioning/Characterization.java | 4 +-
.../geometry/partitioning/InsideFinder.java | 8 +--
.../math4/geometry/partitioning/Region.java | 10 ---
.../geometry/partitioning/RegionFactory.java | 29 ++++++++
.../geometry/partitioning/SubHyperplane.java | 30 +++++---
.../math4/geometry/spherical/oned/ArcsSet.java | 57 +++++++---------
.../geometry/spherical/oned/SubLimitAngle.java | 8 ---
.../geometry/spherical/twod/SubCircle.java | 28 +-------
.../util/LocalizedFormats_fr.properties | 1 +
.../exception/util/LocalizedFormatsTest.java | 2 +-
.../euclidean/twod/PolygonsSetTest.java | 14 +++-
.../geometry/spherical/oned/ArcsSetTest.java | 72 ++++++++++++--------
.../twod/SphericalPolygonsSetTest.java | 22 ++++--
.../geometry/spherical/twod/SubCircleTest.java | 33 ++++++---
22 files changed, 231 insertions(+), 253 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ee4b64c..91f3b24 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible trailing spaces!
</release>
<release version="4.0" date="XXXX-XX-XX" description="">
+ <action dev="luc" type="fix" issue="MATH-1266"> <!-- backported to 3.6 -->
+ Fixed split/side inconsistencies in BSP trees.
+ </action>
<action dev="erans" type="add" issue="MATH-1265"> <!-- backported to 3.6 -->
"NeuronSquareMesh2D" (package "o.a.c.m.ml.neuralnet.twod") implements "Iterable".
</action>
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java b/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java
index 699a0cc..4349e40 100644
--- a/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java
+++ b/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java
@@ -180,6 +180,7 @@ public enum LocalizedFormats implements Localizable {
NUMBER_OF_INTERPOLATION_POINTS("number of interpolation points ({0})"), /* keep */
NUMBER_OF_TRIALS("number of trials ({0})"),
NOT_CONVEX("vertices do not form a convex hull in CCW winding"),
+ NOT_CONVEX_HYPERPLANES("hyperplanes do not define a convex region"),
ROBUSTNESS_ITERATIONS("number of robustness iterations ({0})"),
START_POSITION("start position ({0})"), /* keep */
NON_CONVERGENT_CONTINUED_FRACTION("Continued fraction convergents failed to converge (in less than {0} iterations) for value {1}"),
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
index dc654e9..a80873d 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/SubOrientedPoint.java
@@ -19,7 +19,6 @@ package org.apache.commons.math4.geometry.euclidean.oned;
import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.Side;
/** This class represents sub-hyperplane for {@link OrientedPoint}.
* <p>An hyperplane in 1D is a simple point, its orientation being a
@@ -59,18 +58,15 @@ public class SubOrientedPoint extends AbstractSubHyperplane<Euclidean1D, Euclide
/** {@inheritDoc} */
@Override
- public Side side(final Hyperplane<Euclidean1D> hyperplane) {
- final double global = hyperplane.getOffset(((OrientedPoint) getHyperplane()).getLocation());
- return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
- }
-
- /** {@inheritDoc} */
- @Override
public SplitSubHyperplane<Euclidean1D> split(final Hyperplane<Euclidean1D> hyperplane) {
final double global = hyperplane.getOffset(((OrientedPoint) getHyperplane()).getLocation());
- return (global < -1.0e-10) ?
- new SplitSubHyperplane<Euclidean1D>(null, this) :
- new SplitSubHyperplane<Euclidean1D>(this, null);
+ if (global < -1.0e-10) {
+ return new SplitSubHyperplane<Euclidean1D>(null, this);
+ } else if (global > 1.0e-10) {
+ return new SplitSubHyperplane<Euclidean1D>(this, null);
+ } else {
+ return new SplitSubHyperplane<Euclidean1D>(null, null);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
index 9bab72f..89885d4 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/SubPlane.java
@@ -26,7 +26,6 @@ import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
import org.apache.commons.math4.geometry.partitioning.BSPTree;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.Side;
import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
/** This class represents a sub-hyperplane for {@link Plane}.
@@ -50,45 +49,6 @@ public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Euclidean2D> {
return new SubPlane(hyperplane, remainingRegion);
}
- /** {@inheritDoc} */
- @Override
- public Side side(Hyperplane<Euclidean3D> hyperplane) {
-
- final Plane otherPlane = (Plane) hyperplane;
- final Plane thisPlane = (Plane) getHyperplane();
- final Line inter = otherPlane.intersection(thisPlane);
- final double tolerance = thisPlane.getTolerance();
-
- if (inter == null) {
- // the hyperplanes are parallel,
- // any point can be used to check their relative position
- final double global = otherPlane.getOffset(thisPlane);
- return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
- }
-
- // create a 2D line in the otherPlane canonical 2D frame such that:
- // - the line is the crossing line of the two planes in 3D
- // - the line splits the otherPlane in two half planes with an
- // orientation consistent with the orientation of the instance
- // (i.e. the 3D half space on the plus side (resp. minus side)
- // of the instance contains the 2D half plane on the plus side
- // (resp. minus side) of the 2D line
- Vector2D p = thisPlane.toSubSpace((Point<Euclidean3D>) inter.toSpace((Point<Euclidean1D>) Vector1D.ZERO));
- Vector2D q = thisPlane.toSubSpace((Point<Euclidean3D>) inter.toSpace((Point<Euclidean1D>) Vector1D.ONE));
- Vector3D crossP = Vector3D.crossProduct(inter.getDirection(), thisPlane.getNormal());
- if (crossP.dotProduct(otherPlane.getNormal()) < 0) {
- final Vector2D tmp = p;
- p = q;
- q = tmp;
- }
- final org.apache.commons.math4.geometry.euclidean.twod.Line line2D =
- new org.apache.commons.math4.geometry.euclidean.twod.Line(p, q, tolerance);
-
- // check the side on the 2D plane
- return getRemainingRegion().side(line2D);
-
- }
-
/** Split the instance in two parts by an hyperplane.
* @param hyperplane splitting hyperplane
* @return an object containing both the part of the instance
@@ -106,9 +66,13 @@ public class SubPlane extends AbstractSubHyperplane<Euclidean3D, Euclidean2D> {
if (inter == null) {
// the hyperplanes are parallel
final double global = otherPlane.getOffset(thisPlane);
- return (global < -1.0e-10) ?
- new SplitSubHyperplane<Euclidean3D>(null, this) :
- new SplitSubHyperplane<Euclidean3D>(this, null);
+ if (global < -tolerance) {
+ return new SplitSubHyperplane<Euclidean3D>(null, this);
+ } else if (global > tolerance) {
+ return new SplitSubHyperplane<Euclidean3D>(this, null);
+ } else {
+ return new SplitSubHyperplane<Euclidean3D>(null, null);
+ }
}
// the hyperplanes do intersect
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/SubLine.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/SubLine.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/SubLine.java
index 2976b3f..4f53e6c 100644
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/SubLine.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/SubLine.java
@@ -29,7 +29,6 @@ import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
import org.apache.commons.math4.geometry.partitioning.BSPTree;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.Side;
import org.apache.commons.math4.geometry.partitioning.SubHyperplane;
import org.apache.commons.math4.geometry.partitioning.Region.Location;
import org.apache.commons.math4.util.FastMath;
@@ -158,27 +157,6 @@ public class SubLine extends AbstractSubHyperplane<Euclidean2D, Euclidean1D> {
/** {@inheritDoc} */
@Override
- public Side side(final Hyperplane<Euclidean2D> hyperplane) {
-
- final Line thisLine = (Line) getHyperplane();
- final Line otherLine = (Line) hyperplane;
- final Vector2D crossing = thisLine.intersection(otherLine);
-
- if (crossing == null) {
- // the lines are parallel,
- final double global = otherLine.getOffset(thisLine);
- return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
- }
-
- // the lines do intersect
- final boolean direct = FastMath.sin(thisLine.getAngle() - otherLine.getAngle()) < 0;
- final Vector1D x = thisLine.toSubSpace((Point<Euclidean2D>) crossing);
- return getRemainingRegion().side(new OrientedPoint(x, direct, thisLine.getTolerance()));
-
- }
-
- /** {@inheritDoc} */
- @Override
public SplitSubHyperplane<Euclidean2D> split(final Hyperplane<Euclidean2D> hyperplane) {
final Line thisLine = (Line) getHyperplane();
@@ -189,9 +167,13 @@ public class SubLine extends AbstractSubHyperplane<Euclidean2D, Euclidean1D> {
if (crossing == null) {
// the lines are parallel
final double global = otherLine.getOffset(thisLine);
- return (global < -1.0e-10) ?
- new SplitSubHyperplane<Euclidean2D>(null, this) :
- new SplitSubHyperplane<Euclidean2D>(this, null);
+ if (global < -tolerance) {
+ return new SplitSubHyperplane<Euclidean2D>(null, this);
+ } else if (global > tolerance) {
+ return new SplitSubHyperplane<Euclidean2D>(this, null);
+ } else {
+ return new SplitSubHyperplane<Euclidean2D>(null, null);
+ }
}
// the lines do intersect
@@ -211,7 +193,6 @@ public class SubLine extends AbstractSubHyperplane<Euclidean2D, Euclidean1D> {
new BSPTree<Euclidean1D>(Boolean.FALSE) :
new BSPTree<Euclidean1D>(subMinus, new BSPTree<Euclidean1D>(Boolean.FALSE),
splitTree.getMinus(), null);
-
return new SplitSubHyperplane<Euclidean2D>(new SubLine(thisLine.copySelf(), new IntervalsSet(plusTree, tolerance)),
new SubLine(thisLine.copySelf(), new IntervalsSet(minusTree, tolerance)));
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractRegion.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractRegion.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractRegion.java
index f75c0b3..1df1fcf 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractRegion.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractRegion.java
@@ -221,7 +221,8 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
final ArrayList<SubHyperplane<S>> minusList = new ArrayList<SubHyperplane<S>>();
while (iterator.hasNext()) {
final SubHyperplane<S> other = iterator.next();
- switch (other.side(inserted)) {
+ final SubHyperplane.SplitSubHyperplane<S> split = other.split(inserted);
+ switch (split.getSide()) {
case PLUS:
plusList.add(other);
break;
@@ -229,7 +230,6 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
minusList.add(other);
break;
case BOTH:
- final SubHyperplane.SplitSubHyperplane<S> split = other.split(inserted);
plusList.add(split.getPlus());
minusList.add(split.getMinus());
break;
@@ -426,16 +426,6 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
/** {@inheritDoc} */
@Override
- public Side side(final Hyperplane<S> hyperplane) {
- final InsideFinder<S> finder = new InsideFinder<S>(this);
- finder.recurseSides(tree, hyperplane.wholeHyperplane());
- return finder.plusFound() ?
- (finder.minusFound() ? Side.BOTH : Side.PLUS) :
- (finder.minusFound() ? Side.MINUS : Side.HYPER);
- }
-
- /** {@inheritDoc} */
- @Override
public SubHyperplane<S> intersection(final SubHyperplane<S> sub) {
return recurseIntersection(tree, sub);
}
@@ -453,23 +443,28 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
}
final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
- switch (sub.side(hyperplane)) {
- case PLUS :
- return recurseIntersection(node.getPlus(), sub);
- case MINUS :
- return recurseIntersection(node.getMinus(), sub);
- case BOTH :
- final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
- final SubHyperplane<S> plus = recurseIntersection(node.getPlus(), split.getPlus());
- final SubHyperplane<S> minus = recurseIntersection(node.getMinus(), split.getMinus());
- if (plus == null) {
- return minus;
- } else if (minus == null) {
- return plus;
+ final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
+ if (split.getPlus() != null) {
+ if (split.getMinus() != null) {
+ // both sides
+ final SubHyperplane<S> plus = recurseIntersection(node.getPlus(), split.getPlus());
+ final SubHyperplane<S> minus = recurseIntersection(node.getMinus(), split.getMinus());
+ if (plus == null) {
+ return minus;
+ } else if (minus == null) {
+ return plus;
+ } else {
+ return plus.reunite(minus);
+ }
} else {
- return plus.reunite(minus);
+ // only on plus side
+ return recurseIntersection(node.getPlus(), sub);
}
- default :
+ } else if (split.getMinus() != null) {
+ // only on minus side
+ return recurseIntersection(node.getMinus(), sub);
+ } else {
+ // on hyperplane
return recurseIntersection(node.getPlus(),
recurseIntersection(node.getMinus(), sub));
}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractSubHyperplane.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractSubHyperplane.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractSubHyperplane.java
index f75998c..76c925c 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractSubHyperplane.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/AbstractSubHyperplane.java
@@ -180,10 +180,6 @@ public abstract class AbstractSubHyperplane<S extends Space, T extends Space>
/** {@inheritDoc} */
@Override
- public abstract Side side(Hyperplane<S> hyper);
-
- /** {@inheritDoc} */
- @Override
public abstract SplitSubHyperplane<S> split(Hyperplane<S> hyper);
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/BSPTree.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/BSPTree.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/BSPTree.java
index 3be5b08..5a4f18e 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/BSPTree.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/BSPTree.java
@@ -558,11 +558,12 @@ public class BSPTree<S extends Space> {
final Hyperplane<S> cHyperplane = cut.getHyperplane();
final Hyperplane<S> sHyperplane = sub.getHyperplane();
- switch (sub.side(cHyperplane)) {
+ final SubHyperplane.SplitSubHyperplane<S> subParts = sub.split(cHyperplane);
+ switch (subParts.getSide()) {
case PLUS :
{ // the partitioning sub-hyperplane is entirely in the plus sub-tree
final BSPTree<S> split = plus.split(sub);
- if (cut.side(sHyperplane) == Side.PLUS) {
+ if (cut.split(sHyperplane).getSide() == Side.PLUS) {
split.plus =
new BSPTree<S>(cut.copySelf(), split.plus, minus.copySelf(), attribute);
split.plus.condense();
@@ -578,7 +579,7 @@ public class BSPTree<S extends Space> {
case MINUS :
{ // the partitioning sub-hyperplane is entirely in the minus sub-tree
final BSPTree<S> split = minus.split(sub);
- if (cut.side(sHyperplane) == Side.PLUS) {
+ if (cut.split(sHyperplane).getSide() == Side.PLUS) {
split.plus =
new BSPTree<S>(cut.copySelf(), plus.copySelf(), split.plus, attribute);
split.plus.condense();
@@ -594,7 +595,6 @@ public class BSPTree<S extends Space> {
case BOTH :
{
final SubHyperplane.SplitSubHyperplane<S> cutParts = cut.split(sHyperplane);
- final SubHyperplane.SplitSubHyperplane<S> subParts = sub.split(cHyperplane);
final BSPTree<S> split =
new BSPTree<S>(sub, plus.split(subParts.getPlus()), minus.split(subParts.getMinus()),
null);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/Characterization.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/Characterization.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/Characterization.java
index e1caf17..fb5256d 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/Characterization.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/Characterization.java
@@ -86,7 +86,8 @@ class Characterization<S extends Space> {
}
} else {
final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
- switch (sub.side(hyperplane)) {
+ final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
+ switch (split.getSide()) {
case PLUS:
characterize(node.getPlus(), sub, splitters);
break;
@@ -94,7 +95,6 @@ class Characterization<S extends Space> {
characterize(node.getMinus(), sub, splitters);
break;
case BOTH:
- final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
splitters.add(node);
characterize(node.getPlus(), split.getPlus(), splitters);
characterize(node.getMinus(), split.getMinus(), splitters);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/InsideFinder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/InsideFinder.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/InsideFinder.java
index 14bd142..da72e6d 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/InsideFinder.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/InsideFinder.java
@@ -69,10 +69,11 @@ class InsideFinder<S extends Space> {
}
final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
- switch (sub.side(hyperplane)) {
+ final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
+ switch (split.getSide()) {
case PLUS :
// the sub-hyperplane is entirely in the plus sub-tree
- if (node.getCut().side(sub.getHyperplane()) == Side.PLUS) {
+ if (node.getCut().split(sub.getHyperplane()).getSide() == Side.PLUS) {
if (!region.isEmpty(node.getMinus())) {
plusFound = true;
}
@@ -87,7 +88,7 @@ class InsideFinder<S extends Space> {
break;
case MINUS :
// the sub-hyperplane is entirely in the minus sub-tree
- if (node.getCut().side(sub.getHyperplane()) == Side.PLUS) {
+ if (node.getCut().split(sub.getHyperplane()).getSide() == Side.PLUS) {
if (!region.isEmpty(node.getPlus())) {
plusFound = true;
}
@@ -102,7 +103,6 @@ class InsideFinder<S extends Space> {
break;
case BOTH :
// the sub-hyperplane extends in both sub-trees
- final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
// explore first the plus sub-tree
recurseSides(node.getPlus(), split.getPlus());
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/Region.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/Region.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/Region.java
index 80c80b8..404d15d 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/Region.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/Region.java
@@ -197,16 +197,6 @@ public interface Region<S extends Space> {
*/
Point<S> getBarycenter();
- /** Compute the relative position of the instance with respect to an
- * hyperplane.
- * @param hyperplane reference hyperplane
- * @return one of {@link Side#PLUS Side.PLUS}, {@link Side#MINUS
- * Side.MINUS}, {@link Side#BOTH Side.BOTH} or {@link Side#HYPER
- * Side.HYPER} (the latter result can occur only if the tree
- * contains only one cut hyperplane)
- */
- Side side(final Hyperplane<S> hyperplane);
-
/** Get the parts of a sub-hyperplane that are contained in the region.
* <p>The parts of the sub-hyperplane that belong to the boundary are
* <em>not</em> included in the resulting parts.</p>
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/RegionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/RegionFactory.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/RegionFactory.java
index 9e32c99..bcae157 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/RegionFactory.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/RegionFactory.java
@@ -19,10 +19,13 @@ package org.apache.commons.math4.geometry.partitioning;
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.math4.exception.MathIllegalArgumentException;
+import org.apache.commons.math4.exception.util.LocalizedFormats;
import org.apache.commons.math4.geometry.Point;
import org.apache.commons.math4.geometry.Space;
import org.apache.commons.math4.geometry.partitioning.BSPTree.VanishingCutHandler;
import org.apache.commons.math4.geometry.partitioning.Region.Location;
+import org.apache.commons.math4.geometry.partitioning.SubHyperplane.SplitSubHyperplane;
/** This class is a factory for {@link Region}.
@@ -63,6 +66,32 @@ public class RegionFactory<S extends Space> {
node.getPlus().setAttribute(Boolean.FALSE);
node = node.getMinus();
node.setAttribute(Boolean.TRUE);
+ } else {
+ // the hyperplane could not be inserted in the current leaf node
+ // either it is completely outside (which means the input hyperplanes
+ // are wrong), or it is parallel to a previous hyperplane
+ SubHyperplane<S> s = hyperplane.wholeHyperplane();
+ for (BSPTree<S> tree = node; tree.getParent() != null && s != null; tree = tree.getParent()) {
+ final Hyperplane<S> other = tree.getParent().getCut().getHyperplane();
+ final SplitSubHyperplane<S> split = s.split(other);
+ switch (split.getSide()) {
+ case HYPER :
+ // the hyperplane is parallel to a previous hyperplane
+ if (!hyperplane.sameOrientationAs(other)) {
+ // this hyperplane is opposite to the other one,
+ // the region is thinner than the tolerance, we consider it empty
+ return getComplement(hyperplanes[0].wholeSpace());
+ }
+ // the hyperplane is an extension of an already known hyperplane, we just ignore it
+ break;
+ case PLUS :
+ // the hyperplane is outside of the current convex zone,
+ // the input hyperplanes are inconsistent
+ throw new MathIllegalArgumentException(LocalizedFormats.NOT_CONVEX_HYPERPLANES);
+ default :
+ s = split.getMinus();
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/partitioning/SubHyperplane.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/partitioning/SubHyperplane.java b/src/main/java/org/apache/commons/math4/geometry/partitioning/SubHyperplane.java
index 33afd20..03a766e 100644
--- a/src/main/java/org/apache/commons/math4/geometry/partitioning/SubHyperplane.java
+++ b/src/main/java/org/apache/commons/math4/geometry/partitioning/SubHyperplane.java
@@ -66,14 +66,6 @@ public interface SubHyperplane<S extends Space> {
*/
double getSize();
- /** Compute the relative position of the instance with respect
- * to an hyperplane.
- * @param hyperplane hyperplane to check instance against
- * @return one of {@link Side#PLUS}, {@link Side#MINUS}, {@link Side#BOTH},
- * {@link Side#HYPER}
- */
- Side side(Hyperplane<S> hyperplane);
-
/** Split the instance in two parts by an hyperplane.
* @param hyperplane splitting hyperplane
* @return an object containing both the part of the instance
@@ -126,6 +118,28 @@ public interface SubHyperplane<S extends Space> {
return minus;
}
+ /** Get the side of the split sub-hyperplane with respect to its splitter.
+ * @return {@link Side#PLUS} if only {@link #getPlus()} is neither null nor empty,
+ * {@link Side#MINUS} if only {@link #getMinus()} is neither null nor empty,
+ * {@link Side#BOTH} if both {@link #getPlus()} and {@link #getMinus()}
+ * are neither null nor empty or {@link Side#HYPER} if both {@link #getPlus()} and
+ * {@link #getMinus()} are either null or empty
+ * @since 3.6
+ */
+ public Side getSide() {
+ if (plus != null && !plus.isEmpty()) {
+ if (minus != null && !minus.isEmpty()) {
+ return Side.BOTH;
+ } else {
+ return Side.PLUS;
+ }
+ } else if (minus != null && !minus.isEmpty()) {
+ return Side.MINUS;
+ } else {
+ return Side.HYPER;
+ }
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSet.java b/src/main/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSet.java
index bd195c0..c5f772b 100644
--- a/src/main/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSet.java
+++ b/src/main/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSet.java
@@ -709,40 +709,11 @@ public class ArcsSet extends AbstractRegion<Sphere1D, Sphere1D> implements Itera
* @param arc arc to check instance against
* @return one of {@link Side#PLUS}, {@link Side#MINUS}, {@link Side#BOTH}
* or {@link Side#HYPER}
+ * @deprecated as of 3.6, replaced with {@link #split(Arc)}.{@link Split#getSide()}
*/
+ @Deprecated
public Side side(final Arc arc) {
-
- final double reference = FastMath.PI + arc.getInf();
- final double arcLength = arc.getSup() - arc.getInf();
-
- boolean inMinus = false;
- boolean inPlus = false;
- for (final double[] a : this) {
- final double syncedStart = MathUtils.normalizeAngle(a[0], reference) - arc.getInf();
- final double arcOffset = a[0] - syncedStart;
- final double syncedEnd = a[1] - arcOffset;
- if (syncedStart <= arcLength - getTolerance() || syncedEnd >= MathUtils.TWO_PI + getTolerance()) {
- inMinus = true;
- }
- if (syncedEnd >= arcLength + getTolerance()) {
- inPlus = true;
- }
- }
-
- if (inMinus) {
- if (inPlus) {
- return Side.BOTH;
- } else {
- return Side.MINUS;
- }
- } else {
- if (inPlus) {
- return Side.PLUS;
- } else {
- return Side.HYPER;
- }
- }
-
+ return split(arc).getSide();
}
/** Split the instance in two parts by an arc.
@@ -941,6 +912,28 @@ public class ArcsSet extends AbstractRegion<Sphere1D, Sphere1D> implements Itera
return minus;
}
+ /** Get the side of the split arc with respect to its splitter.
+ * @return {@link Side#PLUS} if only {@link #getPlus()} returns non-null,
+ * {@link Side#MINUS} if only {@link #getMinus()} returns non-null,
+ * {@link Side#BOTH} if both {@link #getPlus()} and {@link #getMinus()}
+ * return non-null or {@link Side#HYPER} if both {@link #getPlus()} and
+ * {@link #getMinus()} return null
+ * @since 3.6
+ */
+ public Side getSide() {
+ if (plus != null) {
+ if (minus != null) {
+ return Side.BOTH;
+ } else {
+ return Side.PLUS;
+ }
+ } else if (minus != null) {
+ return Side.MINUS;
+ } else {
+ return Side.HYPER;
+ }
+ }
+
}
/** Specialized exception for inconsistent BSP tree state inconsistency.
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/spherical/oned/SubLimitAngle.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/spherical/oned/SubLimitAngle.java b/src/main/java/org/apache/commons/math4/geometry/spherical/oned/SubLimitAngle.java
index e90ad8b..31f79fd 100644
--- a/src/main/java/org/apache/commons/math4/geometry/spherical/oned/SubLimitAngle.java
+++ b/src/main/java/org/apache/commons/math4/geometry/spherical/oned/SubLimitAngle.java
@@ -19,7 +19,6 @@ package org.apache.commons.math4.geometry.spherical.oned;
import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.Side;
/** This class represents sub-hyperplane for {@link LimitAngle}.
* <p>Instances of this class are guaranteed to be immutable.</p>
@@ -57,13 +56,6 @@ public class SubLimitAngle extends AbstractSubHyperplane<Sphere1D, Sphere1D> {
/** {@inheritDoc} */
@Override
- public Side side(final Hyperplane<Sphere1D> hyperplane) {
- final double global = hyperplane.getOffset(((LimitAngle) getHyperplane()).getLocation());
- return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
- }
-
- /** {@inheritDoc} */
- @Override
public SplitSubHyperplane<Sphere1D> split(final Hyperplane<Sphere1D> hyperplane) {
final double global = hyperplane.getOffset(((LimitAngle) getHyperplane()).getLocation());
return (global < -1.0e-10) ?
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/java/org/apache/commons/math4/geometry/spherical/twod/SubCircle.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/geometry/spherical/twod/SubCircle.java b/src/main/java/org/apache/commons/math4/geometry/spherical/twod/SubCircle.java
index afa5005..837c953 100644
--- a/src/main/java/org/apache/commons/math4/geometry/spherical/twod/SubCircle.java
+++ b/src/main/java/org/apache/commons/math4/geometry/spherical/twod/SubCircle.java
@@ -20,7 +20,6 @@ import org.apache.commons.math4.geometry.euclidean.threed.Vector3D;
import org.apache.commons.math4.geometry.partitioning.AbstractSubHyperplane;
import org.apache.commons.math4.geometry.partitioning.Hyperplane;
import org.apache.commons.math4.geometry.partitioning.Region;
-import org.apache.commons.math4.geometry.partitioning.Side;
import org.apache.commons.math4.geometry.spherical.oned.Arc;
import org.apache.commons.math4.geometry.spherical.oned.ArcsSet;
import org.apache.commons.math4.geometry.spherical.oned.Sphere1D;
@@ -49,36 +48,15 @@ public class SubCircle extends AbstractSubHyperplane<Sphere2D, Sphere1D> {
/** {@inheritDoc} */
@Override
- public Side side(final Hyperplane<Sphere2D> hyperplane) {
-
- final Circle thisCircle = (Circle) getHyperplane();
- final Circle otherCircle = (Circle) hyperplane;
- final double angle = Vector3D.angle(thisCircle.getPole(), otherCircle.getPole());
-
- if (angle < thisCircle.getTolerance() || angle > FastMath.PI - thisCircle.getTolerance()) {
- // the two circles are aligned or opposite
- return Side.HYPER;
- } else {
- // the two circles intersect each other
- return ((ArcsSet) getRemainingRegion()).side(thisCircle.getInsideArc(otherCircle));
- }
-
- }
-
- /** {@inheritDoc} */
- @Override
public SplitSubHyperplane<Sphere2D> split(final Hyperplane<Sphere2D> hyperplane) {
final Circle thisCircle = (Circle) getHyperplane();
final Circle otherCircle = (Circle) hyperplane;
final double angle = Vector3D.angle(thisCircle.getPole(), otherCircle.getPole());
- if (angle < thisCircle.getTolerance()) {
- // the two circles are aligned
- return new SplitSubHyperplane<Sphere2D>(null, this);
- } else if (angle > FastMath.PI - thisCircle.getTolerance()) {
- // the two circles are opposite
- return new SplitSubHyperplane<Sphere2D>(this, null);
+ if (angle < thisCircle.getTolerance() || angle > FastMath.PI - thisCircle.getTolerance()) {
+ // the two circles are aligned or opposite
+ return new SplitSubHyperplane<Sphere2D>(null, null);
} else {
// the two circles intersect each other
final Arc arc = thisCircle.getInsideArc(otherCircle);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties b/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties
index eba92a0..cbbec08 100644
--- a/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties
+++ b/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties
@@ -167,6 +167,7 @@ NORMALIZE_INFINITE = impossible de normaliser vers une valeur infinie
NORMALIZE_NAN = impossible de normaliser vers NaN
NOT_ADDITION_COMPATIBLE_MATRICES = les dimensions {0}x{1} et {2}x{3} sont incompatibles pour l''addition matricielle
NOT_CONVEX = les points ne constituent pas une enveloppe convexe
+NOT_CONVEX_HYPERPLANES = les hyperplans ne d\u00e9finissent pas une r\u00e9gion convexe
NOT_DECREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas d\u00e9croissants ({2} < {3})
NOT_DECREASING_SEQUENCE = les points {3} et {2} ne sont pas d\u00e9croissants ({1} < {0})
NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS = pas assez de donn\u00e9es ({0} lignes) pour {1} pr\u00e9dicteurs
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java b/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java
index 6912f5f..4d1dcbf 100644
--- a/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java
+++ b/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java
@@ -29,7 +29,7 @@ public class LocalizedFormatsTest {
@Test
public void testMessageNumber() {
- Assert.assertEquals(326, LocalizedFormats.values().length);
+ Assert.assertEquals(327, LocalizedFormats.values().length);
}
@Test
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/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 a444273..34f10c2 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
@@ -19,6 +19,7 @@ package org.apache.commons.math4.geometry.euclidean.twod;
import java.util.ArrayList;
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.euclidean.oned.Vector1D;
@@ -1153,12 +1154,19 @@ public class PolygonsSetTest {
new Line(pD, pA, 1.0 / 16)
};
Region<Euclidean2D> degeneratedPolygon = factory.buildConvex(h2);
- Assert.assertEquals(1.0 / 64.0, degeneratedPolygon.getSize(), 1.0e-10);
- Assert.assertTrue(Double.isInfinite(new RegionFactory<Euclidean2D>().getComplement(degeneratedPolygon).getSize()));
- Assert.assertEquals(2 * (1.0 + 1.0 / 64.0), degeneratedPolygon.getBoundarySize(), 1.0e-10);
+ Assert.assertEquals(0.0, degeneratedPolygon.getSize(), 1.0e-10);
+ Assert.assertTrue(degeneratedPolygon.isEmpty());
}
+ @SuppressWarnings("unchecked")
+ @Test(expected=MathIllegalArgumentException.class)
+ public void testInconsistentHyperplanes() {
+ double tolerance = 1.0e-10;
+ new RegionFactory<Euclidean2D>().buildConvex(new Line(new Vector2D(0, 0), new Vector2D(0, 1), tolerance),
+ new Line(new Vector2D(1, 1), new Vector2D(1, 0), tolerance));
+ }
+
@Test
public void testBoundarySimplification() {
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/test/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSetTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSetTest.java b/src/test/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSetTest.java
index 1eaa73c..e57286b 100644
--- a/src/test/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSetTest.java
+++ b/src/test/java/org/apache/commons/math4/geometry/spherical/oned/ArcsSetTest.java
@@ -389,27 +389,27 @@ public class ArcsSetTest {
ArcsSet set = (ArcsSet) new RegionFactory<Sphere1D>().difference(new ArcsSet(1.0, 6.0, 1.0e-10),
new ArcsSet(3.0, 5.0, 1.0e-10));
for (int k = -2; k < 3; ++k) {
- Assert.assertEquals(Side.MINUS, set.side(new Arc(0.5 + k * MathUtils.TWO_PI,
- 6.1 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.PLUS, set.side(new Arc(0.5 + k * MathUtils.TWO_PI,
- 0.8 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.PLUS, set.side(new Arc(6.2 + k * MathUtils.TWO_PI,
- 6.3 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.PLUS, set.side(new Arc(3.5 + k * MathUtils.TWO_PI,
- 4.5 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.BOTH, set.side(new Arc(2.9 + k * MathUtils.TWO_PI,
- 4.5 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.BOTH, set.side(new Arc(0.5 + k * MathUtils.TWO_PI,
- 1.2 + k * MathUtils.TWO_PI,
- set.getTolerance())));
- Assert.assertEquals(Side.BOTH, set.side(new Arc(0.5 + k * MathUtils.TWO_PI,
- 5.9 + k * MathUtils.TWO_PI,
- set.getTolerance())));
+ Assert.assertEquals(Side.MINUS, set.split(new Arc(0.5 + k * MathUtils.TWO_PI,
+ 6.1 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.PLUS, set.split(new Arc(0.5 + k * MathUtils.TWO_PI,
+ 0.8 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.PLUS, set.split(new Arc(6.2 + k * MathUtils.TWO_PI,
+ 6.3 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.PLUS, set.split(new Arc(3.5 + k * MathUtils.TWO_PI,
+ 4.5 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.BOTH, set.split(new Arc(2.9 + k * MathUtils.TWO_PI,
+ 4.5 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.BOTH, set.split(new Arc(0.5 + k * MathUtils.TWO_PI,
+ 1.2 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
+ Assert.assertEquals(Side.BOTH, set.split(new Arc(0.5 + k * MathUtils.TWO_PI,
+ 5.9 + k * MathUtils.TWO_PI,
+ set.getTolerance())).getSide());
}
}
@@ -419,10 +419,10 @@ public class ArcsSetTest {
ArcsSet s35 = new ArcsSet(3.0, 5.0, 1.0e-10);
ArcsSet s16 = new ArcsSet(1.0, 6.0, 1.0e-10);
- Assert.assertEquals(Side.BOTH, s16.side(new Arc(3.0, 5.0, 1.0e-10)));
- Assert.assertEquals(Side.BOTH, s16.side(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10)));
- Assert.assertEquals(Side.MINUS, s35.side(new Arc(1.0, 6.0, 1.0e-10)));
- Assert.assertEquals(Side.PLUS, s35.side(new Arc(6.0, 1.0 + MathUtils.TWO_PI, 1.0e-10)));
+ Assert.assertEquals(Side.BOTH, s16.split(new Arc(3.0, 5.0, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.BOTH, s16.split(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.MINUS, s35.split(new Arc(1.0, 6.0, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.PLUS, s35.split(new Arc(6.0, 1.0 + MathUtils.TWO_PI, 1.0e-10)).getSide());
}
@@ -431,17 +431,17 @@ public class ArcsSetTest {
ArcsSet s35 = new ArcsSet(3.0, 5.0, 1.0e-10);
ArcsSet s46 = new ArcsSet(4.0, 6.0, 1.0e-10);
- Assert.assertEquals(Side.BOTH, s46.side(new Arc(3.0, 5.0, 1.0e-10)));
- Assert.assertEquals(Side.BOTH, s46.side(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10)));
- Assert.assertEquals(Side.BOTH, s35.side(new Arc(4.0, 6.0, 1.0e-10)));
- Assert.assertEquals(Side.BOTH, s35.side(new Arc(6.0, 4.0 + MathUtils.TWO_PI, 1.0e-10)));
+ Assert.assertEquals(Side.BOTH, s46.split(new Arc(3.0, 5.0, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.BOTH, s46.split(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.BOTH, s35.split(new Arc(4.0, 6.0, 1.0e-10)).getSide());
+ Assert.assertEquals(Side.BOTH, s35.split(new Arc(6.0, 4.0 + MathUtils.TWO_PI, 1.0e-10)).getSide());
}
@Test
public void testSideHyper() {
ArcsSet sub = (ArcsSet) new RegionFactory<Sphere1D>().getComplement(new ArcsSet(1.0e-10));
Assert.assertTrue(sub.isEmpty());
- Assert.assertEquals(Side.HYPER, sub.side(new Arc(2.0, 3.0, 1.0e-10)));
+ Assert.assertEquals(Side.HYPER, sub.split(new Arc(2.0, 3.0, 1.0e-10)).getSide());
}
@Test
@@ -583,4 +583,16 @@ public class ArcsSetTest {
Assert.assertNull(split.getMinus());
}
+ @Test
+ public void testSideSplitConsistency() {
+ double epsilon = 1.0e-6;
+ double a = 4.725;
+ ArcsSet set = new ArcsSet(a, a + 0.5, epsilon);
+ Arc arc = new Arc(a + 0.5 * epsilon, a + 1, epsilon);
+ ArcsSet.Split split = set.split(arc);
+ Assert.assertNotNull(split.getMinus());
+ Assert.assertNull(split.getPlus());
+ Assert.assertEquals(Side.MINUS, set.split(arc).getSide());
+ }
+
}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SphericalPolygonsSetTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SphericalPolygonsSetTest.java b/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SphericalPolygonsSetTest.java
index e2359a3..e9fbe47 100644
--- a/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SphericalPolygonsSetTest.java
+++ b/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SphericalPolygonsSetTest.java
@@ -228,17 +228,23 @@ public class SphericalPolygonsSetTest {
boolean zVFound = false;
Vertex first = loops.get(0);
int count = 0;
+ double sumPoleX = 0;
+ double sumPoleY = 0;
+ double sumPoleZ = 0;
for (Vertex v = first; count == 0 || v != first; v = v.getOutgoing().getEnd()) {
++count;
Edge e = v.getIncoming();
Assert.assertTrue(v == e.getStart().getOutgoing().getEnd());
- xPFound = xPFound || e.getCircle().getPole().distance(Vector3D.MINUS_I) < 1.0e-10;
- yPFound = yPFound || e.getCircle().getPole().distance(Vector3D.MINUS_J) < 1.0e-10;
- zPFound = zPFound || e.getCircle().getPole().distance(Vector3D.PLUS_K) < 1.0e-10;
- if (Vector3D.PLUS_K.distance(e.getCircle().getPole()) < 1.0e-10) {
- Assert.assertEquals(1.5 * FastMath.PI, e.getLength(), 1.0e-10);
+ if (e.getCircle().getPole().distance(Vector3D.MINUS_I) < 1.0e-10) {
+ xPFound = true;
+ sumPoleX += e.getLength();
+ } else if (e.getCircle().getPole().distance(Vector3D.MINUS_J) < 1.0e-10) {
+ yPFound = true;
+ sumPoleY += e.getLength();
} else {
- Assert.assertEquals(0.5 * FastMath.PI, e.getLength(), 1.0e-10);
+ Assert.assertEquals(0.0, e.getCircle().getPole().distance(Vector3D.PLUS_K), 1.0e-10);
+ zPFound = true;
+ sumPoleZ += e.getLength();
}
xVFound = xVFound || v.getLocation().getVector().distance(Vector3D.PLUS_I) < 1.0e-10;
yVFound = yVFound || v.getLocation().getVector().distance(Vector3D.PLUS_J) < 1.0e-10;
@@ -250,7 +256,9 @@ public class SphericalPolygonsSetTest {
Assert.assertTrue(xVFound);
Assert.assertTrue(yVFound);
Assert.assertTrue(zVFound);
- Assert.assertEquals(3, count);
+ Assert.assertEquals(0.5 * FastMath.PI, sumPoleX, 1.0e-10);
+ Assert.assertEquals(0.5 * FastMath.PI, sumPoleY, 1.0e-10);
+ Assert.assertEquals(1.5 * FastMath.PI, sumPoleZ, 1.0e-10);
Assert.assertEquals(1.5 * FastMath.PI, threeOctants.getSize(), 1.0e-10);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2091cfba/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SubCircleTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SubCircleTest.java b/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SubCircleTest.java
index 743cdbc..891f620 100644
--- a/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SubCircleTest.java
+++ b/src/test/java/org/apache/commons/math4/geometry/spherical/twod/SubCircleTest.java
@@ -47,19 +47,19 @@ public class SubCircleTest {
Circle xzPlane = new Circle(Vector3D.PLUS_J, 1.0e-10);
SubCircle sc1 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 1.0, 3.0, 5.0, 6.0);
- Assert.assertEquals(Side.BOTH, sc1.side(xzPlane));
+ Assert.assertEquals(Side.BOTH, sc1.split(xzPlane).getSide());
SubCircle sc2 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 1.0, 3.0);
- Assert.assertEquals(Side.MINUS, sc2.side(xzPlane));
+ Assert.assertEquals(Side.MINUS, sc2.split(xzPlane).getSide());
SubCircle sc3 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 5.0, 6.0);
- Assert.assertEquals(Side.PLUS, sc3.side(xzPlane));
+ Assert.assertEquals(Side.PLUS, sc3.split(xzPlane).getSide());
SubCircle sc4 = create(Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I, 1.0e-10, 5.0, 6.0);
- Assert.assertEquals(Side.HYPER, sc4.side(xzPlane));
+ Assert.assertEquals(Side.HYPER, sc4.split(xzPlane).getSide());
SubCircle sc5 = create(Vector3D.MINUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K, 1.0e-10, 5.0, 6.0);
- Assert.assertEquals(Side.HYPER, sc5.side(xzPlane));
+ Assert.assertEquals(Side.HYPER, sc5.split(xzPlane).getSide());
}
@@ -97,17 +97,34 @@ public class SubCircleTest {
SubCircle sc4 = create(Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I, 1.0e-10, 5.0, 6.0);
SplitSubHyperplane<Sphere2D> split4 = sc4.split(xzPlane);
- Assert.assertEquals(Side.HYPER, sc4.side(xzPlane));
+ Assert.assertEquals(Side.HYPER, sc4.split(xzPlane).getSide());
Assert.assertNull(split4.getPlus());
- Assert.assertTrue(split4.getMinus() == sc4);
+ Assert.assertNull(split4.getMinus());
SubCircle sc5 = create(Vector3D.MINUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K, 1.0e-10, 5.0, 6.0);
SplitSubHyperplane<Sphere2D> split5 = sc5.split(xzPlane);
- Assert.assertTrue(split5.getPlus() == sc5);
+ Assert.assertEquals(Side.HYPER, sc5.split(xzPlane).getSide());
+ Assert.assertNull(split5.getPlus());
Assert.assertNull(split5.getMinus());
}
+ @Test
+ public void testSideSplitConsistency() {
+
+ double tolerance = 1.0e-6;
+ Circle hyperplane = new Circle(new Vector3D(9.738804529764676E-5, -0.6772824575010357, -0.7357230887208355),
+ tolerance);
+ SubCircle sub = new SubCircle(new Circle(new Vector3D(2.1793884139073498E-4, 0.9790647032675541, -0.20354915700704285),
+ tolerance),
+ new ArcsSet(4.7121441684170700, 4.7125386635004760, tolerance));
+ SplitSubHyperplane<Sphere2D> split = sub.split(hyperplane);
+ Assert.assertNotNull(split.getMinus());
+ Assert.assertNull(split.getPlus());
+ Assert.assertEquals(Side.MINUS, sub.split(hyperplane).getSide());
+
+ }
+
private SubCircle create(Vector3D pole, Vector3D x, Vector3D y,
double tolerance, double ... limits) {
RegionFactory<Sphere1D> factory = new RegionFactory<Sphere1D>();