mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-19 06:00:56 -05:00
Improve handling of points on paths in getWinding()
This commit is contained in:
parent
56dd636f22
commit
e2eaf87fcb
1 changed files with 34 additions and 4 deletions
|
@ -305,7 +305,6 @@ PathItem.inject(new function() {
|
|||
py = point.y,
|
||||
windLeft = 0,
|
||||
windRight = 0,
|
||||
isOnCurve = false,
|
||||
length = curves.length,
|
||||
roots = [],
|
||||
abs = Math.abs;
|
||||
|
@ -341,7 +340,14 @@ PathItem.inject(new function() {
|
|||
var xBefore = px - epsilon,
|
||||
xAfter = px + epsilon,
|
||||
prevWinding,
|
||||
prevXEnd;
|
||||
prevXEnd,
|
||||
// Separately count the windings for points on curves.
|
||||
windLeftOnCurve = 0,
|
||||
windRightOnCurve = 0,
|
||||
isOnCurve = false,
|
||||
// Use the winding at the leftmost intersection to determine
|
||||
// the orientation of the loop (clockwise / anti-clockwise).
|
||||
leftIntersVal;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var curve = curves[i],
|
||||
winding = curve.winding,
|
||||
|
@ -356,6 +362,10 @@ PathItem.inject(new function() {
|
|||
// non-horizontal curve for the first curve in the loop.
|
||||
prevWinding = curve.last.winding;
|
||||
prevXEnd = curve.last.values[6];
|
||||
// Reset the on curve flag and the leftmost intersection
|
||||
// values for each loop.
|
||||
isOnCurve = false;
|
||||
leftIntersVal = null;
|
||||
}
|
||||
// Since the curves are monotonic in y direction, we can just
|
||||
// compare the endpoints of the curve to determine if the ray
|
||||
|
@ -396,16 +406,36 @@ PathItem.inject(new function() {
|
|||
// the ray intersects a non-horizontal curve.
|
||||
prevWinding = winding;
|
||||
prevXEnd = values[6];
|
||||
// Test if the point is on the horizontal curve
|
||||
// Test if the point is on the horizontal curve.
|
||||
} else if ((px - values[0]) * (px - values[6]) <= 0) {
|
||||
isOnCurve = true;
|
||||
}
|
||||
}
|
||||
// If we are at the end of a loop and the point was on a curve of the
|
||||
// loop, we increment / decrement the on-curve winding numbers as if
|
||||
// the point was inside the path.
|
||||
if (i == length - 1 || curves[i + 1].last) {
|
||||
if (isOnCurve) {
|
||||
if (leftIntersVal && leftIntersVal[1] < 0) {
|
||||
windLeftOnCurve -= 1;
|
||||
windRightOnCurve += 1;
|
||||
} else {
|
||||
windLeftOnCurve += 1;
|
||||
windRightOnCurve -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use the on-curve windings if no other intersections were
|
||||
// found or if they canceled each other.
|
||||
if (windLeft === 0 && windRight === 0) {
|
||||
windLeft = windLeftOnCurve;
|
||||
windRight = windRightOnCurve;
|
||||
}
|
||||
}
|
||||
// If the point was on a monotonic curve, we are on the path by
|
||||
// definition. In this case ensure that the winding is at least 1.
|
||||
return Math.max(abs(windLeft), abs(windRight), isOnCurve ? 1 : 0);
|
||||
return Math.max(abs(windLeft), abs(windRight));
|
||||
}
|
||||
|
||||
function propagateWinding(segment, path1, path2, monoCurves, operator) {
|
||||
|
|
Loading…
Reference in a new issue