mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-04 03:45:58 -05:00
Merge pull request #938 from iconexperience/getWinding-simplification
Simplify getWindings() by using only the 'last' property to understand when a new loop starts.
This commit is contained in:
commit
53269ab169
1 changed files with 55 additions and 61 deletions
|
@ -348,69 +348,65 @@ PathItem.inject(new function() {
|
||||||
} else {
|
} else {
|
||||||
var xBefore = px - epsilon,
|
var xBefore = px - epsilon,
|
||||||
xAfter = px + epsilon,
|
xAfter = px + epsilon,
|
||||||
start,
|
prevWinding,
|
||||||
end = 0;
|
prevXEnd;
|
||||||
while (end < length) {
|
for (var i = 0; i < length; i++) {
|
||||||
start = end;
|
var curve = curves[i],
|
||||||
// The first curve of a loop holds information about its length
|
winding = curve.winding,
|
||||||
// and the last curve with non-zero winding.
|
values = curve.values,
|
||||||
|
yStart = values[1],
|
||||||
|
yEnd = values[7];
|
||||||
|
// The first curve of a loop holds the last curve with
|
||||||
|
// non-zero winding.
|
||||||
// Retrieve and use it here (See _getMonoCurve()).
|
// Retrieve and use it here (See _getMonoCurve()).
|
||||||
var curve = curves[start],
|
if (curve.last) {
|
||||||
last = curve.last,
|
|
||||||
// Get the values of to the end x coordinate and winding of
|
// Get the values of to the end x coordinate and winding of
|
||||||
// the last non-horizontal curve, which will be the previous
|
// the last non-horizontal curve, which will be the previous
|
||||||
// non-horizontal curve for the first curve of the loop.
|
// non-horizontal curve for the first curve of the loop.
|
||||||
prevWinding = last.winding,
|
prevWinding = curve.last.winding;
|
||||||
prevXEnd = last.values[6];
|
prevXEnd = curve.last.values[6];
|
||||||
end = start + curve.length;
|
}
|
||||||
for (var i = start; i < end; i++) {
|
// Since the curves are monotone in y direction, we can just
|
||||||
var curve = curves[i],
|
// compare the endpoints of the curve to determine if the
|
||||||
winding = curve.winding,
|
// ray from query point along +-x direction will intersect
|
||||||
values = curve.values,
|
// the monotone curve.
|
||||||
yStart = values[1],
|
// Horizontal curves with winding == 0 will be completely
|
||||||
yEnd = values[7];
|
// ignored.
|
||||||
// Since the curves are monotone in y direction, we can just
|
if (winding && (py >= yStart && py <= yEnd
|
||||||
// compare the endpoints of the curve to determine if the
|
|| py >= yEnd && py <= yStart)) {
|
||||||
// ray from query point along +-x direction will intersect
|
// Calculate the x value for the ray's intersection.
|
||||||
// the monotone curve.
|
var x = py === yStart ? values[0]
|
||||||
// Horizontal curves with winding == 0 will be completely
|
: py === yEnd ? values[6]
|
||||||
// ignored.
|
: Curve.solveCubic(values, 1, py, roots, 0, 1) === 1
|
||||||
if (winding && (py >= yStart && py <= yEnd
|
? Curve.getPoint(values, roots[0]).x
|
||||||
|| py >= yEnd && py <= yStart)) {
|
: null;
|
||||||
// Calculate the x value for the ray's intersection.
|
if (x != null) {
|
||||||
var x = py === yStart ? values[0]
|
// Count the intersection of the ray with the
|
||||||
: py === yEnd ? values[6]
|
// monotonic curve if:
|
||||||
: Curve.solveCubic(values, 1, py, roots, 0, 1) === 1
|
// - the crossing is not at the start of the curve
|
||||||
? Curve.getPoint(values, roots[0]).x
|
// - or the windings are opposite (intersect at a
|
||||||
: null;
|
// vertical extremum)
|
||||||
if (x != null) {
|
// - or the start of the current curve and the end
|
||||||
// Count the intersection of the ray with the
|
// of the prev curve are on opposite sides of px
|
||||||
// monotonic curve if:
|
var isWindingChange = winding === -prevWinding;
|
||||||
// - the crossing is not at the start of the curve
|
if (py !== yStart || isWindingChange
|
||||||
// - or the windings are opposite (intersect at a
|
|| (x - px) * (prevXEnd - px) < 0) {
|
||||||
// vertical extremum)
|
if (x < xBefore) {
|
||||||
// - or the start of the current curve and the end
|
windLeft += winding;
|
||||||
// of the prev curve are on opposite sides of px
|
} else if (x > xAfter) {
|
||||||
var isWindingChange = winding === -prevWinding;
|
windRight += winding;
|
||||||
if (py !== yStart || isWindingChange
|
} else if (py === yStart && isWindingChange) {
|
||||||
|| (x - px) * (prevXEnd - px) < 0) {
|
// The point is a vertical extremum of the
|
||||||
if (x < xBefore) {
|
// path.
|
||||||
windLeft += winding;
|
++windLeft;
|
||||||
} else if (x > xAfter) {
|
++windRight;
|
||||||
windRight += winding;
|
|
||||||
} else if (py === yStart && isWindingChange) {
|
|
||||||
// The point is a vertical extremum of the
|
|
||||||
// path.
|
|
||||||
++windLeft;
|
|
||||||
++windRight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update previous winding and end coordinate whenever
|
|
||||||
// the ray intersects a non-horizontal curve.
|
|
||||||
prevWinding = winding;
|
|
||||||
prevXEnd = values[6];
|
|
||||||
}
|
}
|
||||||
|
// Update previous winding and end coordinate whenever
|
||||||
|
// the ray intersects a non-horizontal curve.
|
||||||
|
prevWinding = winding;
|
||||||
|
prevXEnd = values[6];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -976,11 +972,9 @@ Path.inject(/** @lends Path# */{
|
||||||
handleCurve([p1x, p1y, p1x, p1y, p2x, p2y, p2x, p2y]);
|
handleCurve([p1x, p1y, p1x, p1y, p2x, p2y, p2x, p2y]);
|
||||||
}
|
}
|
||||||
if (monoCurves.length > 0) {
|
if (monoCurves.length > 0) {
|
||||||
// Add information about the loop length and the last curve with
|
// Add information about the last curve with non-zero winding,
|
||||||
// non-zero winding, as required in getWinding().
|
// as required in getWinding().
|
||||||
var first = monoCurves[0];
|
monoCurves[0].last = last;
|
||||||
first.length = monoCurves.length;
|
|
||||||
first.last = last;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return monoCurves;
|
return monoCurves;
|
||||||
|
|
Loading…
Reference in a new issue