mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-06 04:42:15 -05:00
Handle overlapping intercepts in getIntersection,
In a more robust way. Restricting ranges in parameter is not a nice way to handle endpoint intersections.
This commit is contained in:
parent
e5e2a8d7d4
commit
6c6ad76c94
1 changed files with 26 additions and 19 deletions
|
@ -229,7 +229,8 @@ PathItem.inject(new function() {
|
||||||
windRight = 0,
|
windRight = 0,
|
||||||
roots = [],
|
roots = [],
|
||||||
abs = Math.abs,
|
abs = Math.abs,
|
||||||
MAX = 1 - TOLERANCE;
|
tMin = TOLERANCE,
|
||||||
|
tMax = 1 - TOLERANCE;
|
||||||
// Absolutely horizontal curves may return wrong results, since
|
// Absolutely horizontal curves may return wrong results, since
|
||||||
// the curves are monotonic in y direction and this is an
|
// the curves are monotonic in y direction and this is an
|
||||||
// indeterminate state.
|
// indeterminate state.
|
||||||
|
@ -270,7 +271,8 @@ PathItem.inject(new function() {
|
||||||
var curve = curves[i],
|
var curve = curves[i],
|
||||||
values = curve.values,
|
values = curve.values,
|
||||||
winding = curve.winding,
|
winding = curve.winding,
|
||||||
next = curve.next;
|
next = curve.next,
|
||||||
|
lastT, lastX0;
|
||||||
// Since the curves are monotone in y direction, we can just
|
// Since the curves are monotone in y direction, we can just
|
||||||
// compare the endpoints of the curve to determine if the
|
// compare the endpoints of the curve to determine if the
|
||||||
// ray from query point along +-x direction will intersect
|
// ray from query point along +-x direction will intersect
|
||||||
|
@ -278,30 +280,35 @@ PathItem.inject(new function() {
|
||||||
if (winding && (winding === 1
|
if (winding && (winding === 1
|
||||||
&& y >= values[1] && y <= values[7]
|
&& y >= values[1] && y <= values[7]
|
||||||
|| y >= values[7] && y <= values[1])
|
|| y >= values[7] && y <= values[1])
|
||||||
&& Curve.solveCubic(values, 1, y, roots, 0,
|
&& Curve.solveCubic(values, 1, y, roots, 0, 1) === 1){
|
||||||
// If the next curve is horizontal, we have to include
|
|
||||||
// the end of this curve to make sure we won't miss an
|
|
||||||
// intercept.
|
|
||||||
!next.winding && next.values[1] === y ? 1 : MAX) === 1){
|
|
||||||
var t = roots[0],
|
var t = roots[0],
|
||||||
x0 = Curve.evaluate(values, t, 0).x,
|
x0 = Curve.evaluate(values, t, 0).x,
|
||||||
slope = Curve.evaluate(values, t, 1).y;
|
slope = Curve.evaluate(values, t, 1).y;
|
||||||
// Take care of cases where the curve and the preceding
|
// Due to numerical precision issues, two consecutive curves
|
||||||
// curve merely touches the ray towards +-x direction, but
|
// may register an intercept twice, at t = 1 and 0, if y is
|
||||||
// proceeds to the same side of the ray. This essentially is
|
// almost equal to one of the endpoints of the curves.
|
||||||
// not a crossing.
|
if (!(lastT && abs(lastX0 - x0) < TOLERANCE
|
||||||
if (abs(slope) < TOLERANCE && !Curve.isLinear(values)
|
&& ((lastT <= tMin && t >= tMax)
|
||||||
|
|| (t <= tMin && lastT >= tMax)))) {
|
||||||
|
// Take care of cases where the curve and the preceding
|
||||||
|
// curve merely touches the ray towards +-x direction, but
|
||||||
|
// proceeds to the same side of the ray. This essentially is
|
||||||
|
// not a crossing.
|
||||||
|
if (abs(slope) < TOLERANCE && !Curve.isLinear(values)
|
||||||
|| t < TOLERANCE && slope * Curve.evaluate(
|
|| t < TOLERANCE && slope * Curve.evaluate(
|
||||||
curve.previous.values, t, 1).y < 0) {
|
curve.previous.values, t, 1).y < 0) {
|
||||||
if (testContains && x0 >= xBefore && x0 <= xAfter) {
|
if (testContains && x0 >= xBefore && x0 <= xAfter) {
|
||||||
++windLeft;
|
++windLeft;
|
||||||
++windRight;
|
++windRight;
|
||||||
|
}
|
||||||
|
} else if (x0 <= xBefore) {
|
||||||
|
windLeft += winding;
|
||||||
|
} else if (x0 >= xAfter) {
|
||||||
|
windRight += winding;
|
||||||
}
|
}
|
||||||
} else if (x0 <= xBefore) {
|
|
||||||
windLeft += winding;
|
|
||||||
} else if (x0 >= xAfter) {
|
|
||||||
windRight += winding;
|
|
||||||
}
|
}
|
||||||
|
lastT = t;
|
||||||
|
lastX0 = x0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue