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:07 UTC
svn commit: r1554654 - in /commons/proper/math/trunk/src:
main/java/org/apache/commons/math3/geometry/spherical/oned/
main/java/org/apache/commons/math3/geometry/spherical/twod/
test/java/org/apache/commons/math3/geometry/spherical/oned/
Author: luc
Date: Wed Jan 1 17:30:06 2014
New Revision: 1554654
URL: http://svn.apache.org/r1554654
Log:
Simplified 1-sphere case.
Added:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java (contents, props changed)
- copied, changed from r1554653, commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Chord.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java (with props)
Removed:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Chord.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubChord.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ChordTest.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/SubChordTest.java
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/S1Point.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/Circle.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SubCircle.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.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/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=1554654&r1=1554653&r2=1554654&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:30:06 2014
@@ -16,6 +16,8 @@
*/
package org.apache.commons.math3.geometry.spherical.oned;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
+import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.geometry.partitioning.Region.Location;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.MathUtils;
@@ -38,38 +40,54 @@ public class Arc {
/** Middle point of the arc. */
private final double middle;
+ /** Tolerance below which angles are considered identical. */
+ private final double tolerance;
+
/** Simple constructor.
* <p>
- * As the circle is a closed curve, {@code lower} is
- * allowed to be greater than {@code upper}, and will
- * be automatically canonicalized so the arc wraps
- * around \( 2\pi \), but without exceeding a total
- * length of \( 2\pi \). If {@code lower} is equals
- * to {@code upper}, the arc is considered to be the full
- * circle.
+ * If either {@code lower} is equals to {@code upper} or
+ * the interval exceeds \( 2 \pi \), the arc is considered
+ * to be the full circle and its initial defining boundaries
+ * will be forgotten. {@code lower} is not allowed to be
+ * greater than {@code upper} (an exception is thrown in this case).
+ * {@code lower} will be canonicalized between 0 and \( 2 \pi \), and
+ * upper shifted accordingly, so the {@link #getInf()} and {@link #getSup()}
+ * may not return the value used at instance construction.
* </p>
* @param lower lower angular bound of the arc
* @param upper upper angular bound of the arc
+ * @param tolerance tolerance below which angles are considered identical
+ * @exception NumberIsTooLargeException if lower is greater than upper
*/
- public Arc(final double lower, final double upper) {
- this.lower = lower;
- if (Precision.equals(lower, upper, 0)) {
- this.upper = MathUtils.TWO_PI + lower;
+ public Arc(final double lower, final double upper, final double tolerance)
+ throws NumberIsTooLargeException {
+ this.tolerance = tolerance;
+ if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) {
+ // the arc must cover the whole circle
+ this.lower = 0;
+ this.upper = MathUtils.TWO_PI;
+ this.middle = FastMath.PI;
+ } else if (lower <= upper) {
+ this.lower = MathUtils.normalizeAngle(lower, FastMath.PI);
+ this.upper = this.lower + (upper - lower);
+ this.middle = 0.5 * (this.lower + this.upper);
} else {
- this.upper = MathUtils.normalizeAngle(upper, lower + FastMath.PI);
+ throw new NumberIsTooLargeException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+ lower, upper, true);
}
- this.middle = 0.5 * (this.lower + this.upper);
}
/** Get the lower angular bound of the arc.
- * @return lower angular bound of the arc
+ * @return lower angular bound of the arc,
+ * always between 0 and \( 2 \pi \)
*/
public double getInf() {
return lower;
}
/** Get the upper angular bound of the arc.
- * @return upper angular bound of the arc
+ * @return upper angular bound of the arc,
+ * always between {@link #getInf()} and {@link #getInf()} \( + 2 \pi \)
*/
public double getSup() {
return upper;
@@ -89,14 +107,19 @@ public class Arc {
return middle;
}
+ /** Get the tolerance below which angles are considered identical.
+ * @return tolerance below which angles are considered identical
+ */
+ public double getTolerance() {
+ return tolerance;
+ }
+
/** Check a point with respect to the arc.
* @param point point to check
- * @param tolerance tolerance below which points are considered to
- * belong to the boundary
* @return a code representing the point status: either {@link
* Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY}
*/
- public Location checkPoint(final double point, final double tolerance) {
+ public Location checkPoint(final double point) {
final double normalizedPoint = MathUtils.normalizeAngle(point, middle);
if (normalizedPoint < lower - tolerance || normalizedPoint > upper + tolerance) {
return Location.OUTSIDE;
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=1554654&r1=1554653&r2=1554654&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:06 2014
@@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+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;
@@ -30,6 +32,13 @@ import org.apache.commons.math3.util.Mat
import org.apache.commons.math3.util.Precision;
/** This class represents a region of a circle: a set of arcs.
+ * <p>
+ * Note that due to the wrapping around \(2 \pi\), barycenter is
+ * ill-defined here. It was defined only in order to fulfill
+ * the requirements of the {@link
+ * org.apache.commons.math3.geometry.partitioning.Region Region}
+ * interface, but its use is discouraged.
+ * </p>
* @version $Id$
* @since 3.3
*/
@@ -47,19 +56,19 @@ public class ArcsSet extends AbstractReg
/** Build an arcs set corresponding to a single arc.
* <p>
- * As the circle is a closed curve, {@code lower} is
- * allowed to be greater than {@code upper}, and will
- * be automatically canonicalized so the arc wraps
- * around \( 2\pi \), but without exceeding a total
- * length of \( 2\pi \). If {@code lower} is equals
- * to {@code upper}, the arc is considered to be the full
- * circle.
+ * If either {@code lower} is equals to {@code upper} or
+ * the interval exceeds \( 2 \pi \), the arc is considered
+ * to be the full circle and its initial defining boundaries
+ * will be forgotten. {@code lower} is not allowed to be greater
+ * than {@code upper} (an exception is thrown in this case).
* </p>
* @param lower lower bound of the arc
* @param upper upper bound of the arc
* @param tolerance tolerance below which close sub-arcs are merged together
+ * @exception NumberIsTooLargeException if lower is greater than upper
*/
- public ArcsSet(final double lower, final double upper, final double tolerance) {
+ public ArcsSet(final double lower, final double upper, final double tolerance)
+ throws NumberIsTooLargeException {
super(buildTree(lower, upper, tolerance));
this.tolerance = tolerance;
}
@@ -105,33 +114,236 @@ public class ArcsSet extends AbstractReg
}
/** Build an inside/outside tree representing a single arc.
- * <p>
- * As the circle is a closed curve, {@code lower} is
- * allowed to be greater than {@code upper}, and will
- * be automatically canonicalized so the arc wraps
- * around \( 2\pi \), but without exceeding a total
- * length of \( 2\pi \). If {@code lower} is equals
- * to {@code upper}, the arc is considered to be the full
- * circle.
- * </p>
* @param lower lower angular bound of the arc
* @param upper upper angular bound of the arc
* @param tolerance tolerance below which close sub-arcs are merged together
* @return the built tree
+ * @exception NumberIsTooLargeException if lower is greater than upper
*/
- private static BSPTree<Sphere1D> buildTree(final double lower, final double upper, final double tolerance) {
+ private static BSPTree<Sphere1D> buildTree(final double lower, final double upper,
+ final double tolerance)
+ throws NumberIsTooLargeException {
- if (Precision.equals(lower, upper, 0)) {
- // the tree must cover the whole real line
+ if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) {
+ // the tree must cover the whole circle
return new BSPTree<Sphere1D>(Boolean.TRUE);
+ } else if (lower > upper) {
+ throw new NumberIsTooLargeException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+ lower, upper, true);
+ }
+
+ // this is a regular arc, covering only part of the circle
+ final double normalizedLower = MathUtils.normalizeAngle(lower, FastMath.PI);
+ final double normalizedUpper = normalizedLower + (upper - lower);
+ final SubHyperplane<Sphere1D> lowerCut =
+ new LimitAngle(new S1Point(normalizedLower), false, tolerance).wholeHyperplane();
+
+ if (normalizedUpper <= MathUtils.TWO_PI) {
+ // simple arc starting after 0 and ending before 2 \pi
+ final SubHyperplane<Sphere1D> upperCut =
+ new LimitAngle(new S1Point(normalizedUpper), true, tolerance).wholeHyperplane();
+ return new BSPTree<Sphere1D>(lowerCut,
+ new BSPTree<Sphere1D>(Boolean.FALSE),
+ new BSPTree<Sphere1D>(upperCut,
+ new BSPTree<Sphere1D>(Boolean.FALSE),
+ new BSPTree<Sphere1D>(Boolean.TRUE),
+ null),
+ null);
+ } else {
+ // arc wrapping around 2 \pi
+ final SubHyperplane<Sphere1D> upperCut =
+ new LimitAngle(new S1Point(normalizedUpper - MathUtils.TWO_PI), true, tolerance).wholeHyperplane();
+ return new BSPTree<Sphere1D>(lowerCut,
+ new BSPTree<Sphere1D>(upperCut,
+ new BSPTree<Sphere1D>(Boolean.FALSE),
+ new BSPTree<Sphere1D>(Boolean.TRUE),
+ null),
+ new BSPTree<Sphere1D>(Boolean.TRUE),
+ null);
+ }
+
+ }
+
+ /** Get the tolerance below which angles are considered identical.
+ * @return tolerance below which angles are considered identical
+ */
+ public double getTolerance() {
+ 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() {
+
+ // start search at the tree root
+ BSPTree<Sphere1D> node = getTree(false);
+ if (node.getCut() == null) {
+ return null;
+ }
+
+ BSPTree<Sphere1D> previous = previousNode(node);
+ while (previous != null) {
+ node = previous;
+ previous = previousNode(node);
+ }
+
+ return (LimitAngle) node.getCut().getHyperplane();
+
+ }
+
+ /** Get the largest limit angle in the set.
+ * @return largest limit angle (i.e. last before or at \(2 \pi) radians, in trigonometric direction),
+ * or null if there are no limits (i.e. the set is either empty or covers the full circle)
+ */
+ public LimitAngle getLargestLimit() {
+
+ // start search at the tree root
+ BSPTree<Sphere1D> node = getTree(false);
+ if (node.getCut() == null) {
+ return null;
+ }
+
+ BSPTree<Sphere1D> next = nextNode(node);
+ while (next != null) {
+ node = next;
+ next = nextNode(node);
}
- // the two boundary angles define only one cutting chord
- final double normalizedUpper = MathUtils.normalizeAngle(upper, lower + FastMath.PI);
- return new BSPTree<Sphere1D>(new Chord(lower, normalizedUpper, tolerance).wholeHyperplane(),
- new BSPTree<Sphere1D>(Boolean.FALSE),
- new BSPTree<Sphere1D>(Boolean.TRUE),
- null);
+ return (LimitAngle) node.getCut().getHyperplane();
+
+ }
+
+ /** Get the next internal node.
+ * @param node current node
+ * @return next internal node in trigonometric order, or null
+ * if this is the last internal node
+ */
+ private BSPTree<Sphere1D> nextNode(BSPTree<Sphere1D> node) {
+
+ final BSPTree<Sphere1D> nextDeeper =
+ ((LimitAngle) node.getCut().getHyperplane()).isDirect() ?
+ node.getPlus() : node.getMinus();
+
+ if (nextDeeper.getCut() != null) {
+ // the next node is in the sub-tree
+ return findSmallest(nextDeeper);
+ }
+
+ // there is nothing left deeper in the tree, we backtrack
+ while (isAfterParent(node)) {
+ node = node.getParent();
+ }
+ return node.getParent();
+
+ }
+
+ /** Get the previous internal node.
+ * @param node current node
+ * @return previous internal node in trigonometric order, or null
+ * if this is the first internal node
+ */
+ private BSPTree<Sphere1D> previousNode(BSPTree<Sphere1D> node) {
+
+ final BSPTree<Sphere1D> nextDeeper =
+ ((LimitAngle) node.getCut().getHyperplane()).isDirect() ?
+ node.getMinus() : node.getPlus();
+
+ if (nextDeeper.getCut() != null) {
+ // the next node is in the sub-tree
+ return findLargest(nextDeeper);
+ }
+
+ // there is nothing left deeper in the tree, we backtrack
+ while (isBeforeParent(node)) {
+ node = node.getParent();
+ }
+ return node.getParent();
+
+ }
+
+ /** Check if a node is the child before its parent in trigonometric order.
+ * @param node child node considered
+ * @return true is the node has a parent end is before it in trigonometric order
+ */
+ private boolean isBeforeParent(final BSPTree<Sphere1D> node) {
+ final BSPTree<Sphere1D> parent = node.getParent();
+ if (parent == null) {
+ return false;
+ }
+ if (((LimitAngle) parent.getCut().getHyperplane()).isDirect()) {
+ // smaller angles are on minus side, larger angles are on plus side
+ return node == parent.getMinus();
+ } else {
+ // smaller angles are on plus side, larger angles are on minus side
+ return node == parent.getPlus();
+ }
+ }
+
+ /** Check if a node is the child after its parent in trigonometric order.
+ * @param node child node considered
+ * @return true is the node has a parent end is after it in trigonometric order
+ */
+ private boolean isAfterParent(final BSPTree<Sphere1D> node) {
+ final BSPTree<Sphere1D> parent = node.getParent();
+ if (parent == null) {
+ return false;
+ }
+ if (((LimitAngle) parent.getCut().getHyperplane()).isDirect()) {
+ // smaller angles are on minus side, larger angles are on plus side
+ return node == parent.getPlus();
+ } else {
+ // smaller angles are on plus side, larger angles are on minus side
+ return node == parent.getMinus();
+ }
+ }
+
+ /** Find the smallest internal node in a sub-tree.
+ * @param node node at which the sub-tree starts
+ * @return smallest internal node (in trigonometric order), may be the
+ * provided node if no smaller internal node exist
+ */
+ private BSPTree<Sphere1D> findSmallest(BSPTree<Sphere1D> node) {
+
+ BSPTree<Sphere1D> internal = null;
+
+ while (node.getCut() != null) {
+ internal = node;
+ if (((LimitAngle) node.getCut().getHyperplane()).isDirect()) {
+ // smaller angles are on minus side, larger angles are on plus side
+ node = node.getMinus();
+ } else {
+ // smaller angles are on plus side, larger angles are on minus side
+ node = node.getPlus();
+ }
+ }
+
+ return internal;
+
+ }
+
+ /** Find the largest internal node in a sub-tree.
+ * @param node node at which the sub-tree starts
+ * @return largest internal node (in trigonometric order), may be the
+ * provided node if no larger internal node exist
+ */
+ private BSPTree<Sphere1D> findLargest(BSPTree<Sphere1D> node) {
+
+ BSPTree<Sphere1D> internal = null;
+
+ while (node.getCut() != null) {
+ internal = node;
+ if (((LimitAngle) node.getCut().getHyperplane()).isDirect()) {
+ // smaller angles are on minus side, larger angles are on plus side
+ node = node.getPlus();
+ } else {
+ // smaller angles are on plus side, larger angles are on minus side
+ node = node.getMinus();
+ }
+ }
+
+ return internal;
}
@@ -160,8 +372,8 @@ public class ArcsSet extends AbstractReg
} else if (size >= Precision.SAFE_MIN) {
setBarycenter(new S1Point(sum / size));
} else {
- final Chord chord = (Chord) getTree(false).getCut().getHyperplane();
- setBarycenter(new S1Point(0.5 * (chord.getStart() + chord.getEnd())));
+ final LimitAngle limit = (LimitAngle) getTree(false).getCut().getHyperplane();
+ setBarycenter(limit.getLocation());
}
}
}
@@ -182,7 +394,7 @@ public class ArcsSet extends AbstractReg
// 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
+ list.add(new Arc(0.0, 0.0, tolerance)); // since lower == upper, the arc covers the full circle
}
} else {
@@ -190,6 +402,11 @@ public class ArcsSet extends AbstractReg
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;
+ }
// sort them so the first angle is an arc start
Collections.sort(limits);
@@ -201,7 +418,7 @@ public class ArcsSet extends AbstractReg
// 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)));
+ list.add(new Arc(limits.get(i), limits.get(i + 1), tolerance));
}
}
@@ -229,12 +446,9 @@ public class ArcsSet extends AbstractReg
/** {@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));
- }
- if (checkPoint(new S1Point(chord.getEnd())) == Location.BOUNDARY) {
- limits.add(MathUtils.normalizeAngle(chord.getEnd(), FastMath.PI));
+ final LimitAngle limit = (LimitAngle) node.getCut().getHyperplane();
+ if (checkPoint(limit.getLocation()) == Location.BOUNDARY) {
+ limits.add(limit.getLocation().getAlpha());
}
}
Copied: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java (from r1554653, commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Chord.java)
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java?p2=commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java&p1=commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Chord.java&r1=1554653&r2=1554654&rev=1554654&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/Chord.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java Wed Jan 1 17:30:06 2014
@@ -18,43 +18,33 @@ package org.apache.commons.math3.geometr
import org.apache.commons.math3.geometry.Point;
import org.apache.commons.math3.geometry.partitioning.Hyperplane;
-import org.apache.commons.math3.util.FastMath;
-import org.apache.commons.math3.util.MathUtils;
/** This class represents a 1D oriented hyperplane on the circle.
- * <p>An hyperplane on the 1-sphere is a chord that splits
- * the circle in two parts.</p>
+ * <p>An hyperplane on the 1-sphere is an angle with an orientation.</p>
* <p>Instances of this class are guaranteed to be immutable.</p>
* @version $Id$
* @since 3.3
*/
-public class Chord implements Hyperplane<Sphere1D> {
+public class LimitAngle implements Hyperplane<Sphere1D> {
- /** Start angle of the chord. */
- private final double start;
+ /** Angle location. */
+ private S1Point location;
- /** End angle of the chord. */
- private final double end;
+ /** Orientation. */
+ private boolean direct;
- /** Cosine of the half aperture. */
- private final double cos;
-
- /** Middle point of the chord. */
- private final S1Point middle;
-
- /** Tolerance below which close sub-arcs are merged together. */
+ /** Tolerance below which angles are considered identical. */
private final double tolerance;
/** Simple constructor.
- * @param start start angle of the chord
- * @param end end angle of the chord
- * @param tolerance tolerance below which close sub-arcs are merged together
- */
- public Chord(final double start, final double end, final double tolerance) {
- this.start = start;
- this.end = end;
- this.middle = new S1Point(0.5 * (start + end));
- this.cos = FastMath.cos(0.5 * (end - start));
+ * @param location location of the hyperplane
+ * @param direct if true, the plus side of the hyperplane is towards
+ * angles greater than {@code location}
+ * @param tolerance tolerance below which angles are considered identical
+ */
+ public LimitAngle(final S1Point location, final boolean direct, final double tolerance) {
+ this.location = location;
+ this.direct = direct;
this.tolerance = tolerance;
}
@@ -63,22 +53,31 @@ public class Chord implements Hyperplane
* the instance.</p>
* @return the instance itself
*/
- public Chord copySelf() {
+ public LimitAngle copySelf() {
return this;
}
/** {@inheritDoc} */
public double getOffset(final Point<Sphere1D> point) {
- return cos - middle.getVector().dotProduct(((S1Point) point).getVector());
+ final double delta = ((S1Point) point).getAlpha()- location.getAlpha();
+ return direct ? delta : -delta;
+ }
+
+ /** Check if the hyperplane orientation is direct.
+ * @return true if the plus side of the hyperplane is towards
+ * angles greater than hyperplane location
+ */
+ public boolean isDirect() {
+ return direct;
}
/** Get the reverse of the instance.
- * <p>Get a chord with reversed orientation with respect to the
+ * <p>Get a limit angle with reversed orientation with respect to the
* instance. A new object is built, the instance is untouched.</p>
- * @return a new chord, with orientation opposite to the instance orientation
+ * @return a new limit angle, with orientation opposite to the instance orientation
*/
- public Chord getReverse() {
- return new Chord(end, MathUtils.normalizeAngle(start, end + FastMath.PI), tolerance);
+ public LimitAngle getReverse() {
+ return new LimitAngle(location, !direct, tolerance);
}
/** Build a region covering the whole hyperplane.
@@ -92,8 +91,8 @@ public class Chord implements Hyperplane
* <em>not</em> be used otherwise.</p>
* @return a dummy sub hyperplane
*/
- public SubChord wholeHyperplane() {
- return new SubChord(this);
+ public SubLimitAngle wholeHyperplane() {
+ return new SubLimitAngle(this, null);
}
/** Build a region covering the whole space.
@@ -106,25 +105,18 @@ public class Chord implements Hyperplane
/** {@inheritDoc} */
public boolean sameOrientationAs(final Hyperplane<Sphere1D> other) {
- return middle.getVector().dotProduct(((Chord) other).middle.getVector()) >= 0.0;
- }
-
- /** Get the start angle of the chord.
- * @return start angle of the chord.
- */
- public double getStart() {
- return start;
+ return !(direct ^ ((LimitAngle) other).direct);
}
- /** Get the end angle of the chord.
- * @return end angle of the chord.
+ /** Get the hyperplane location on the circle.
+ * @return the hyperplane location
*/
- public double getEnd() {
- return end;
+ public S1Point getLocation() {
+ return location;
}
- /** Get the tolerance below which close sub-arcs are merged together.
- * @return tolerance below which close sub-arcs are merged together
+ /** Get the tolerance below which angles are considered identical.
+ * @return tolerance below which angles are considered identical
*/
public double getTolerance() {
return tolerance;
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/LimitAngle.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/S1Point.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/S1Point.java?rev=1554654&r1=1554653&r2=1554654&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/S1Point.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/S1Point.java Wed Jan 1 17:30:06 2014
@@ -49,7 +49,8 @@ public class S1Point implements Point<Sp
* @see #getAlpha()
*/
public S1Point(final double alpha) {
- this(alpha, new Vector2D(FastMath.cos(alpha), FastMath.sin(alpha)));
+ this(MathUtils.normalizeAngle(alpha, FastMath.PI),
+ new Vector2D(FastMath.cos(alpha), FastMath.sin(alpha)));
}
/** Build a point from its internal components.
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java?rev=1554654&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java Wed Jan 1 17:30:06 2014
@@ -0,0 +1,74 @@
+/*
+ * 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.AbstractSubHyperplane;
+import org.apache.commons.math3.geometry.partitioning.Hyperplane;
+import org.apache.commons.math3.geometry.partitioning.Region;
+import org.apache.commons.math3.geometry.partitioning.Side;
+
+/** This class represents sub-hyperplane for {@link LimitAngle}.
+ * <p>Instances of this class are guaranteed to be immutable.</p>
+ * @version $Id$
+ * @since 3.3
+ */
+public class SubLimitAngle extends AbstractSubHyperplane<Sphere1D, Sphere1D> {
+
+ /** Simple constructor.
+ * @param hyperplane underlying hyperplane
+ * @param remainingRegion remaining region of the hyperplane
+ */
+ public SubLimitAngle(final Hyperplane<Sphere1D> hyperplane,
+ final Region<Sphere1D> remainingRegion) {
+ super(hyperplane, remainingRegion);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public double getSize() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected AbstractSubHyperplane<Sphere1D, Sphere1D> buildNew(final Hyperplane<Sphere1D> hyperplane,
+ final Region<Sphere1D> remainingRegion) {
+ return new SubLimitAngle(hyperplane, remainingRegion);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Side side(final Hyperplane<Sphere1D> hyperplane) {
+ final double global = hyperplane.getOffset(((LimitAngle) getHyperplane()).getLocation());
+ return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public SplitSubHyperplane<Sphere1D> split(final Hyperplane<Sphere1D> hyperplane) {
+ final double global = hyperplane.getOffset(((LimitAngle) getHyperplane()).getLocation());
+ return (global < -1.0e-10) ?
+ new SplitSubHyperplane<Sphere1D>(null, this) :
+ new SplitSubHyperplane<Sphere1D>(this, null);
+ }
+
+}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/oned/SubLimitAngle.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/Circle.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/Circle.java?rev=1554654&r1=1554653&r2=1554654&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/Circle.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/Circle.java Wed Jan 1 17:30:06 2014
@@ -23,8 +23,8 @@ import org.apache.commons.math3.geometry
import org.apache.commons.math3.geometry.partitioning.Hyperplane;
import org.apache.commons.math3.geometry.partitioning.SubHyperplane;
import org.apache.commons.math3.geometry.partitioning.Transform;
+import org.apache.commons.math3.geometry.spherical.oned.Arc;
import org.apache.commons.math3.geometry.spherical.oned.ArcsSet;
-import org.apache.commons.math3.geometry.spherical.oned.Chord;
import org.apache.commons.math3.geometry.spherical.oned.S1Point;
import org.apache.commons.math3.geometry.spherical.oned.Sphere1D;
import org.apache.commons.math3.util.FastMath;
@@ -223,15 +223,15 @@ public class Circle implements Hyperplan
return pole;
}
- /** Get the chord of the instance that lies inside the other circle.
+ /** Get the arc of the instance that lies inside the other circle.
* @param other other circle
- * @return chord of the instance that lies inside the other circle
+ * @return arc of the instance that lies inside the other circle
* (guaranteed to always have a length of \( \pi \))
*/
- public Chord getChord(final Circle other) {
+ public Arc getInsideArc(final Circle other) {
final double alpha = getPhase(other.pole);
final double halfPi = 0.5 * FastMath.PI;
- return new Chord(alpha - halfPi, alpha + halfPi, tolerance);
+ return new Arc(alpha - halfPi, alpha + halfPi, tolerance);
}
/** {@inheritDoc} */
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SubCircle.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SubCircle.java?rev=1554654&r1=1554653&r2=1554654&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SubCircle.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/spherical/twod/SubCircle.java Wed Jan 1 17:30:06 2014
@@ -22,6 +22,7 @@ import org.apache.commons.math3.geometry
import org.apache.commons.math3.geometry.partitioning.Region;
import org.apache.commons.math3.geometry.partitioning.Side;
import org.apache.commons.math3.geometry.partitioning.SubHyperplane;
+import org.apache.commons.math3.geometry.spherical.oned.Arc;
import org.apache.commons.math3.geometry.spherical.oned.ArcsSet;
import org.apache.commons.math3.geometry.spherical.oned.Chord;
import org.apache.commons.math3.geometry.spherical.oned.Sphere1D;
@@ -54,16 +55,8 @@ public class SubCircle extends AbstractS
final Circle thisCircle = (Circle) getHyperplane();
final Circle otherCircle = (Circle) hyperplane;
- final Chord chord = thisCircle.getChord(otherCircle);
-
- if (chord == null) {
- // the circles are disjoint
- final double global = otherCircle.getOffset(thisCircle.getXAxis());
- return (global < -1.0e-10) ? Side.MINUS : ((global > 1.0e-10) ? Side.PLUS : Side.HYPER);
- }
-
- // the circles do intersect each other
- return getRemainingRegion().side(chord);
+ final Arc arc = thisCircle.getInsideArc(otherCircle);
+ return ((ArcsSet) getRemainingRegion()).side(arc);
}
@@ -73,17 +66,8 @@ public class SubCircle extends AbstractS
final Circle thisCircle = (Circle) getHyperplane();
final Circle otherCircle = (Circle) hyperplane;
- final Chord chord = thisCircle.getChord(otherCircle);
-
- if (chord == null) {
- // the circles are disjoint
- final double global = otherCircle.getOffset(thisCircle.getXAxis());
- return (global < -1.0e-10) ?
- new SplitSubHyperplane<Sphere2D>(null, this) :
- new SplitSubHyperplane<Sphere2D>(this, null);
- }
+ final Arc arc = thisCircle.getInsideArc(otherCircle);
- // the circles do intersect
final SubHyperplane<Sphere1D> subMinus = chord.wholeHyperplane();
final SubHyperplane<Sphere1D> subPlus = chord.getReverse().wholeHyperplane();
final BSPTree<Sphere1D> splitTree = getRemainingRegion().getTree(false).split(subMinus);
Modified: 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=1554654&r1=1554653&r2=1554654&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/spherical/oned/ArcTest.java Wed Jan 1 17:30:06 2014
@@ -16,8 +16,10 @@
*/
package org.apache.commons.math3.geometry.spherical.oned;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.geometry.partitioning.Region;
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;
@@ -26,49 +28,52 @@ public class ArcTest {
@Test
public void testArc() {
- Arc arc = new Arc(2.3, 5.7);
+ Arc arc = new Arc(2.3, 5.7, 1.0e-10);
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(Region.Location.BOUNDARY, arc.checkPoint(2.3));
+ Assert.assertEquals(Region.Location.BOUNDARY, arc.checkPoint(5.7));
+ Assert.assertEquals(Region.Location.OUTSIDE, arc.checkPoint(1.2));
+ Assert.assertEquals(Region.Location.OUTSIDE, arc.checkPoint(8.5));
+ Assert.assertEquals(Region.Location.INSIDE, arc.checkPoint(8.7));
+ Assert.assertEquals(Region.Location.INSIDE, arc.checkPoint(3.0));
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(expected=NumberIsTooLargeException.class)
+ public void testWrongInterval() {
+ new Arc(1.2, 0.0, 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));
+ Assert.assertEquals(Region.Location.OUTSIDE, new Arc(2.3, 5.7, 1.0).checkPoint(1.2));
+ Assert.assertEquals(Region.Location.BOUNDARY, new Arc(2.3, 5.7, 1.2).checkPoint(1.2));
+ Assert.assertEquals(Region.Location.OUTSIDE, new Arc(2.3, 5.7, 0.7).checkPoint(6.5));
+ Assert.assertEquals(Region.Location.BOUNDARY, new Arc(2.3, 5.7, 0.9).checkPoint(6.5));
+ Assert.assertEquals(Region.Location.INSIDE, new Arc(2.3, 5.7, 0.6).checkPoint(3.0));
+ Assert.assertEquals(Region.Location.BOUNDARY, new Arc(2.3, 5.7, 0.8).checkPoint(3.0));
}
@Test
public void testFullCircle() {
- Arc arc = new Arc(9.0, 9.0);
+ Arc arc = new Arc(9.0, 9.0, 1.0e-10);
// 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(Region.Location.INSIDE, arc.checkPoint(9.0));
+ Assert.assertEquals(.0, arc.getInf(), 1.0e-10);
+ Assert.assertEquals(MathUtils.TWO_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));
+ Assert.assertEquals(Region.Location.INSIDE, arc.checkPoint(alpha));
}
}
@Test
public void testSmall() {
- Arc arc = new Arc(1.0, FastMath.nextAfter(1.0, Double.POSITIVE_INFINITY));
+ Arc arc = new Arc(1.0, FastMath.nextAfter(1.0, Double.POSITIVE_INFINITY), Precision.EPSILON);
Assert.assertEquals(2 * Precision.EPSILON, arc.getSize(), Precision.SAFE_MIN);
Assert.assertEquals(1.0, arc.getBarycenter(), Precision.EPSILON);
}
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=1554654&r1=1554653&r2=1554654&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:06 2014
@@ -16,11 +16,14 @@
*/
package org.apache.commons.math3.geometry.spherical.oned;
+import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.math3.exception.NumberIsTooLargeException;
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.geometry.partitioning.SubHyperplane;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.MathUtils;
import org.apache.commons.math3.util.Precision;
@@ -33,7 +36,7 @@ public class ArcsSetTest {
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(1.0e-10, set.getTolerance(), 1.0e-20);
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)));
@@ -43,13 +46,59 @@ 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(4.0, ((S1Point) set.getBarycenter()).getAlpha(), 1.0e-10);
- Assert.assertEquals(3.4, set.getSize(), 1.0e-10);
+ Assert.assertEquals(2.3, set.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
+ Assert.assertFalse(set.getSmallestLimit().isDirect());
+ Assert.assertEquals(5.7, set.getLargestLimit().getLocation().getAlpha(), 1.0e-10);
+ Assert.assertTrue(set.getLargestLimit().isDirect());
+ }
+
+ @Test
+ public void testWrapAround2PiArc() {
+ ArcsSet set = new ArcsSet(5.7 - MathUtils.TWO_PI, 2.3, 1.0e-10);
+ Assert.assertEquals(MathUtils.TWO_PI - 3.4, set.getSize(), 1.0e-10);
+ Assert.assertEquals(1.0e-10, set.getTolerance(), 1.0e-20);
+ 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.INSIDE, set.checkPoint(new S1Point(1.2)));
+ Assert.assertEquals(Region.Location.INSIDE, set.checkPoint(new S1Point(8.5)));
+ Assert.assertEquals(Region.Location.OUTSIDE, set.checkPoint(new S1Point(8.7)));
+ Assert.assertEquals(Region.Location.OUTSIDE, set.checkPoint(new S1Point(3.0)));
+ 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(2.3, set.getSmallestLimit().getLocation().getAlpha(), 1.0e-10);
+ Assert.assertTrue(set.getSmallestLimit().isDirect());
+ Assert.assertEquals(5.7, set.getLargestLimit().getLocation().getAlpha(), 1.0e-10);
+ Assert.assertFalse(set.getLargestLimit().isDirect());
+ }
+
+ @Test(expected=NumberIsTooLargeException.class)
+ public void testWrongInterval() {
+ new ArcsSet(1.2, 0.0, 1.0e-10);
+ }
+
+ @Test
+ 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.assertNull(set.getLargestLimit());
+ 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 testFullCircle() {
- ArcsSet set = new ArcsSet(9.0, 9.0, 1.0e-10);
+ ArcsSet set = new ArcsSet(1.0e-10);
+ Assert.assertEquals(1.0e-10, set.getTolerance(), 1.0e-20);
+ Assert.assertNull(set.getSmallestLimit());
+ Assert.assertNull(set.getLargestLimit());
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)));
@@ -61,6 +110,44 @@ public class ArcsSetTest {
}
@Test
+ public void testEmpty() {
+ ArcsSet empty = (ArcsSet) new RegionFactory<Sphere1D>().getComplement(new ArcsSet(1.0e-10));
+ 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());
+ Assert.assertNull(empty.getLargestLimit());
+ }
+
+ @Test
+ public void testTiny() {
+ ArcsSet tiny = new ArcsSet(0.0, Precision.SAFE_MIN / 2, 1.0e-10);
+ Assert.assertEquals(1.0e-10, tiny.getTolerance(), 1.0e-20);
+ Assert.assertEquals(Precision.SAFE_MIN / 2, tiny.getSize(), 1.0e-10);
+ 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);
+ Assert.assertEquals(Precision.SAFE_MIN / 2, tiny.getLargestLimit().getLocation().getAlpha(), 1.0e-10);
+ }
+
+ @Test
+ 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());
+ 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);
+ 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());
+ Assert.assertEquals(0.0, set.getLargestLimit().getLocation().getAlpha(), 1.0e-10);
+ }
+
+ @Test
public void testDifference() {
ArcsSet a = new ArcsSet(1.0, 6.0, 1.0e-10);
@@ -139,9 +226,11 @@ public class ArcsSetTest {
}
List<Arc> aMbList = aMb.asList();
- Assert.assertEquals(1, aMbList.size());
+ 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(5.5, aMbList.get(1).getSup(), 1.0e-10);
}
@@ -155,7 +244,6 @@ public class ArcsSetTest {
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)));
@@ -179,7 +267,6 @@ public class ArcsSetTest {
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);
}
}