commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r1556880 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/exception/util/ main/java/org/apache/commons/math3/geometry/spherical/oned/ main/java/org/apache/commons/math3/geometry/spherical/twod/ main/resources/assets/o...
Date Thu, 09 Jan 2014 17:08:00 GMT
Author: luc
Date: Thu Jan  9 17:08:00 2014
New Revision: 1556880

URL: http://svn.apache.org/r1556880
Log:
Improved robustness of 1-sphere regions (ArcsSet) at 0/2\pi crossing.

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SphericalPolygonsSet.java
    commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/exception/util/LocalizedFormats.java
Thu Jan  9 17:08:00 2014
@@ -115,6 +115,7 @@ public enum LocalizedFormats implements 
     GCD_OVERFLOW_64_BITS("overflow: gcd({0}, {1}) is 2^63"),
     HOLE_BETWEEN_MODELS_TIME_RANGES("{0} wide hole between models time ranges"),
     ILL_CONDITIONED_OPERATOR("condition number {1} is too high "),
+    INCONSISTENT_STATE_AT_2_PI_WRAPPING("inconsistent state at 2\u03c0 wrapping"),
     INDEX_LARGER_THAN_MAX("the index specified: {0} is larger than the current maximal index
{1}"),
     INDEX_NOT_POSITIVE("index ({0}) is not positive"),
     INDEX_OUT_OF_RANGE("index {0} out of allowed range [{1}, {2}]"),

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java
Thu Jan  9 17:08:00 2014
@@ -22,6 +22,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 
+import org.apache.commons.math3.exception.MathIllegalArgumentException;
 import org.apache.commons.math3.exception.MathInternalError;
 import org.apache.commons.math3.exception.NumberIsTooLargeException;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
@@ -80,9 +81,13 @@ public class ArcsSet extends AbstractReg
      * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p>
      * @param tree inside/outside BSP tree representing the arcs set
      * @param tolerance tolerance below which close sub-arcs are merged together
+     * @exception InconsistentStateAt2PiWrapping if the tree leaf nodes are not
+     * consistent across the \( 0, 2 \pi \) crossing
      */
-    public ArcsSet(final BSPTree<Sphere1D> tree, final double tolerance) {
+    public ArcsSet(final BSPTree<Sphere1D> tree, final double tolerance)
+        throws InconsistentStateAt2PiWrapping {
         super(tree, tolerance);
+        check2PiConsistency();
     }
 
     /** Build an arcs set from a Boundary REPresentation (B-rep).
@@ -104,9 +109,13 @@ public class ArcsSet extends AbstractReg
      * space.</p>
      * @param boundary collection of boundary elements
      * @param tolerance tolerance below which close sub-arcs are merged together
+     * @exception InconsistentStateAt2PiWrapping if the tree leaf nodes are not
+     * consistent across the \( 0, 2 \pi \) crossing
      */
-    public ArcsSet(final Collection<SubHyperplane<Sphere1D>> boundary, final
double tolerance) {
+    public ArcsSet(final Collection<SubHyperplane<Sphere1D>> boundary, final
double tolerance)
+        throws InconsistentStateAt2PiWrapping {
         super(boundary, tolerance);
+        check2PiConsistency();
     }
 
     /** Build an inside/outside tree representing a single arc.
@@ -160,6 +169,70 @@ public class ArcsSet extends AbstractReg
 
     }
 
+    /** Check consistency.
+    * @exception InconsistentStateAt2PiWrapping if the tree leaf nodes are not
+    * consistent across the \( 0, 2 \pi \) crossing
+    */
+    private void check2PiConsistency() throws InconsistentStateAt2PiWrapping {
+
+        // start search at the tree root
+        BSPTree<Sphere1D> root = getTree(false);
+        if (root.getCut() == null) {
+            return;
+        }
+
+        // find the inside/outside state before the smallest internal node
+        final Boolean stateBefore = (Boolean) getFirstLeaf(root).getAttribute();
+
+        // find the inside/outside state after the largest internal node
+        final Boolean stateAfter = (Boolean) getLastLeaf(root).getAttribute();
+
+        if (stateBefore ^ stateAfter) {
+            throw new InconsistentStateAt2PiWrapping();
+        }
+
+    }
+
+    /** Get the first leaf node of a tree.
+     * @param root tree root
+     * @return first leaf node (i.e. node corresponding to the region just after 0.0 radians)
+     */
+    private BSPTree<Sphere1D> getFirstLeaf(final BSPTree<Sphere1D> root) {
+
+        if (root.getCut() == null) {
+            return root;
+        }
+
+        // find the smallest internal node
+        BSPTree<Sphere1D> smallest = null;
+        for (BSPTree<Sphere1D> n = root; n != null; n = previousInternalNode(n)) {
+            smallest = n;
+        }
+
+        return leafBefore(smallest);
+
+    }
+
+    /** Get the last leaf node of a tree.
+     * @param root tree root
+     * @return last leaf node (i.e. node corresponding to the region just before \( 2 \pi
\) radians)
+     */
+    private BSPTree<Sphere1D> getLastLeaf(final BSPTree<Sphere1D> root) {
+
+        if (root.getCut() == null) {
+            return root;
+        }
+
+        // find the largest internal node
+        BSPTree<Sphere1D> largest = null;
+        for (BSPTree<Sphere1D> n = root; n != null; n = nextInternalNode(n)) {
+            largest = n;
+        }
+
+        return leafAfter(largest);
+
+    }
+
     /** Get the node corresponding to the first arc start.
      * @return smallest internal node (i.e. first after 0.0 radians, in trigonometric direction),
      * or null if there are no internal nodes (i.e. the set is either empty or covers the
full circle)
@@ -173,11 +246,7 @@ public class ArcsSet extends AbstractReg
         }
 
         // walk tree until we find the smallest internal node
-        BSPTree<Sphere1D> previous = previousInternalNode(node);
-        while (previous != null) {
-            node = previous;
-            previous = previousInternalNode(node);
-        }
+        node = getFirstLeaf(node).getParent();
 
         // walk tree until we find an arc start
         while (node != null && !isArcStart(node)) {
@@ -372,22 +441,6 @@ public class ArcsSet extends AbstractReg
         return ((LimitAngle) node.getCut().getHyperplane()).getLocation().getAlpha();
     }
 
-    /** Build a sub-hyperplane corresponding to an arc start.
-     * @param alpha arc start
-     * @return sub-hyperplane for start of arc
-     */
-    private SubLimitAngle arcStart(final double alpha) {
-        return new LimitAngle(new S1Point(alpha), false, getTolerance()).wholeHyperplane();
-    }
-
-    /** Build a sub-hyperplane corresponding to an arc end.
-     * @param alpha arc end
-     * @return sub-hyperplane for end of arc
-     */
-    private SubLimitAngle arcEnd(final double alpha) {
-        return new LimitAngle(new S1Point(alpha), true, getTolerance()).wholeHyperplane();
-    }
-
     /** {@inheritDoc} */
     @Override
     public ArcsSet buildNew(final BSPTree<Sphere1D> tree) {
@@ -454,7 +507,7 @@ public class ArcsSet extends AbstractReg
         private final BSPTree<Sphere1D> firstStart;
 
         /** Current node. */
-        private BSPTree<Sphere1D> node;
+        private BSPTree<Sphere1D> current;
 
         /** Sub-arc no yet returned. */
         private double[] pending;
@@ -464,7 +517,7 @@ public class ArcsSet extends AbstractReg
         public SubArcsIterator() {
 
             firstStart = getFirstArcStart();
-            node = firstStart;
+            current    = firstStart;
 
             if (firstStart == null) {
                 // the tree has a single node
@@ -476,13 +529,6 @@ public class ArcsSet extends AbstractReg
                 } else {
                     pending = null;
                 }
-            } else if (previousInternalNode(firstStart) == null && nextInternalNode(firstStart)
== null) {
-                // the tree is a degenerate tree (probably build from a custom collection
of hyperplanes) with a single cut
-                // we ignore the cut and consider the tree represents the full circle
-                node = null;
-                pending = new double[] {
-                    0, MathUtils.TWO_PI
-                };
             } else {
                 selectPending();
             }
@@ -493,14 +539,14 @@ public class ArcsSet extends AbstractReg
         private void selectPending() {
 
             // look for the start of the arc
-            BSPTree<Sphere1D> start = node;
+            BSPTree<Sphere1D> start = current;
             while (start != null && !isArcStart(start)) {
                 start = nextInternalNode(start);
             }
 
             if (start == null) {
                 // we have exhausted the iterator
-                node    = null;
+                current = null;
                 pending = null;
                 return;
             }
@@ -519,7 +565,7 @@ public class ArcsSet extends AbstractReg
                 };
 
                 // prepare search for next arc
-                node = end;
+                current = end;
 
             } else {
 
@@ -539,7 +585,7 @@ public class ArcsSet extends AbstractReg
                 };
 
                 // there won't be any other arcs
-                node = null;
+                current = null;
 
             }
 
@@ -619,8 +665,12 @@ public class ArcsSet extends AbstractReg
      */
     public Split split(final Arc arc) {
 
-        final List<SubHyperplane<Sphere1D>> minus = new ArrayList<SubHyperplane<Sphere1D>>();
-        final List<SubHyperplane<Sphere1D>> plus  = new ArrayList<SubHyperplane<Sphere1D>>();
+        final BSPTree<Sphere1D> minus = new BSPTree<Sphere1D>();
+        minus.setAttribute(Boolean.FALSE);
+        boolean minusIgnored = false;
+        final BSPTree<Sphere1D> plus  = new BSPTree<Sphere1D>();
+        plus.setAttribute(Boolean.FALSE);
+        boolean plusIgnored  = false;
 
         final double reference = FastMath.PI + arc.getInf();
         final double arcLength = arc.getSup() - arc.getInf();
@@ -631,57 +681,145 @@ public class ArcsSet extends AbstractReg
             final double syncedEnd   = a[1] - arcOffset;
             if (syncedStart < arcLength) {
                 // the start point a[0] is in the minus part of the arc
-                minus.add(arcStart(a[0]));
+                minusIgnored = addArcStart(minus, a[0], minusIgnored);
                 if (syncedEnd > arcLength) {
                     // the end point a[1] is past the end of the arc
                     // so we leave the minus part and enter the plus part
                     final double minusToPlus = arcLength + arcOffset;
-                    minus.add(arcEnd(minusToPlus));
-                    plus.add(arcStart(minusToPlus));
+                    minusIgnored = addArcEnd(minus, minusToPlus, minusIgnored);
+                    plusIgnored  = addArcStart(plus, minusToPlus, plusIgnored);
                     if (syncedEnd > MathUtils.TWO_PI) {
                         // in fact the end point a[1] goes far enough that we
                         // leave the plus part of the arc and enter the minus part again
                         final double plusToMinus = MathUtils.TWO_PI + arcOffset;
-                        plus.add(arcEnd(plusToMinus));
-                        minus.add(arcStart(plusToMinus));
-                        minus.add(arcEnd(a[1]));
+                        plusIgnored  = addArcEnd(plus, plusToMinus, plusIgnored);
+                        minusIgnored = addArcStart(minus, plusToMinus, minusIgnored);
+                        minusIgnored = addArcEnd(minus, a[1], minusIgnored);
                     } else {
                         // the end point a[1] is in the plus part of the arc
-                        plus.add(arcEnd(a[1]));
+                        plusIgnored  = addArcEnd(plus, a[1], plusIgnored);
                     }
                 } else {
                     // the end point a[1] is in the minus part of the arc
-                    minus.add(arcEnd(a[1]));
+                    minusIgnored = addArcEnd(minus, a[1], minusIgnored);
                 }
             } else {
                 // the start point a[0] is in the plus part of the arc
-                plus.add(arcStart(a[0]));
+                plusIgnored  = addArcStart(plus, a[0], plusIgnored);
                 if (syncedEnd > MathUtils.TWO_PI) {
                     // the end point a[1] wraps around to the start of the arc
                     // so we leave the plus part and enter the minus part
                     final double plusToMinus = MathUtils.TWO_PI + arcOffset;
-                    plus.add(arcEnd(plusToMinus));
-                    minus.add(arcStart(plusToMinus));
+                    plusIgnored  = addArcEnd(plus, plusToMinus, plusIgnored);
+                    minusIgnored = addArcStart(minus, plusToMinus, minusIgnored);
                     if (syncedEnd > MathUtils.TWO_PI + arcLength) {
                         // in fact the end point a[1] goes far enough that we
                         // leave the minus part of the arc and enter the plus part again
                         final double minusToPlus = MathUtils.TWO_PI + arcLength + arcOffset;
-                        minus.add(arcEnd(minusToPlus));
-                        plus.add(arcStart(minusToPlus));
-                        plus.add(arcEnd(a[1]));
+                        minusIgnored = addArcEnd(minus, minusToPlus, minusIgnored);
+                        plusIgnored  = addArcStart(plus, minusToPlus, plusIgnored);
+                        plusIgnored  = addArcEnd(plus, a[1], plusIgnored);
                     } else {
                         // the end point a[1] is in the minus part of the arc
-                        minus.add(arcEnd(a[1]));
+                        minusIgnored = addArcEnd(minus, a[1], minusIgnored);
                     }
                 } else {
                     // the end point a[1] is in the plus part of the arc
-                    plus.add(arcEnd(a[1]));
+                    plusIgnored  = addArcEnd(plus, a[1], plusIgnored);
                 }
             }
         }
 
-        return new Split(plus.isEmpty()  ? null : new ArcsSet(plus, getTolerance()),
-                         minus.isEmpty() ? null : new ArcsSet(minus,getTolerance()));
+        return new Split(createSplitPart(plus, plusIgnored), createSplitPart(minus, minusIgnored));
+
+    }
+
+    /** Add an arc start to a BSP tree under construction.
+     * <p>
+     * Note that this method <em>MUST</em> be called in increasing angle order.
+     * </p>
+     * @param tree BSP tree under construction
+     * @param alpha arc start
+     * @param ignored if true, some end points have been ignored previously
+     * @return true if some points have been ignored, taking this arc end into account
+     */
+    private boolean addArcStart(final BSPTree<Sphere1D> tree, final double alpha, final
boolean ignored) {
+
+        final BSPTree<Sphere1D> last = getLastLeaf(tree);
+
+        if (alpha <= getTolerance()) {
+            // don't add a spurious cut hyperplane at the start of the circle,
+            last.setAttribute(Boolean.TRUE);
+            return true;
+        } else {
+            last.insertCut(new LimitAngle(new S1Point(alpha), false, getTolerance()));
+            last.setAttribute(null);
+            last.getPlus().setAttribute(Boolean.FALSE);
+            last.getMinus().setAttribute(Boolean.TRUE);
+            return ignored;
+        }
+
+    }
+
+    /** Add an arc end to a BSP tree under construction.
+     * <p>
+     * Note that this method <em>MUST</em> be called in increasing angle order.
+     * </p>
+     * @param tree BSP tree under construction
+     * @param alpha arc end
+     * @param ignored if true, some end points have been ignored previously
+     * @return true if some points have been ignored, taking this arc end into account
+     */
+    private boolean addArcEnd(final BSPTree<Sphere1D> tree, final double alpha, final
boolean ignored) {
+
+        final BSPTree<Sphere1D> last = getLastLeaf(tree);
+
+        if (alpha >= MathUtils.TWO_PI - getTolerance()) {
+
+            // don't add a spurious cut hyperplane at the end of the circle,
+            last.setAttribute(Boolean.TRUE);
+            return true;
+
+        } else {
+            last.insertCut(new LimitAngle(new S1Point(alpha), true, getTolerance()));
+            last.setAttribute(null);
+            last.getPlus().setAttribute(Boolean.FALSE);
+            last.getMinus().setAttribute(Boolean.TRUE);
+            return ignored;
+        }
+
+    }
+
+    /** Create a split part.
+     * @param tree BSP tree containing the limit angles of the split part
+     * @param ignored if true, some end points have been ignored previously
+     * @return split part (may be null)
+     */
+    private ArcsSet createSplitPart(final BSPTree<Sphere1D> tree, final boolean ignored)
{
+
+        if (ignored) {
+            // ensure consistent state at 0 / 2 \pi crossing
+
+            final BSPTree<Sphere1D> first = getFirstLeaf(tree);
+            final boolean firstState      = (Boolean) first.getAttribute();
+            final BSPTree<Sphere1D> last  = getLastLeaf(tree);
+            final boolean lastState       = (Boolean) last.getAttribute();
+            if (firstState ^ lastState) {
+                // there should be a real boundary at the crossing. Since it is not accurately
+                // representable due to S1Point normalizing the angles between 0 (included)
+                // and 2 \pi (excluded), we insert it at the *beginning* of the tree,
+                // with an angle forced to 0.0
+                first.insertCut(new LimitAngle(new S1Point(0.0), true, getTolerance()));
+                first.getPlus().setAttribute(firstState);
+                first.getMinus().setAttribute(lastState);
+            }
+        }
+
+        if (tree.getCut() == null && !(Boolean) tree.getAttribute()) {
+            return null;
+        } else {
+            return new ArcsSet(tree, getTolerance());
+        }
 
     }
 
@@ -722,4 +860,24 @@ public class ArcsSet extends AbstractReg
 
     }
 
+    /** Specialized exception for inconsistent BSP tree state inconsistency.
+     * <p>
+     * This exception is thrown at {@link ArcsSet} construction time when the
+     * {@link Location inside/outside} state is not consistent at the 0,
+     * \(2 \pi \) crossing.
+     * </p>
+     */
+    public static class InconsistentStateAt2PiWrapping extends MathIllegalArgumentException
{
+
+        /** Serializable UID. */
+        private static final long serialVersionUID = 20140107L;
+
+        /** Simple constructor.
+         */
+        public InconsistentStateAt2PiWrapping() {
+            super(LocalizedFormats.INCONSISTENT_STATE_AT_2_PI_WRAPPING);
+        }
+
+    }
+
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
Thu Jan  9 17:08:00 2014
@@ -59,7 +59,7 @@ public class LimitAngle implements Hyper
 
     /** {@inheritDoc} */
     public double getOffset(final Point<Sphere1D> point) {
-        final double delta = ((S1Point) point).getAlpha()- location.getAlpha();
+        final double delta = ((S1Point) point).getAlpha() - location.getAlpha();
         return direct ? delta : -delta;
     }
 

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SphericalPolygonsSet.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SphericalPolygonsSet.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SphericalPolygonsSet.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SphericalPolygonsSet.java
Thu Jan  9 17:08:00 2014
@@ -172,11 +172,12 @@ public class SphericalPolygonsSet extend
 
         // build the edges
         List<Edge> edges = new ArrayList<Edge>(n);
+        Vertex end = vArray[n - 1];
         for (int i = 0; i < n; ++i) {
 
             // get the endpoints of the edge
-            final Vertex start = vArray[i];
-            final Vertex end   = vArray[(i + 1) % n];
+            final Vertex start = end;
+            end = vArray[i];
 
             // get the circle supporting the edge, taking care not to recreate it
             // if it was already created earlier due to another edge being aligned

Modified: commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
(original)
+++ commons/proper/math/trunk/src/main/resources/assets/org/apache/commons/math3/exception/util/LocalizedFormats_fr.properties
Thu Jan  9 17:08:00 2014
@@ -87,6 +87,7 @@ GCD_OVERFLOW_32_BITS = d\u00e9passement 
 GCD_OVERFLOW_64_BITS = d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^63
 HOLE_BETWEEN_MODELS_TIME_RANGES = trou de longueur {0} entre les domaines temporels des mod\u00e8les
 ILL_CONDITIONED_OPERATOR = le conditionnement {1} est trop \u00e9lev\u00e9
+INCONSISTENT_STATE_AT_2_PI_WRAPPING = \u00e9tat incoh\u00e9rent au niveau du recollement
\u00e0 2\u03c0
 INDEX_LARGER_THAN_MAX = l''index sp\u00e9cifi\u00e9 ({0}) d\u00e9passe l''index maximal courant
({1})
 INDEX_NOT_POSITIVE = l''indice ({0}) n''est pas positif
 INDEX_OUT_OF_RANGE = l''indice ({0}) est hors du domaine autoris\u00e9 [{1}, {2}]

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/exception/util/LocalizedFormatsTest.java
Thu Jan  9 17:08:00 2014
@@ -30,7 +30,7 @@ public class LocalizedFormatsTest {
 
     @Test
     public void testMessageNumber() {
-        Assert.assertEquals(316, LocalizedFormats.values().length);
+        Assert.assertEquals(317, LocalizedFormats.values().length);
     }
 
     @Test

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java?rev=1556880&r1=1556879&r2=1556880&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
Thu Jan  9 17:08:00 2014
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.NoSuchElementException;
 
 import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.geometry.partitioning.BSPTree;
 import org.apache.commons.math3.geometry.partitioning.Region;
 import org.apache.commons.math3.geometry.partitioning.Region.Location;
 import org.apache.commons.math3.geometry.partitioning.RegionFactory;
@@ -67,6 +68,49 @@ public class ArcsSetTest {
         Assert.assertEquals(2.3 + MathUtils.TWO_PI, set.asList().get(0).getSup(), 1.0e-10);
     }
 
+    @Test
+    public void testSplitOver2Pi() {
+        ArcsSet set = new ArcsSet(1.0e-10);
+        Arc     arc = new Arc(1.5 * FastMath.PI, 2.5 * FastMath.PI, 1.0e-10);
+        ArcsSet.Split split = set.split(arc);
+        for (double alpha = 0; alpha <= MathUtils.TWO_PI; alpha += 0.01) {
+            S1Point p = new S1Point(alpha);
+            if (alpha < 0.5 * FastMath.PI || alpha > 1.5 * FastMath.PI) {
+                Assert.assertEquals(Location.OUTSIDE, split.getPlus().checkPoint(p));
+                Assert.assertEquals(Location.INSIDE,  split.getMinus().checkPoint(p));
+            } else {
+                Assert.assertEquals(Location.INSIDE,  split.getPlus().checkPoint(p));
+                Assert.assertEquals(Location.OUTSIDE, split.getMinus().checkPoint(p));
+            }
+        }
+    }
+
+    @Test
+    public void testSplitAtEnd() {
+        ArcsSet set = new ArcsSet(1.0e-10);
+        Arc     arc = new Arc(FastMath.PI, MathUtils.TWO_PI, 1.0e-10);
+        ArcsSet.Split split = set.split(arc);
+        for (double alpha = 0.01; alpha < MathUtils.TWO_PI; alpha += 0.01) {
+            S1Point p = new S1Point(alpha);
+            if (alpha > FastMath.PI) {
+                Assert.assertEquals(Location.OUTSIDE, split.getPlus().checkPoint(p));
+                Assert.assertEquals(Location.INSIDE,  split.getMinus().checkPoint(p));
+            } else {
+                Assert.assertEquals(Location.INSIDE,  split.getPlus().checkPoint(p));
+                Assert.assertEquals(Location.OUTSIDE, split.getMinus().checkPoint(p));
+            }
+        }
+
+        S1Point zero = new S1Point(0.0);
+        Assert.assertEquals(Location.BOUNDARY,  split.getPlus().checkPoint(zero));
+        Assert.assertEquals(Location.BOUNDARY,  split.getMinus().checkPoint(zero));
+
+        S1Point pi = new S1Point(FastMath.PI);
+        Assert.assertEquals(Location.BOUNDARY,  split.getPlus().checkPoint(pi));
+        Assert.assertEquals(Location.BOUNDARY,  split.getMinus().checkPoint(pi));
+
+    }
+
     @Test(expected=NumberIsTooLargeException.class)
     public void testWrongInterval() {
         new ArcsSet(1.2, 0.0, 1.0e-10);
@@ -122,7 +166,7 @@ public class ArcsSetTest {
     public void testSpecialConstruction() {
         List<SubHyperplane<Sphere1D>> boundary = new ArrayList<SubHyperplane<Sphere1D>>();
         boundary.add(new LimitAngle(new S1Point(0.0), false, 1.0e-10).wholeHyperplane());
-        boundary.add(new LimitAngle(new S1Point(MathUtils.TWO_PI), true, 1.0e-10).wholeHyperplane());
+        boundary.add(new LimitAngle(new S1Point(MathUtils.TWO_PI - 1.0e-11), true, 1.0e-10).wholeHyperplane());
         ArcsSet set = new ArcsSet(boundary, 1.0e-10);
         Assert.assertEquals(MathUtils.TWO_PI, set.getSize(), 1.0e-10);
         Assert.assertEquals(1.0e-10, set.getTolerance(), 1.0e-20);
@@ -288,6 +332,53 @@ public class ArcsSetTest {
     }
 
     @Test
+    public void testEmptyTree() {
+        Assert.assertEquals(MathUtils.TWO_PI, new ArcsSet(new BSPTree<Sphere1D>(Boolean.TRUE),
1.0e-10).getSize(), 1.0e-10);
+    }
+
+    @Test
+    public void testShiftedAngles() {
+        for (int k = -2; k < 3; ++k) {
+            SubLimitAngle l1  = new LimitAngle(new S1Point(1.0 + k * MathUtils.TWO_PI), false,
1.0e-10).wholeHyperplane();
+            SubLimitAngle l2  = new LimitAngle(new S1Point(1.5 + k * MathUtils.TWO_PI), true,
 1.0e-10).wholeHyperplane();
+            ArcsSet set = new ArcsSet(new BSPTree<Sphere1D>(l1,
+                                                            new BSPTree<Sphere1D>(Boolean.FALSE),
+                                                            new BSPTree<Sphere1D>(l2,
+                                                                                  new BSPTree<Sphere1D>(Boolean.FALSE),
+                                                                                  new BSPTree<Sphere1D>(Boolean.TRUE),
+                                                                                  null),
+                                                            null),
+                                      1.0e-10);
+            for (double alpha = 1.0e-6; alpha < MathUtils.TWO_PI; alpha += 0.001) {
+                if (alpha < 1 || alpha > 1.5) {
+                    Assert.assertEquals(Location.OUTSIDE, set.checkPoint(new S1Point(alpha)));
+                } else {
+                    Assert.assertEquals(Location.INSIDE,  set.checkPoint(new S1Point(alpha)));
+                }
+            }
+        }
+
+    }
+
+    @Test(expected=ArcsSet.InconsistentStateAt2PiWrapping.class)
+    public void testInconsistentState() {
+        SubLimitAngle l1 = new LimitAngle(new S1Point(1.0), false, 1.0e-10).wholeHyperplane();
+        SubLimitAngle l2 = new LimitAngle(new S1Point(2.0), true,  1.0e-10).wholeHyperplane();
+        SubLimitAngle l3 = new LimitAngle(new S1Point(3.0), false, 1.0e-10).wholeHyperplane();
+        new ArcsSet(new BSPTree<Sphere1D>(l1,
+                                          new BSPTree<Sphere1D>(Boolean.FALSE),
+                                          new BSPTree<Sphere1D>(l2,
+                                                                new BSPTree<Sphere1D>(l3,
+                                                                                      new
BSPTree<Sphere1D>(Boolean.FALSE),
+                                                                                      new
BSPTree<Sphere1D>(Boolean.TRUE),
+                                                                                      null),
+                                                                new BSPTree<Sphere1D>(Boolean.TRUE),
+                                                                null),
+                                          null),
+                                          1.0e-10);
+    }
+
+    @Test
     public void testSide() {
         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));



Mime
View raw message