Fixed an error introduced by a wrong fix...
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1557609 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
bb2dc86de1
commit
0f13370f35
|
@ -394,7 +394,7 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
|
|||
* <p>The filtering consist in splitting the specified
|
||||
* sub-hyperplane into several parts lying in inside and outside
|
||||
* cells of the tree. The principle is to call this method twice for
|
||||
* each cut sub-hyperplane in the tree, once one the plus node and
|
||||
* each cut sub-hyperplane in the tree, once on the plus node and
|
||||
* once on the minus node. The parts that have the same flag
|
||||
* (inside/inside or outside/outside) do not belong to the boundary
|
||||
* while parts that have different flags (inside/outside or
|
||||
|
|
|
@ -667,10 +667,8 @@ public class ArcsSet extends AbstractRegion<Sphere1D, Sphere1D> implements Itera
|
|||
|
||||
final BSPTree<Sphere1D> minus = new BSPTree<Sphere1D>();
|
||||
minus.setAttribute(Boolean.FALSE);
|
||||
boolean minusIgnored = false;
|
||||
final BSPTree<Sphere1D> plus = new BSPTree<Sphere1D>();
|
||||
plus.setAttribute(Boolean.FALSE);
|
||||
boolean plusIgnored = false;
|
||||
|
||||
final double reference = FastMath.PI + arc.getInf();
|
||||
final double arcLength = arc.getSup() - arc.getInf();
|
||||
|
@ -681,146 +679,90 @@ public class ArcsSet extends AbstractRegion<Sphere1D, Sphere1D> implements Itera
|
|||
final double syncedEnd = a[1] - arcOffset;
|
||||
if (syncedStart < arcLength) {
|
||||
// the start point a[0] is in the minus part of the arc
|
||||
minusIgnored = addArcStart(minus, a[0], minusIgnored);
|
||||
addArcLimit(minus, a[0], true);
|
||||
if (syncedEnd > arcLength) {
|
||||
// the end point a[1] is past the end of the arc
|
||||
// so we leave the minus part and enter the plus part
|
||||
final double minusToPlus = arcLength + arcOffset;
|
||||
minusIgnored = addArcEnd(minus, minusToPlus, minusIgnored);
|
||||
plusIgnored = addArcStart(plus, minusToPlus, plusIgnored);
|
||||
addArcLimit(minus, minusToPlus, false);
|
||||
addArcLimit(plus, minusToPlus, true);
|
||||
if (syncedEnd > MathUtils.TWO_PI) {
|
||||
// in fact the end point a[1] goes far enough that we
|
||||
// leave the plus part of the arc and enter the minus part again
|
||||
final double plusToMinus = MathUtils.TWO_PI + arcOffset;
|
||||
plusIgnored = addArcEnd(plus, plusToMinus, plusIgnored);
|
||||
minusIgnored = addArcStart(minus, plusToMinus, minusIgnored);
|
||||
minusIgnored = addArcEnd(minus, a[1], minusIgnored);
|
||||
addArcLimit(plus, plusToMinus, false);
|
||||
addArcLimit(minus, plusToMinus, true);
|
||||
addArcLimit(minus, a[1], false);
|
||||
} else {
|
||||
// the end point a[1] is in the plus part of the arc
|
||||
plusIgnored = addArcEnd(plus, a[1], plusIgnored);
|
||||
addArcLimit(plus, a[1], false);
|
||||
}
|
||||
} else {
|
||||
// the end point a[1] is in the minus part of the arc
|
||||
minusIgnored = addArcEnd(minus, a[1], minusIgnored);
|
||||
addArcLimit(minus, a[1], false);
|
||||
}
|
||||
} else {
|
||||
// the start point a[0] is in the plus part of the arc
|
||||
plusIgnored = addArcStart(plus, a[0], plusIgnored);
|
||||
addArcLimit(plus, a[0], true);
|
||||
if (syncedEnd > MathUtils.TWO_PI) {
|
||||
// the end point a[1] wraps around to the start of the arc
|
||||
// so we leave the plus part and enter the minus part
|
||||
final double plusToMinus = MathUtils.TWO_PI + arcOffset;
|
||||
plusIgnored = addArcEnd(plus, plusToMinus, plusIgnored);
|
||||
minusIgnored = addArcStart(minus, plusToMinus, minusIgnored);
|
||||
addArcLimit(plus, plusToMinus, false);
|
||||
addArcLimit(minus, plusToMinus, true);
|
||||
if (syncedEnd > MathUtils.TWO_PI + arcLength) {
|
||||
// in fact the end point a[1] goes far enough that we
|
||||
// leave the minus part of the arc and enter the plus part again
|
||||
final double minusToPlus = MathUtils.TWO_PI + arcLength + arcOffset;
|
||||
minusIgnored = addArcEnd(minus, minusToPlus, minusIgnored);
|
||||
plusIgnored = addArcStart(plus, minusToPlus, plusIgnored);
|
||||
plusIgnored = addArcEnd(plus, a[1], plusIgnored);
|
||||
addArcLimit(minus, minusToPlus, false);
|
||||
addArcLimit(plus, minusToPlus, true);
|
||||
addArcLimit(plus, a[1], false);
|
||||
} else {
|
||||
// the end point a[1] is in the minus part of the arc
|
||||
minusIgnored = addArcEnd(minus, a[1], minusIgnored);
|
||||
addArcLimit(minus, a[1], false);
|
||||
}
|
||||
} else {
|
||||
// the end point a[1] is in the plus part of the arc
|
||||
plusIgnored = addArcEnd(plus, a[1], plusIgnored);
|
||||
addArcLimit(plus, a[1], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Split(createSplitPart(plus, plusIgnored), createSplitPart(minus, minusIgnored));
|
||||
return new Split(createSplitPart(plus), createSplitPart(minus));
|
||||
|
||||
}
|
||||
|
||||
/** Add an arc start to a BSP tree under construction.
|
||||
* <p>
|
||||
* Note that this method <em>MUST</em> be called in increasing angle order.
|
||||
* </p>
|
||||
/** Add an arc limit to a BSP tree under construction.
|
||||
* @param tree BSP tree under construction
|
||||
* @param alpha arc start
|
||||
* @param ignored if true, some end points have been ignored previously
|
||||
* @return true if some points have been ignored, taking this arc end into account
|
||||
* @param alpha arc limit
|
||||
* @param isStart if true, the limit is the start of an arc
|
||||
*/
|
||||
private boolean addArcStart(final BSPTree<Sphere1D> tree, final double alpha, final boolean ignored) {
|
||||
|
||||
final BSPTree<Sphere1D> last = getLastLeaf(tree);
|
||||
|
||||
if (alpha <= getTolerance()) {
|
||||
// don't add a spurious cut hyperplane at the start of the circle,
|
||||
last.setAttribute(Boolean.TRUE);
|
||||
return true;
|
||||
private void addArcLimit(final BSPTree<Sphere1D> tree, final double alpha, final boolean isStart) {
|
||||
final LimitAngle limit = new LimitAngle(new S1Point(alpha), !isStart, getTolerance());
|
||||
final BSPTree<Sphere1D> node = tree.getCell(limit.getLocation(), getTolerance());
|
||||
if (node.getCut() != null) {
|
||||
// we find again an already added limit,
|
||||
// this means we have done a full turn around the circle
|
||||
leafBefore(node).setAttribute(Boolean.valueOf(!isStart));
|
||||
} else {
|
||||
last.insertCut(new LimitAngle(new S1Point(alpha), false, getTolerance()));
|
||||
last.setAttribute(null);
|
||||
last.getPlus().setAttribute(Boolean.FALSE);
|
||||
last.getMinus().setAttribute(Boolean.TRUE);
|
||||
return ignored;
|
||||
// it's a new node
|
||||
node.insertCut(limit);
|
||||
node.setAttribute(null);
|
||||
node.getPlus().setAttribute(Boolean.FALSE);
|
||||
node.getMinus().setAttribute(Boolean.TRUE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Add an arc end to a BSP tree under construction.
|
||||
* <p>
|
||||
* Note that this method <em>MUST</em> be called in increasing angle order.
|
||||
* </p>
|
||||
* @param tree BSP tree under construction
|
||||
* @param alpha arc end
|
||||
* @param ignored if true, some end points have been ignored previously
|
||||
* @return true if some points have been ignored, taking this arc end into account
|
||||
*/
|
||||
private boolean addArcEnd(final BSPTree<Sphere1D> tree, final double alpha, final boolean ignored) {
|
||||
|
||||
final BSPTree<Sphere1D> last = getLastLeaf(tree);
|
||||
|
||||
if (alpha >= MathUtils.TWO_PI - getTolerance()) {
|
||||
|
||||
// don't add a spurious cut hyperplane at the end of the circle,
|
||||
last.setAttribute(Boolean.TRUE);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
last.insertCut(new LimitAngle(new S1Point(alpha), true, getTolerance()));
|
||||
last.setAttribute(null);
|
||||
last.getPlus().setAttribute(Boolean.FALSE);
|
||||
last.getMinus().setAttribute(Boolean.TRUE);
|
||||
return ignored;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Create a split part.
|
||||
* @param tree BSP tree containing the limit angles of the split part
|
||||
* @param ignored if true, some end points have been ignored previously
|
||||
* @return split part (may be null)
|
||||
*/
|
||||
private ArcsSet createSplitPart(final BSPTree<Sphere1D> tree, final boolean ignored) {
|
||||
|
||||
if (ignored) {
|
||||
// ensure consistent state at 0 / 2 \pi crossing
|
||||
|
||||
final BSPTree<Sphere1D> first = getFirstLeaf(tree);
|
||||
final boolean firstState = (Boolean) first.getAttribute();
|
||||
final BSPTree<Sphere1D> last = getLastLeaf(tree);
|
||||
final boolean lastState = (Boolean) last.getAttribute();
|
||||
if (firstState ^ lastState) {
|
||||
// there should be a real boundary at the crossing. Since it is not accurately
|
||||
// representable due to S1Point normalizing the angles between 0 (included)
|
||||
// and 2 \pi (excluded), we insert it at the *beginning* of the tree,
|
||||
// with an angle forced to 0.0
|
||||
first.insertCut(new LimitAngle(new S1Point(0.0), true, getTolerance()));
|
||||
first.getPlus().setAttribute(firstState);
|
||||
first.getMinus().setAttribute(lastState);
|
||||
}
|
||||
}
|
||||
|
||||
private ArcsSet createSplitPart(final BSPTree<Sphere1D> tree) {
|
||||
if (tree.getCut() == null && !(Boolean) tree.getAttribute()) {
|
||||
return null;
|
||||
} else {
|
||||
return new ArcsSet(tree, getTolerance());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Class holding the results of the {@link #split split} method.
|
||||
|
|
|
@ -73,7 +73,7 @@ public class ArcsSetTest {
|
|||
ArcsSet set = new ArcsSet(1.0e-10);
|
||||
Arc arc = new Arc(1.5 * FastMath.PI, 2.5 * FastMath.PI, 1.0e-10);
|
||||
ArcsSet.Split split = set.split(arc);
|
||||
for (double alpha = 0; alpha <= MathUtils.TWO_PI; alpha += 0.01) {
|
||||
for (double alpha = 0.0; alpha <= MathUtils.TWO_PI; alpha += 0.01) {
|
||||
S1Point p = new S1Point(alpha);
|
||||
if (alpha < 0.5 * FastMath.PI || alpha > 1.5 * FastMath.PI) {
|
||||
Assert.assertEquals(Location.OUTSIDE, split.getPlus().checkPoint(p));
|
||||
|
@ -445,8 +445,8 @@ public class ArcsSetTest {
|
|||
ArcsSet s16 = new ArcsSet(1.0, 6.0, 1.0e-10);
|
||||
|
||||
ArcsSet.Split split1 = s16.split(new Arc(3.0, 5.0, 1.0e-10));
|
||||
ArcsSet split1Plus = (ArcsSet) split1.getPlus();
|
||||
ArcsSet split1Minus = (ArcsSet) split1.getMinus();
|
||||
ArcsSet split1Plus = split1.getPlus();
|
||||
ArcsSet split1Minus = split1.getMinus();
|
||||
Assert.assertEquals(3.0, split1Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(2, split1Plus.asList().size());
|
||||
Assert.assertEquals(1.0, split1Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -459,8 +459,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(5.0, split1Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split2 = s16.split(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10));
|
||||
ArcsSet split2Plus = (ArcsSet) split2.getPlus();
|
||||
ArcsSet split2Minus = (ArcsSet) split2.getMinus();
|
||||
ArcsSet split2Plus = split2.getPlus();
|
||||
ArcsSet split2Minus = split2.getMinus();
|
||||
Assert.assertEquals(2.0, split2Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split2Plus.asList().size());
|
||||
Assert.assertEquals(3.0, split2Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -473,8 +473,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(6.0, split2Minus.asList().get(1).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split3 = s35.split(new Arc(1.0, 6.0, 1.0e-10));
|
||||
ArcsSet split3Plus = (ArcsSet) split3.getPlus();
|
||||
ArcsSet split3Minus = (ArcsSet) split3.getMinus();
|
||||
ArcsSet split3Plus = split3.getPlus();
|
||||
ArcsSet split3Minus = split3.getMinus();
|
||||
Assert.assertNull(split3Plus);
|
||||
Assert.assertEquals(2.0, split3Minus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split3Minus.asList().size());
|
||||
|
@ -482,8 +482,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(5.0, split3Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split4 = s35.split(new Arc(6.0, 1.0 + MathUtils.TWO_PI, 1.0e-10));
|
||||
ArcsSet split4Plus = (ArcsSet) split4.getPlus();
|
||||
ArcsSet split4Minus = (ArcsSet) split4.getMinus();
|
||||
ArcsSet split4Plus = split4.getPlus();
|
||||
ArcsSet split4Minus = split4.getMinus();
|
||||
Assert.assertEquals(2.0, split4Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split4Plus.asList().size());
|
||||
Assert.assertEquals(3.0, split4Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -499,8 +499,8 @@ public class ArcsSetTest {
|
|||
ArcsSet s46 = new ArcsSet(4.0, 6.0, 1.0e-10);
|
||||
|
||||
ArcsSet.Split split1 = s46.split(new Arc(3.0, 5.0, 1.0e-10));
|
||||
ArcsSet split1Plus = (ArcsSet) split1.getPlus();
|
||||
ArcsSet split1Minus = (ArcsSet) split1.getMinus();
|
||||
ArcsSet split1Plus = split1.getPlus();
|
||||
ArcsSet split1Minus = split1.getMinus();
|
||||
Assert.assertEquals(1.0, split1Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split1Plus.asList().size());
|
||||
Assert.assertEquals(5.0, split1Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -511,8 +511,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(5.0, split1Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split2 = s46.split(new Arc(5.0, 3.0 + MathUtils.TWO_PI, 1.0e-10));
|
||||
ArcsSet split2Plus = (ArcsSet) split2.getPlus();
|
||||
ArcsSet split2Minus = (ArcsSet) split2.getMinus();
|
||||
ArcsSet split2Plus = split2.getPlus();
|
||||
ArcsSet split2Minus = split2.getMinus();
|
||||
Assert.assertEquals(1.0, split2Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split2Plus.asList().size());
|
||||
Assert.assertEquals(4.0, split2Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -523,8 +523,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(6.0, split2Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split3 = s35.split(new Arc(4.0, 6.0, 1.0e-10));
|
||||
ArcsSet split3Plus = (ArcsSet) split3.getPlus();
|
||||
ArcsSet split3Minus = (ArcsSet) split3.getMinus();
|
||||
ArcsSet split3Plus = split3.getPlus();
|
||||
ArcsSet split3Minus = split3.getMinus();
|
||||
Assert.assertEquals(1.0, split3Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split3Plus.asList().size());
|
||||
Assert.assertEquals(3.0, split3Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -535,8 +535,8 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(5.0, split3Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
ArcsSet.Split split4 = s35.split(new Arc(6.0, 4.0 + MathUtils.TWO_PI, 1.0e-10));
|
||||
ArcsSet split4Plus = (ArcsSet) split4.getPlus();
|
||||
ArcsSet split4Minus = (ArcsSet) split4.getMinus();
|
||||
ArcsSet split4Plus = split4.getPlus();
|
||||
ArcsSet split4Minus = split4.getMinus();
|
||||
Assert.assertEquals(1.0, split4Plus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, split4Plus.asList().size());
|
||||
Assert.assertEquals(4.0, split4Plus.asList().get(0).getInf(), 1.0e-10);
|
||||
|
@ -547,4 +547,22 @@ public class ArcsSetTest {
|
|||
Assert.assertEquals(4.0, split4Minus.asList().get(0).getSup(), 1.0e-10);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFarSplit() {
|
||||
ArcsSet set = new ArcsSet(FastMath.PI, 2.5 * FastMath.PI, 1.0e-10);
|
||||
ArcsSet.Split split = set.split(new Arc(0.5 * FastMath.PI, 1.5 * FastMath.PI, 1.0e-10));
|
||||
ArcsSet splitPlus = split.getPlus();
|
||||
ArcsSet splitMinus = split.getMinus();
|
||||
Assert.assertEquals(1, splitMinus.asList().size());
|
||||
Assert.assertEquals(1.0 * FastMath.PI, splitMinus.asList().get(0).getInf(), 1.0e-10);
|
||||
Assert.assertEquals(1.5 * FastMath.PI, splitMinus.asList().get(0).getSup(), 1.0e-10);
|
||||
Assert.assertEquals(0.5 * FastMath.PI, splitMinus.getSize(), 1.0e-10);
|
||||
Assert.assertEquals(1, splitPlus.asList().size());
|
||||
Assert.assertEquals(1.5 * FastMath.PI, splitPlus.asList().get(0).getInf(), 1.0e-10);
|
||||
Assert.assertEquals(2.5 * FastMath.PI, splitPlus.asList().get(0).getSup(), 1.0e-10);
|
||||
Assert.assertEquals(1.0 * FastMath.PI, splitPlus.getSize(), 1.0e-10);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue