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:30:58 UTC
svn commit: r1554656 - in /commons/proper/math/trunk/src:
main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.java
test/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSetTest.java
Author: luc
Date: Wed Jan 1 17:30:58 2014
New Revision: 1554656
URL: http://svn.apache.org/r1554656
Log:
Finalized 1-sphere.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/ArcsSet.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/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=1554656&r1=1554655&r2=1554656&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:30:58 2014
@@ -18,14 +18,13 @@ 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.exception.MathInternalError;
import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
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;
@@ -171,19 +170,6 @@ public class ArcsSet extends AbstractReg
return tolerance;
}
- /** Get the smallest internal node.
- * @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)
- */
- public LimitAngle getSmallestLimit() {
- final BSPTree<Sphere1D> first = getFirstArcStart();
- if (first == null) {
- return null;
- } else {
- return (LimitAngle) first.getCut().getHyperplane();
- }
- }
-
/** 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)
@@ -373,7 +359,7 @@ public class ArcsSet extends AbstractReg
* @return child node just before the internal node
*/
private BSPTree<Sphere1D> childBefore(BSPTree<Sphere1D> node) {
- if (((LimitAngle) node.getCut().getHyperplane()).isDirect()) {
+ if (isDirect(node)) {
// smaller angles are on minus side, larger angles are on plus side
return node.getMinus();
} else {
@@ -387,7 +373,7 @@ public class ArcsSet extends AbstractReg
* @return child node just after the internal node
*/
private BSPTree<Sphere1D> childAfter(BSPTree<Sphere1D> node) {
- if (((LimitAngle) node.getCut().getHyperplane()).isDirect()) {
+ if (isDirect(node)) {
// smaller angles are on minus side, larger angles are on plus side
return node.getPlus();
} else {
@@ -396,6 +382,22 @@ public class ArcsSet extends AbstractReg
}
}
+ /** Check if an internal node has a direct limit angle.
+ * @param node node to check
+ * @return true if the limit angle is direct
+ */
+ private boolean isDirect(final BSPTree<Sphere1D> node) {
+ return ((LimitAngle) node.getCut().getHyperplane()).isDirect();
+ }
+
+ /** Get the limit angle of a node.
+ * @param node node to check
+ * @return true if the limit angle is direct
+ */
+ private double getAngle(final BSPTree<Sphere1D> node) {
+ return ((LimitAngle) node.getCut().getHyperplane()).getLocation().getAlpha();
+ }
+
/** {@inheritDoc} */
@Override
public ArcsSet buildNew(final BSPTree<Sphere1D> tree) {
@@ -437,80 +439,65 @@ public class ArcsSet extends AbstractReg
public List<Arc> asList() {
final List<Arc> list = new ArrayList<Arc>();
- final BSPTree<Sphere1D> root = getTree(false);
+ final BSPTree<Sphere1D> firstStart = getFirstArcStart();
- 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, tolerance)); // since lower == upper, the arc covers the full circle
- }
+ if (firstStart == null) {
+ // the tree has a single node
+ if ((Boolean) getTree(false).getAttribute()) {
+ // it is an inside node, it represents the full circle
+ list.add(new Arc(0.0, 0.0, tolerance)); // since lower == upper, the arc covers the full circle
+ }
+ } else if (previousNode(firstStart) == null && nextNode(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
+ list.add(new Arc(0.0, 0.0, tolerance)); // 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();
- if (limits.size() < 2) {
- // the start and end angle collapsed to the same value, its the full circle again
- list.add(new Arc(0.0, 0.0, tolerance)); // since lower == upper, the arc covers the full circle
- return list;
- }
+ // find all arcs
+ BSPTree<Sphere1D> start = firstStart;
+ while (start != null) {
+
+ // look for the end of the current arc
+ BSPTree<Sphere1D> end = start;
+ while (end != null && !isArcEnd(end)) {
+ end = nextNode(end);
+ }
+
+ if (end != null) {
+
+ // we have identified the current arc
+ list.add(new Arc(getAngle(start), getAngle(end), tolerance));
+
+ // prepare search for next arc
+ start = end;
+ while (start != null && !isArcStart(start)) {
+ start = nextNode(start);
+ }
+
+ } else {
+ // the final arc wraps around 2\pi, its end is before the first start
+ end = firstStart;
+ while (end != null && !isArcEnd(end)) {
+ end = previousNode(end);
+ }
+ if (end == null) {
+ // this should never happen
+ throw new MathInternalError();
+ }
- // 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 have identified the last arc
+ list.add(new Arc(getAngle(start), getAngle(end) + MathUtils.TWO_PI, tolerance));
- // 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), tolerance));
- }
-
- }
-
- return list;
-
- }
+ // stop the loop
+ start = null;
- /** 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 LimitAngle limit = (LimitAngle) node.getCut().getHyperplane();
- if (checkPoint(limit.getLocation()) == Location.BOUNDARY) {
- limits.add(limit.getLocation().getAlpha());
}
- }
- /** {@inheritDoc} */
- public void visitLeafNode(final BSPTree<Sphere1D> node) {
}
- /** Get the collected limits.
- * @return collected limits
- */
- public List<Double> getLimits() {
- return limits;
- }
+ return list;
}
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=1554656&r1=1554655&r2=1554656&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 Wed Jan 1 17:30:58 2014
@@ -46,8 +46,6 @@ public class ArcsSetTest {
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(2.3, set.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
- Assert.assertFalse(set.getSmallestLimit().isDirect());
}
@Test
@@ -64,8 +62,6 @@ public class ArcsSetTest {
Assert.assertEquals(1, set.asList().size());
Assert.assertEquals(5.7, set.asList().get(0).getInf(), 1.0e-10);
Assert.assertEquals(2.3 + MathUtils.TWO_PI, set.asList().get(0).getSup(), 1.0e-10);
- Assert.assertEquals(5.7, set.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
- Assert.assertFalse(set.getSmallestLimit().isDirect());
}
@Test(expected=NumberIsTooLargeException.class)
@@ -77,7 +73,6 @@ public class ArcsSetTest {
public void testFullEqualEndPoints() {
ArcsSet set = new ArcsSet(1.0, 1.0, 1.0e-10);
Assert.assertEquals(1.0e-10, set.getTolerance(), 1.0e-20);
- Assert.assertNull(set.getSmallestLimit());
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)));
@@ -92,7 +87,6 @@ public class ArcsSetTest {
public void testFullCircle() {
ArcsSet set = new ArcsSet(1.0e-10);
Assert.assertEquals(1.0e-10, set.getTolerance(), 1.0e-20);
- Assert.assertNull(set.getSmallestLimit());
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)));
@@ -109,7 +103,6 @@ public class ArcsSetTest {
Assert.assertEquals(1.0e-10, empty.getTolerance(), 1.0e-20);
Assert.assertEquals(0.0, empty.getSize(), 1.0e-10);
Assert.assertTrue(empty.asList().isEmpty());
- Assert.assertNull(empty.getSmallestLimit());
}
@Test
@@ -120,7 +113,6 @@ public class ArcsSetTest {
Assert.assertEquals(1, tiny.asList().size());
Assert.assertEquals(0.0, tiny.asList().get(0).getInf(), 1.0e-10);
Assert.assertEquals(Precision.SAFE_MIN / 2, tiny.asList().get(0).getSup(), 1.0e-10);
- Assert.assertEquals(0.0, tiny.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
}
@Test
@@ -134,8 +126,6 @@ public class ArcsSetTest {
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);
- Assert.assertEquals(0.0, set.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
- Assert.assertFalse(set.getSmallestLimit().isDirect());
}
@Test