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 2014/01/01 18:28:51 UTC

svn commit: r1554652 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/geometry/spherical/oned/ test/java/org/apache/commons/math3/geometry/spherical/ test/java/org/apache/commons/math3/geometry/spherical/oned/

Author: luc
Date: Wed Jan  1 17:28:51 2014
New Revision: 1554652

URL: http://svn.apache.org/r1554652
Log:
Intermediate, partially working stuff on the 1-sphere.

Chord/SubChord are most probably not the appropriate classes. They are
too complex and should be replaced by something simpler and more
0-dimension, like OrientedPoint in Euclidean 1-D.

Added:
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java   (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java   (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Arc.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/SubChord.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Arc.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Arc.java?rev=1554652&r1=1554651&r2=1554652&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Arc.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Arc.java Wed Jan  1 17:28:51 2014
@@ -54,7 +54,7 @@ public class Arc {
     public Arc(final double lower, final double upper) {
         this.lower = lower;
         if (Precision.equals(lower, upper, 0)) {
-            this.upper = 2 * FastMath.PI + lower;
+            this.upper = MathUtils.TWO_PI + lower;
         } else {
             this.upper = MathUtils.normalizeAngle(upper, lower + FastMath.PI);
         }
@@ -103,7 +103,7 @@ public class Arc {
         } else if (normalizedPoint > lower + tolerance && normalizedPoint < upper - tolerance) {
             return Location.INSIDE;
         } else {
-            return Location.BOUNDARY;
+            return (getSize() >= MathUtils.TWO_PI - tolerance) ? Location.INSIDE : Location.BOUNDARY;
         }
     }
 

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=1554652&r1=1554651&r2=1554652&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 Wed Jan  1 17:28:51 2014
@@ -18,10 +18,12 @@ package org.apache.commons.math3.geometr
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.math3.geometry.partitioning.AbstractRegion;
 import org.apache.commons.math3.geometry.partitioning.BSPTree;
+import org.apache.commons.math3.geometry.partitioning.BSPTreeVisitor;
 import org.apache.commons.math3.geometry.partitioning.SubHyperplane;
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.MathUtils;
@@ -144,7 +146,7 @@ public class ArcsSet extends AbstractReg
     protected void computeGeometricalProperties() {
         if (getTree(false).getCut() == null) {
             setBarycenter(S1Point.NaN);
-            setSize(((Boolean) getTree(false).getAttribute()) ? 2 * FastMath.PI : 0);
+            setSize(((Boolean) getTree(false).getAttribute()) ? MathUtils.TWO_PI : 0);
         } else {
             double size = 0.0;
             double sum  = 0.0;
@@ -153,7 +155,7 @@ public class ArcsSet extends AbstractReg
                 sum  += arc.getSize() * arc.getBarycenter();
             }
             setSize(size);
-            if (Precision.equals(size, 2 * FastMath.PI, 0)) {
+            if (Precision.equals(size, MathUtils.TWO_PI, 0)) {
                 setBarycenter(S1Point.NaN);
             } else if (size >= Precision.SAFE_MIN) {
                 setBarycenter(new S1Point(sum / size));
@@ -167,55 +169,84 @@ public class ArcsSet extends AbstractReg
     /** Build an ordered list of arcs representing the instance.
      * <p>This method builds this arcs set as an ordered list of
      * {@link Arc Arc} elements. An empty tree will build an empty list
-     * while a tree representing the whole real line will build a one
-     * element list with bounds set to \( 0 and \pi \).</p>
+     * while a tree representing the whole circle will build a one
+     * element list with bounds set to \( 0 and 2 \pi \).</p>
      * @return a new ordered list containing {@link Arc Arc} elements
      */
     public List<Arc> asList() {
+
         final List<Arc> list = new ArrayList<Arc>();
-        recurseList(getTree(false), list, 0, 2 * FastMath.PI);
+        final BSPTree<Sphere1D> root = getTree(false);
+
+        if (root.getCut() == null) {
+            // the tree has a single node
+            if ((Boolean) root.getAttribute()) {
+                // it is an inside node, it represents the full circle
+                list.add(new Arc(0.0, 0.0)); // since lower == upper, the arc covers the full circle
+            }
+        } else {
+
+            // find all arcs limits
+            final LimitsCollector finder = new LimitsCollector();
+            root.visit(finder);
+            final List<Double> limits = finder.getLimits();
+
+            // sort them so the first angle is an arc start
+            Collections.sort(limits);
+            if (checkPoint(new S1Point(0.5 * (limits.get(0) + limits.get(1)))) == Location.OUTSIDE) {
+                // the first angle is not an arc start, its the last arc end
+                // move it properly to the end
+                limits.add(limits.remove(0) + MathUtils.TWO_PI);
+            }
+
+            // we can now build the list
+            for (int i = 0; i < limits.size(); i += 2) {
+                list.add(new Arc(limits.get(i), limits.get(i + 1)));
+            }
+
+        }
+
         return list;
+
     }
 
-    /** Update an arcs list.
-     * @param node current node
-     * @param list list to update
-     * @param lower lower bound of the current convex cell
-     * @param upper upper bound of the current convex cell
-     */
-    private void recurseList(final BSPTree<Sphere1D> node, final List<Arc> list,
-                             final double lower, final double upper) {
-
-        if (node.getCut() == null) {
-            if ((Boolean) node.getAttribute()) {
-                // this leaf cell is an inside cell: an arc
-                list.add(new Arc(lower, upper));
+    /** Visitor looking for arc limits. */
+    private final class LimitsCollector implements BSPTreeVisitor<Sphere1D> {
+
+        /** Collected limits. */
+        private List<Double> limits;
+
+        /** Simple constructor. */
+        public LimitsCollector() {
+            this.limits = new ArrayList<Double>();
+        }
+
+        /** {@inheritDoc} */
+        public BSPTreeVisitor.Order visitOrder(final BSPTree<Sphere1D> node) {
+            return Order.MINUS_PLUS_SUB;
+        }
+
+        /** {@inheritDoc} */
+        public void visitInternalNode(final BSPTree<Sphere1D> node) {
+            // check if the chord end points are arc limits
+            final Chord chord = (Chord) node.getCut().getHyperplane();
+            if (checkPoint(new S1Point(chord.getStart())) == Location.BOUNDARY) {
+                limits.add(MathUtils.normalizeAngle(chord.getStart(), FastMath.PI));
             }
-        } else {
-            final SubChord  cut      = (SubChord) node.getCut();
-            final List<Arc> cutArcs  = cut.getSubArcs();
-            final double    cutStart = cutArcs.get(0).getInf();
-            final double    cutEnd   = cutArcs.get(cutArcs.size() - 1).getSup();
-
-            recurseList(node.getMinus(), list, lower, cutStart);
-            if (list.get(list.size() - 1).checkPoint(cutStart, tolerance) == Location.INSIDE) {
-                // merge the last arc before the sub-chord and the sub-chord
-                final Arc merged = new Arc(list.remove(list.size() - 1).getInf(),
-                                           cutArcs.remove(0).getSup());
-                cutArcs.add(0, merged);
-            }
-
-            final List<Arc> highList = new ArrayList<Arc>();
-            recurseList(node.getPlus(), highList, cutEnd, upper);
-            if (highList.get(0).checkPoint(cutEnd, tolerance) == Location.INSIDE) {
-                // merge the first arc after the sub-chord and the sub-chord
-                final Arc merged = new Arc(cutArcs.remove(cutArcs.size() - 1).getInf(),
-                                           highList.remove(0).getSup());
-                highList.add(0, merged);
+            if (checkPoint(new S1Point(chord.getEnd())) == Location.BOUNDARY) {
+                limits.add(MathUtils.normalizeAngle(chord.getEnd(), FastMath.PI));
             }
+        }
 
-            list.addAll(highList);
+        /** {@inheritDoc} */
+        public void visitLeafNode(final BSPTree<Sphere1D> node) {
+        }
 
+        /** Get the collected limits.
+         * @return collected limits
+         */
+        public List<Double> getLimits() {
+            return limits;
         }
 
     }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubChord.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubChord.java?rev=1554652&r1=1554651&r2=1554652&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubChord.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubChord.java Wed Jan  1 17:28:51 2014
@@ -69,6 +69,29 @@ public class SubChord implements SubHype
         return subArcs;
     }
 
+    /** Get the number of sub-arcs.
+     * @return number of sub-arcs
+     */
+    public int getNbSubArcs() {
+        return limits.size() / 2;
+    }
+
+    /** Get the start of the i<sup>th</sup> sub-arc.
+     * @param i index of the desired arc (counting from 0)
+     * @return start of the i<sup>th</sup> sub-arc
+     */
+    public double getStart(final int i) {
+        return limits.get(2 * i);
+    }
+
+    /** Get the end of the i<sup>th</sup> sub-arc.
+     * @param i index of the desired arc (counting from 0)
+     * @return end of the i<sup>th</sup> sub-arc
+     */
+    public double getEnd(final int i) {
+        return limits.get(2 * i + 1);
+    }
+
     /** {@inheritDoc} */
     public double getSize() {
         double sum = 0;
@@ -81,15 +104,22 @@ public class SubChord implements SubHype
     /** {@inheritDoc} */
     public Side side(final Hyperplane<Sphere1D> hyperplane) {
 
-        final Chord testChord  = (Chord) hyperplane;
-        final double reference = FastMath.PI + testChord.getStart();
-        final double otherEnd  = testChord.getEnd();
+        final Chord  testChord   = (Chord) hyperplane;
+        final double reference   = FastMath.PI + testChord.getStart();
+        final double chordLength = testChord.getEnd() - testChord.getStart();
 
         boolean inMinus = false;
         boolean inPlus  = false;
         for (int i = 0; i < limits.size(); i += 2) {
-            inMinus = inMinus || (MathUtils.normalizeAngle(limits.get(i),     reference) < otherEnd);
-            inPlus  = inPlus  || (MathUtils.normalizeAngle(limits.get(i + 1), reference) > otherEnd);
+            final double syncedStart = MathUtils.normalizeAngle(limits.get(i), reference) - testChord.getStart();
+            final double chordOffset = limits.get(i) - syncedStart;
+            final double syncedEnd   = limits.get(i + 1) - chordOffset;
+            if (syncedStart < chordLength || syncedEnd > MathUtils.TWO_PI) {
+                inMinus = true;
+            }
+            if (syncedEnd > chordLength) {
+                inPlus = true;
+            }
         }
 
         if (inMinus) {
@@ -111,34 +141,76 @@ public class SubChord implements SubHype
     /** {@inheritDoc} */
     public SplitSubHyperplane<Sphere1D> split(final Hyperplane<Sphere1D> hyperplane) {
 
-        final Chord testChord  = (Chord) hyperplane;
-        final double reference = FastMath.PI + testChord.getStart();
-        final double otherEnd  = testChord.getEnd();
-
         final List<Double> minus = new ArrayList<Double>(limits.size());
         final List<Double> plus  = new ArrayList<Double>(limits.size());
 
+        final Chord  testChord   = (Chord) hyperplane;
+        final double reference   = FastMath.PI + testChord.getStart();
+        final double chordLength = testChord.getEnd() - testChord.getStart();
+
         for (int i = 0; i < limits.size(); i += 2) {
-            final double subStart = MathUtils.normalizeAngle(limits.get(i),     reference);
-            final double subEnd   = MathUtils.normalizeAngle(limits.get(i + 1), reference);
-            if (subStart < otherEnd) {
-                minus.add(subStart);
-                minus.add(FastMath.min(subEnd, otherEnd));
-            }
-            if (subEnd > otherEnd) {
-                plus.add(FastMath.max(subStart, otherEnd));
-                plus.add(subEnd);
+            final double syncedStart = MathUtils.normalizeAngle(limits.get(i), reference) - testChord.getStart();
+            final double chordOffset = limits.get(i) - syncedStart;
+            final double syncedEnd   = limits.get(i + 1) - chordOffset;
+            if (syncedStart < chordLength) {
+                // the start point limits.get(i) is in the minus part of the chord
+                minus.add(limits.get(i));
+                if (syncedEnd > chordLength) {
+                    // the end point limits.get(i + 1) is past the end of the chord
+                    // so we leave the minus part and enter the plus part
+                    final double minusToPlus = chordLength + chordOffset;
+                    minus.add(minusToPlus);
+                    plus.add(minusToPlus);
+                    if (syncedEnd > MathUtils.TWO_PI) {
+                        // in fact the end point limits.get(i + 1) goes far enough that we
+                        // leave the plus part of the chord and enter the minus part again
+                        final double plusToMinus = MathUtils.TWO_PI + chordOffset;
+                        plus.add(plusToMinus);
+                        minus.add(plusToMinus);
+                        minus.add(limits.get(i + 1));
+                    } else {
+                        // the end point limits.get(i + 1) is in the plus part of the chord
+                        plus.add(limits.get(i + 1));
+                    }
+                } else {
+                    // the end point limits.get(i + 1) is in the minus part of the chord
+                    minus.add(limits.get(i + 1));
+                }
+            } else {
+                // the start point limits.get(i) is in the plus part of the chord
+                plus.add(limits.get(i));
+                if (syncedEnd > MathUtils.TWO_PI) {
+                    // the end point limits.get(i + 1) wraps around to the start of the chord
+                    // so we leave the plus part and enter the minus part
+                    final double plusToMinus = MathUtils.TWO_PI + chordOffset;
+                    plus.add(plusToMinus);
+                    minus.add(plusToMinus);
+                    if (syncedEnd > MathUtils.TWO_PI + chordLength) {
+                        // in fact the end point limits.get(i + 1) goes far enough that we
+                        // leave the minus part of the chord and enter the plus part again
+                        final double minusToPlus = MathUtils.TWO_PI + chordLength + chordOffset;
+                        minus.add(minusToPlus);
+                        plus.add(minusToPlus);
+                        plus.add(limits.get(i + 1));
+                    } else {
+                        // the end point limits.get(i + 1) is in the minus part of the chord
+                        minus.add(limits.get(i + 1));
+                    }
+                } else {
+                    // the end point limits.get(i + 1) is in the plus part of the chord
+                    plus.add(limits.get(i + 1));
+                }
             }
         }
 
-        return new SplitSubHyperplane<Sphere1D>(new SubChord(chord, plus),
-                                                new SubChord(chord, minus));
+        return new SplitSubHyperplane<Sphere1D>(plus.isEmpty()  ? null : new SubChord(chord, plus),
+                                                minus.isEmpty() ? null : new SubChord(chord, minus));
 
     }
 
     /** {@inheritDoc} */
     public SubChord copySelf() {
-        return new SubChord(chord, limits);
+        return new SubChord(chord.copySelf(), limits);
     }
 
     /** {@inheritDoc} */
@@ -157,9 +229,9 @@ public class SubChord implements SubHype
         final List<Double> otherLimits = ((SubChord) other).limits;
 
         final List<Double> merged;
-        if (otherLimits.isEmpty()) {
+        if (other.isEmpty()) {
             merged = limits;
-        } else if (limits.isEmpty()) {
+        } else if (isEmpty()) {
             merged = otherLimits;
         } else {
 
@@ -205,25 +277,29 @@ public class SubChord implements SubHype
                         i = -1;
                     } else {
                         ++i;
+                        angleI = MathUtils.normalizeAngle(limits.get(i), reference);
                     }
-                    angleI    = MathUtils.normalizeAngle(limits.get(i), reference);
                     enteringI = !enteringI;
                 } else {
-                    if (inMerged && enteringI && (!enteringJ)) {
-                        // we were in a merged arc and exit from it
-                        merged.add(angleJ);
-                        inMerged = false;
-                    } else if (!inMerged && enteringJ) {
-                        // we were outside and enter into a merged arc
-                        merged.add(angleJ);
-                        inMerged = true;
+                    if (inMerged) {
+                        if (enteringI && !enteringJ) {
+                            // we were in a merged arc and exit from it
+                            merged.add(angleJ);
+                            inMerged = false;
+                        }
+                    } else {
+                        if (enteringJ) {
+                            // we were outside and enter into a merged arc
+                            merged.add(angleJ);
+                            inMerged = true;
+                        }
                     }
                     if (j == jEnd) {
                         j = -1;
                     } else {
-                        j = (j + 1) % otherLimits.size();
+                        j      = (j + 1) % otherLimits.size();
+                        angleJ = MathUtils.normalizeAngle(otherLimits.get(j), reference);
                     }
-                    angleJ    = MathUtils.normalizeAngle(otherLimits.get(j), reference);
                     enteringJ = !enteringJ;
                 }
 
@@ -235,9 +311,9 @@ public class SubChord implements SubHype
                 if (merged.isEmpty()) {
                     // the merged arc covers all the circle
                     merged.add(0.0);
-                    merged.add(2 * FastMath.PI);
+                    merged.add(MathUtils.TWO_PI);
                 } else {
-                    double previousAngle = merged.get(merged.size() - 1) - 2 * FastMath.PI;
+                    double previousAngle = merged.get(merged.size() - 1) - MathUtils.TWO_PI;
                     for (int k = 0; k < merged.size() - 1; ++k) {
                         final double tmp = merged.get(k);
                         merged.set(k, previousAngle);

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java?rev=1554652&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java Wed Jan  1 17:28:51 2014
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.geometry.spherical.oned;
+
+import org.apache.commons.math3.geometry.partitioning.Region;
+import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.util.Precision;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ArcTest {
+
+    @Test
+    public void testArc() {
+        Arc arc = new Arc(2.3, 5.7);
+        Assert.assertEquals(3.4, arc.getSize(), 1.0e-10);
+        Assert.assertEquals(4.0, arc.getBarycenter(), 1.0e-10);
+        Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(2.3, 1.0e-10));
+        Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(5.7, 1.0e-10));
+        Assert.assertEquals(Region.Location.OUTSIDE,  arc.checkPoint(1.2, 1.0e-10));
+        Assert.assertEquals(Region.Location.OUTSIDE,  arc.checkPoint(8.5, 1.0e-10));
+        Assert.assertEquals(Region.Location.INSIDE,   arc.checkPoint(8.7, 1.0e-10));
+        Assert.assertEquals(Region.Location.INSIDE,   arc.checkPoint(3.0, 1.0e-10));
+        Assert.assertEquals(2.3, arc.getInf(), 1.0e-10);
+        Assert.assertEquals(5.7, arc.getSup(), 1.0e-10);
+        Assert.assertEquals(4.0, arc.getBarycenter(), 1.0e-10);
+        Assert.assertEquals(3.4, arc.getSize(), 1.0e-10);
+    }
+
+    @Test
+    public void testTolerance() {
+        Arc arc = new Arc(2.3, 5.7);
+        Assert.assertEquals(Region.Location.OUTSIDE,  arc.checkPoint(1.2, 1.0));
+        Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(1.2, 1.2));
+        Assert.assertEquals(Region.Location.OUTSIDE,  arc.checkPoint(6.5, 0.7));
+        Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(6.5, 0.9));
+        Assert.assertEquals(Region.Location.INSIDE,   arc.checkPoint(3.0, 0.6));
+        Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(3.0, 0.8));
+    }
+
+    @Test
+    public void testFullCircle() {
+        Arc arc = new Arc(9.0, 9.0);
+        // no boundaries on a full circle
+        Assert.assertEquals(Region.Location.INSIDE, arc.checkPoint(9.0, 1.0e-10));
+        Assert.assertEquals(9.0, arc.getInf(), 1.0e-10);
+        Assert.assertEquals(9.0 + 2.0 * FastMath.PI, arc.getSup(), 1.0e-10);
+        Assert.assertEquals(2.0 * FastMath.PI, arc.getSize(), 1.0e-10);
+        for (double alpha = -20.0; alpha <= 20.0; alpha += 0.1) {
+            Assert.assertEquals(Region.Location.INSIDE,
+                                arc.checkPoint(alpha, 1.0e-10));
+        }
+    }
+
+    @Test
+    public void testSmall() {
+        Arc arc = new Arc(1.0, FastMath.nextAfter(1.0, Double.POSITIVE_INFINITY));
+        Assert.assertEquals(2 * Precision.EPSILON, arc.getSize(), Precision.SAFE_MIN);
+        Assert.assertEquals(1.0, arc.getBarycenter(), Precision.EPSILON);
+    }
+
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: 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=1554652&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java Wed Jan  1 17:28:51 2014
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.geometry.spherical.oned;
+
+import java.util.List;
+
+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;
+import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.util.MathUtils;
+import org.apache.commons.math3.util.Precision;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ArcsSetTest {
+
+    @Test
+    public void testArc() {
+        ArcsSet set = new ArcsSet(2.3, 5.7, 1.0e-10);
+        Assert.assertEquals(3.4, set.getSize(), 1.0e-10);
+        Assert.assertEquals(4.0, ((S1Point) set.getBarycenter()).getAlpha(), 1.0e-10);
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(2.3)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(5.7)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new S1Point(1.2)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new S1Point(8.5)));
+        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(new S1Point(8.7)));
+        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(new S1Point(3.0)));
+        Assert.assertEquals(1, set.asList().size());
+        Assert.assertEquals(2.3, set.asList().get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.7, set.asList().get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(4.0, ((S1Point) set.getBarycenter()).getAlpha(), 1.0e-10);
+        Assert.assertEquals(3.4, set.getSize(), 1.0e-10);
+    }
+
+    @Test
+    public void testFullCircle() {
+        ArcsSet set = new ArcsSet(9.0, 9.0, 1.0e-10);
+        Assert.assertEquals(Region.Location.INSIDE, set.checkPoint(new S1Point(9.0)));
+        for (double alpha = -20.0; alpha <= 20.0; alpha += 0.1) {
+            Assert.assertEquals(Region.Location.INSIDE, set.checkPoint(new S1Point(alpha)));
+        }
+        Assert.assertEquals(1, set.asList().size());
+        Assert.assertEquals(0.0, set.asList().get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(2 * FastMath.PI, set.asList().get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(2 * FastMath.PI, set.getSize(), 1.0e-10);
+    }
+
+    @Test
+    public void testDifference() {
+
+        ArcsSet a   = new ArcsSet(1.0, 6.0, 1.0e-10);
+        List<Arc> aList = a.asList();
+        Assert.assertEquals(1,   aList.size());
+        Assert.assertEquals(1.0, aList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(6.0, aList.get(0).getSup(), 1.0e-10);
+
+        ArcsSet b   = new ArcsSet(3.0, 5.0, 1.0e-10);
+        List<Arc> bList = b.asList();
+        Assert.assertEquals(1,   bList.size());
+        Assert.assertEquals(3.0, bList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.0, bList.get(0).getSup(), 1.0e-10);
+
+        ArcsSet aMb = (ArcsSet) new RegionFactory<Sphere1D>().difference(a, b);
+        for (int k = -2; k < 3; ++k) {
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(0.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(0.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(1.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(1.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(2.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(3.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(3.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(4.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(5.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(5.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(5.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(6.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(6.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(6.2 + k * MathUtils.TWO_PI)));
+        }
+
+        List<Arc> aMbList = aMb.asList();
+        Assert.assertEquals(2,   aMbList.size());
+        Assert.assertEquals(1.0, aMbList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(3.0, aMbList.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(5.0, aMbList.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(6.0, aMbList.get(1).getSup(), 1.0e-10);
+
+
+    }
+
+    @Test
+    public void testIntersection() {
+
+        ArcsSet a   = (ArcsSet) new RegionFactory<Sphere1D>().union(new ArcsSet(1.0, 3.0, 1.0e-10),
+                                                                    new ArcsSet(5.0, 6.0, 1.0e-10));
+        List<Arc> aList = a.asList();
+        Assert.assertEquals(2,   aList.size());
+        Assert.assertEquals(1.0, aList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(3.0, aList.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(5.0, aList.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(6.0, aList.get(1).getSup(), 1.0e-10);
+
+        ArcsSet b   = new ArcsSet(0.0, 5.5, 1.0e-10);
+        List<Arc> bList = b.asList();
+        Assert.assertEquals(1,   bList.size());
+        Assert.assertEquals(0.0, bList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.5, bList.get(0).getSup(), 1.0e-10);
+
+        ArcsSet aMb = (ArcsSet) new RegionFactory<Sphere1D>().intersection(a, b);
+        for (int k = -2; k < 3; ++k) {
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(0.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(1.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(1.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(2.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(3.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(3.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(4.9 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(5.0 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(5.1 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.INSIDE,   aMb.checkPoint(new S1Point(5.4 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(5.5 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(5.6 + k * MathUtils.TWO_PI)));
+            Assert.assertEquals(Location.OUTSIDE,  aMb.checkPoint(new S1Point(6.2 + k * MathUtils.TWO_PI)));
+        }
+
+        List<Arc> aMbList = aMb.asList();
+        Assert.assertEquals(1,   aMbList.size());
+        Assert.assertEquals(1.0, aMbList.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(3.0, aMbList.get(0).getSup(), 1.0e-10);
+
+
+    }
+
+    @Test
+    public void testMultiple() {
+        RegionFactory<Sphere1D> factory = new RegionFactory<Sphere1D>();
+        ArcsSet set = (ArcsSet)
+        factory.intersection(factory.union(factory.difference(new ArcsSet(1.0, 6.0, 1.0e-10),
+                                                              new ArcsSet(3.0, 5.0, 1.0e-10)),
+                                                              new ArcsSet(0.5, 2.0, 1.0e-10)),
+                                                              new ArcsSet(0.0, 5.5, 1.0e-10));
+        Assert.assertEquals(3.0, set.getSize(), 1.0e-10);
+        Assert.assertEquals(7.0 / 3.0, ((S1Point) set.getBarycenter()).getAlpha(), 1.0e-10);
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new S1Point(0.0)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new S1Point(4.0)));
+        Assert.assertEquals(Region.Location.OUTSIDE,  set.checkPoint(new S1Point(6.0)));
+        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(new S1Point(1.2)));
+        Assert.assertEquals(Region.Location.INSIDE,   set.checkPoint(new S1Point(5.25)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(0.5)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(3.0)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(5.0)));
+        Assert.assertEquals(Region.Location.BOUNDARY, set.checkPoint(new S1Point(5.5)));
+
+        List<Arc> list = set.asList();
+        Assert.assertEquals(2, list.size());
+        Assert.assertEquals( 0.5, list.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals( 3.0, list.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals( 5.0, list.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals( 5.5, list.get(1).getSup(), 1.0e-10);
+
+    }
+
+    @Test
+    public void testSinglePoint() {
+        ArcsSet set = new ArcsSet(1.0, FastMath.nextAfter(1.0, Double.POSITIVE_INFINITY), 1.0e-10);
+        Assert.assertEquals(2 * Precision.EPSILON, set.getSize(), Precision.SAFE_MIN);
+        Assert.assertEquals(1.0, ((S1Point) set.getBarycenter()).getAlpha(), Precision.EPSILON);
+    }
+
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java?rev=1554652&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java Wed Jan  1 17:28:51 2014
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.geometry.spherical.oned;
+
+import org.apache.commons.math3.util.MathUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ChordTest {
+
+    @Test
+    public void testChord() {
+        Chord chord = new Chord(2.3, 5.7, 1.0e-10);
+        Assert.assertEquals(2.3, chord.copySelf().getStart(), 1.0e-10);
+        Assert.assertEquals(5.7, chord.copySelf().getEnd(), 1.0e-10);
+        Assert.assertEquals(1.0e-10, chord.copySelf().getTolerance(),  1.0e-20);
+        Assert.assertEquals(3.4, chord.wholeHyperplane().getSize(), 1.0e-10);
+        checkOutside(chord,  2.25);
+        checkBoundary(chord, 2.3);
+        checkInside(chord,   2.35);
+        checkInside(chord,  5.65);
+        checkBoundary(chord, 5.7);
+        checkOutside(chord,   5.75);
+    }
+
+    @Test
+    public void testReverse() {
+        Chord chord = new Chord(2.3, 5.7, 1.0e-10);
+        Chord reversed = chord.getReverse();
+        Assert.assertEquals(chord.getEnd(), reversed.getStart(), 1.0e-10);
+        Assert.assertEquals(chord.getStart() + MathUtils.TWO_PI, reversed.getEnd(), 1.0e-10);
+        Assert.assertEquals(1.0e-10, reversed.getTolerance(), 1.0e-20);
+        Assert.assertEquals(MathUtils.TWO_PI - 3.4, reversed.wholeHyperplane().getSize(), 1.0e-10);
+        Assert.assertFalse(chord.sameOrientationAs(reversed));
+        checkInside(reversed,  2.25);
+        checkBoundary(reversed, 2.3);
+        checkOutside(reversed,   2.35);
+        checkOutside(reversed,  5.65);
+        checkBoundary(reversed, 5.7);
+        checkInside(reversed,   5.75);
+    }
+
+    @Test
+    public void testWholeHyperplane() {
+        Chord chord = new Chord(2.3, 5.7, 1.0e-10);
+        SubChord subChord = chord.wholeHyperplane();
+        Assert.assertTrue(chord == subChord.getHyperplane());
+        Assert.assertEquals(chord.getEnd() - chord.getStart(), subChord.getSize(), 1.0e-10);
+    }
+
+    @Test
+    public void testWholeSpace() {
+        Chord chord = new Chord(2.3, 5.7, 1.0e-10);
+        ArcsSet set = chord.wholeSpace();
+        Assert.assertEquals(1,   set.asList().size());
+        Assert.assertEquals(0.0, set.asList().get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(MathUtils.TWO_PI, set.asList().get(0).getSup(), 1.0e-10);
+    }
+
+    private void checkInside(Chord chord, double alpha) {
+        for (int i = -2; i < 3; ++i) {
+            Assert.assertTrue(chord.getOffset(new S1Point(alpha + i * MathUtils.TWO_PI)) < 0.0);
+        }
+    }
+
+    private void checkOutside(Chord chord, double alpha) {
+        for (int i = -2; i < 3; ++i) {
+            Assert.assertTrue(chord.getOffset(new S1Point(alpha + i * MathUtils.TWO_PI)) > 0.0);
+        }
+    }
+
+    private void checkBoundary(Chord chord, double alpha) {
+        for (int i = -2; i < 3; ++i) {
+            Assert.assertEquals(0.0, chord.getOffset(new S1Point(alpha + i * MathUtils.TWO_PI)), chord.getTolerance());
+        }
+    }
+
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java?rev=1554652&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java Wed Jan  1 17:28:51 2014
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.geometry.spherical.oned;
+
+import java.util.List;
+
+import org.apache.commons.math3.geometry.partitioning.Side;
+import org.apache.commons.math3.geometry.partitioning.SubHyperplane.SplitSubHyperplane;
+import org.apache.commons.math3.util.MathUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SubChordTest {
+
+    @Test
+    public void testSubChord() {
+
+        SubChord subChord = new SubChord(new Chord(2.3, 5.7, 1.0e-10));
+        Assert.assertEquals(3.4, subChord.getSize(), 1.0e-10);
+        Assert.assertFalse(subChord.isEmpty());
+
+        Assert.assertEquals(1,   subChord.getNbSubArcs());
+        Assert.assertEquals(2.3, subChord.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.7, subChord.getEnd(0), 1.0e-10);
+        Assert.assertEquals(1,   subChord.getSubArcs().size());
+        Assert.assertEquals(2.3, subChord.getSubArcs().get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.7, subChord.getSubArcs().get(0).getSup(), 1.0e-10);
+
+        // despite a deep copy is used, chord being immutable its copy returns the same instance
+        Assert.assertTrue(subChord.getHyperplane() == subChord.copySelf().getHyperplane());
+
+    }
+
+    @Test
+    public void testSideEmbedded() {
+
+        SubChord s35 = new SubChord(new Chord(3.0, 5.0, 1.0e-10));
+        SubChord s16 = new SubChord(new Chord(1.0, 6.0, 1.0e-10));
+
+        Assert.assertEquals(Side.BOTH,  s16.side(s35.getHyperplane()));
+        Assert.assertEquals(Side.BOTH,  s16.side(s35.getHyperplane().getReverse()));
+        Assert.assertEquals(Side.MINUS, s35.side(s16.getHyperplane()));
+        Assert.assertEquals(Side.PLUS,  s35.side(s16.getHyperplane().getReverse()));
+
+    }
+
+    @Test
+    public void testSideOverlapping() {
+        SubChord s35 = new SubChord(new Chord(3.0, 5.0, 1.0e-10));
+        SubChord s46 = new SubChord(new Chord(4.0, 6.0, 1.0e-10));
+
+        Assert.assertEquals(Side.BOTH,  s46.side(s35.getHyperplane()));
+        Assert.assertEquals(Side.BOTH,  s46.side(s35.getHyperplane().getReverse()));
+        Assert.assertEquals(Side.BOTH, s35.side(s46.getHyperplane()));
+        Assert.assertEquals(Side.BOTH,  s35.side(s46.getHyperplane().getReverse()));
+    }
+
+    @Test
+    public void testSideHyper() {
+        Chord zeroLength = new Chord(2.0, 2.0, 1.0e-10);
+        SubChord sub = new SubChord(zeroLength);
+        Assert.assertTrue(sub.isEmpty());
+        Assert.assertEquals(Side.HYPER,  sub.side(zeroLength));
+    }
+
+    @Test
+    public void testSplitEmbedded() {
+
+        SubChord s35 = new SubChord(new Chord(3.0, 5.0, 1.0e-10));
+        SubChord s16 = new SubChord(new Chord(1.0, 6.0, 1.0e-10));
+
+        SplitSubHyperplane<Sphere1D> split1 = s16.split(s35.getHyperplane());
+        SubChord split1Plus  = (SubChord) split1.getPlus();
+        SubChord split1Minus = (SubChord) split1.getMinus();
+        Assert.assertEquals(3.0, split1Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(2,   split1Plus.getNbSubArcs());
+        Assert.assertEquals(1.0, split1Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(3.0, split1Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(5.0, split1Plus.getStart(1), 1.0e-10);
+        Assert.assertEquals(6.0, split1Plus.getEnd(1), 1.0e-10);
+        Assert.assertEquals(2.0, split1Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split1Minus.getNbSubArcs());
+        Assert.assertEquals(3.0, split1Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split1Minus.getEnd(0), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split2 = s16.split(s35.getHyperplane().getReverse());
+        SubChord split2Plus  = (SubChord) split2.getPlus();
+        SubChord split2Minus = (SubChord) split2.getMinus();
+        Assert.assertEquals(2.0, split2Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split2Plus.getNbSubArcs());
+        Assert.assertEquals(3.0, split2Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split2Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(3.0, split2Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(2,   split2Minus.getNbSubArcs());
+        Assert.assertEquals(1.0, split2Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(3.0, split2Minus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(5.0, split2Minus.getStart(1), 1.0e-10);
+        Assert.assertEquals(6.0, split2Minus.getEnd(1), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split3 = s35.split(s16.getHyperplane());
+        SubChord split3Plus  = (SubChord) split3.getPlus();
+        SubChord split3Minus = (SubChord) split3.getMinus();
+        Assert.assertNull(split3Plus);
+        Assert.assertEquals(2.0, split3Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split3Minus.getNbSubArcs());
+        Assert.assertEquals(3.0, split3Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split3Minus.getEnd(0), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split4 = s35.split(s16.getHyperplane().getReverse());
+        SubChord split4Plus  = (SubChord) split4.getPlus();
+        SubChord split4Minus = (SubChord) split4.getMinus();
+        Assert.assertEquals(2.0, split4Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split4Plus.getNbSubArcs());
+        Assert.assertEquals(3.0, split4Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split4Plus.getEnd(0), 1.0e-10);
+        Assert.assertNull(split4Minus);
+
+    }
+
+    @Test
+    public void testSplitOverlapping() {
+
+        SubChord s35 = new SubChord(new Chord(3.0, 5.0, 1.0e-10));
+        SubChord s46 = new SubChord(new Chord(4.0, 6.0, 1.0e-10));
+
+        SplitSubHyperplane<Sphere1D> split1 = s46.split(s35.getHyperplane());
+        SubChord split1Plus  = (SubChord) split1.getPlus();
+        SubChord split1Minus = (SubChord) split1.getMinus();
+        Assert.assertEquals(1.0, split1Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split1Plus.getNbSubArcs());
+        Assert.assertEquals(5.0, split1Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(6.0, split1Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(1.0, split1Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split1Minus.getNbSubArcs());
+        Assert.assertEquals(4.0, split1Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split1Minus.getEnd(0), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split2 = s46.split(s35.getHyperplane().getReverse());
+        SubChord split2Plus  = (SubChord) split2.getPlus();
+        SubChord split2Minus = (SubChord) split2.getMinus();
+        Assert.assertEquals(1.0, split2Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split2Plus.getNbSubArcs());
+        Assert.assertEquals(4.0, split2Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split2Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(1.0, split2Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split2Minus.getNbSubArcs());
+        Assert.assertEquals(5.0, split2Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(6.0, split2Minus.getEnd(0), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split3 = s35.split(s46.getHyperplane());
+        SubChord split3Plus  = (SubChord) split3.getPlus();
+        SubChord split3Minus = (SubChord) split3.getMinus();
+        Assert.assertEquals(1.0, split3Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split3Plus.getNbSubArcs());
+        Assert.assertEquals(3.0, split3Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(4.0, split3Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(1.0, split3Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split3Minus.getNbSubArcs());
+        Assert.assertEquals(4.0, split3Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split3Minus.getEnd(0), 1.0e-10);
+
+        SplitSubHyperplane<Sphere1D> split4 = s35.split(s46.getHyperplane().getReverse());
+        SubChord split4Plus  = (SubChord) split4.getPlus();
+        SubChord split4Minus = (SubChord) split4.getMinus();
+        Assert.assertEquals(1.0, split4Plus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split4Plus.getNbSubArcs());
+        Assert.assertEquals(4.0, split4Plus.getStart(0), 1.0e-10);
+        Assert.assertEquals(5.0, split4Plus.getEnd(0), 1.0e-10);
+        Assert.assertEquals(1.0, split4Minus.getSize(), 1.0e-10);
+        Assert.assertEquals(1,   split4Minus.getNbSubArcs());
+        Assert.assertEquals(3.0, split4Minus.getStart(0), 1.0e-10);
+        Assert.assertEquals(4.0, split4Minus.getEnd(0), 1.0e-10);
+
+    }
+
+    @Test
+    public void testReunite() {
+
+        // build sub-chord with arcs: [0.5, 1.375], [1.5, 1.75], [2.25, 4.5]
+        SubChord sA1 = new SubChord(new Chord(0.5, 4.5, 1.0e-10));
+        SubChord sA2 = (SubChord) sA1.split(new Chord(1.375, 1.5, 1.0e-10)).getPlus();
+        SubChord sA  = (SubChord) sA2.split(new Chord(1.75, 2.25, 1.0e-10)).getPlus();
+        List<Arc> listSa = sA.getSubArcs();
+        Assert.assertEquals(3, listSa.size());
+        Assert.assertEquals(0.5,   listSa.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(1.375, listSa.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(1.5,   listSa.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.75,  listSa.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(2.25,  listSa.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(4.5,   listSa.get(2).getSup(), 1.0e-10);
+
+        // sub-chord with arcs: [5.0, 5.5], [5.75, 1.0+2pi], [ 1.625+2pi, 1.875+2pi], [2.0+2pi, 2.125+2pi], [2.5+2pi, 3.5+2pi]
+        SubChord sB1 = new SubChord(new Chord(5.0, 3.5 + MathUtils.TWO_PI, 1.0e-10));
+        SubChord sB2 = (SubChord) sB1.split(new Chord(5.5, 5.75, 1.0e-10)).getPlus();
+        SubChord sB3 = (SubChord) sB2.split(new Chord(1.0 + MathUtils.TWO_PI, 1.625 + MathUtils.TWO_PI, 1.0e-10)).getPlus();
+        SubChord sB4 = (SubChord) sB3.split(new Chord(1.875 + MathUtils.TWO_PI, 2.0 + MathUtils.TWO_PI, 1.0e-10)).getPlus();
+        SubChord sB  = (SubChord) sB4.split(new Chord(2.125 + MathUtils.TWO_PI, 2.5 + MathUtils.TWO_PI, 1.0e-10)).getPlus();
+        List<Arc> listSb = sB.getSubArcs();
+        Assert.assertEquals(5, listSb.size());
+        Assert.assertEquals(5.0,                       listSb.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.5,                       listSb.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(5.75,                      listSb.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.0   + MathUtils.TWO_PI,  listSb.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(1.625 + MathUtils.TWO_PI,  listSb.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(1.875 + MathUtils.TWO_PI,  listSb.get(2).getSup(), 1.0e-10);
+        Assert.assertEquals(2.0   + MathUtils.TWO_PI,  listSb.get(3).getInf(), 1.0e-10);
+        Assert.assertEquals(2.125 + MathUtils.TWO_PI,  listSb.get(3).getSup(), 1.0e-10);
+        Assert.assertEquals(2.5   + MathUtils.TWO_PI,  listSb.get(4).getInf(), 1.0e-10);
+        Assert.assertEquals(3.5   + MathUtils.TWO_PI,  listSb.get(4).getSup(), 1.0e-10);
+
+        List<Arc> listAB = sA.reunite(sB).getSubArcs();
+        Assert.assertEquals(5, listAB.size());
+        Assert.assertEquals(5.75 - MathUtils.TWO_PI,   listAB.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(1.375,                     listAB.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(1.5,                       listAB.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.875,                     listAB.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(2.0,                       listAB.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(2.125,                     listAB.get(2).getSup(), 1.0e-10);
+        Assert.assertEquals(2.25,                      listAB.get(3).getInf(), 1.0e-10);
+        Assert.assertEquals(4.5,                       listAB.get(3).getSup(), 1.0e-10);
+        Assert.assertEquals(5.0,                       listAB.get(4).getInf(), 1.0e-10);
+        Assert.assertEquals(5.5,                       listAB.get(4).getSup(), 1.0e-10);
+
+        List<Arc> listBA  = sB.reunite(sA).getSubArcs();
+        Assert.assertEquals(5, listBA.size());
+        Assert.assertEquals(5.0,                       listBA.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(5.5,                       listBA.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(5.75,                      listBA.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.375 + MathUtils.TWO_PI,  listBA.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(1.5   + MathUtils.TWO_PI,  listBA.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(1.875 + MathUtils.TWO_PI,  listBA.get(2).getSup(), 1.0e-10);
+        Assert.assertEquals(2.0   + MathUtils.TWO_PI,  listBA.get(3).getInf(), 1.0e-10);
+        Assert.assertEquals(2.125 + MathUtils.TWO_PI,  listBA.get(3).getSup(), 1.0e-10);
+        Assert.assertEquals(2.25  + MathUtils.TWO_PI,  listBA.get(4).getInf(), 1.0e-10);
+        Assert.assertEquals(4.5   + MathUtils.TWO_PI,  listBA.get(4).getSup(), 1.0e-10);
+
+        // special cases
+        List<Arc> listAEmpty  = sA.reunite(new SubChord(new Chord(0, 0, 1.0e-10))).getSubArcs();
+        Assert.assertEquals(3, listAEmpty.size());
+        Assert.assertEquals(0.5,   listAEmpty.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(1.375, listAEmpty.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(1.5,   listAEmpty.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.75,  listAEmpty.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(2.25,  listAEmpty.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(4.5,   listAEmpty.get(2).getSup(), 1.0e-10);
+        
+        List<Arc> listEmptyA  = new SubChord(new Chord(0, 0, 1.0e-10)).reunite(sA).getSubArcs();
+        Assert.assertEquals(3, listAEmpty.size());
+        Assert.assertEquals(0.5,   listEmptyA.get(0).getInf(), 1.0e-10);
+        Assert.assertEquals(1.375, listEmptyA.get(0).getSup(), 1.0e-10);
+        Assert.assertEquals(1.5,   listEmptyA.get(1).getInf(), 1.0e-10);
+        Assert.assertEquals(1.75,  listEmptyA.get(1).getSup(), 1.0e-10);
+        Assert.assertEquals(2.25,  listEmptyA.get(2).getInf(), 1.0e-10);
+        Assert.assertEquals(4.5,   listEmptyA.get(2).getSup(), 1.0e-10);
+        
+    }
+
+    @Test
+    public void testReuniteFullCircle() {
+        SubChord s1 = new SubChord(new Chord(0, 4, 1.0e-10));
+        SubChord s2 = new SubChord(new Chord(3, 7, 1.0e-10));
+        Assert.assertEquals(MathUtils.TWO_PI, s1.reunite(s2).getSize(), 1.0e-10);
+    }
+
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"