mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -05:00
Optimize new getWinding() code a bit.
By storing additional information along the first curve of a monoCurve loop.
This commit is contained in:
parent
1078e1f8a9
commit
2fc7684efb
1 changed files with 32 additions and 28 deletions
|
@ -350,22 +350,13 @@ PathItem.inject(new function() {
|
||||||
end = 0;
|
end = 0;
|
||||||
while (end < length) {
|
while (end < length) {
|
||||||
start = end;
|
start = end;
|
||||||
// Determine the beginning and end of the loop, along with the
|
// The first curve of a loop holds information about its length
|
||||||
// first and last curve with non-zero winding within the loop:
|
// and the first / last curve with non-zero winding.
|
||||||
var firstCurve = null,
|
// Retrieve and use it here (See _getMonoCurve()).
|
||||||
lastCurve;
|
var curve = curves[start],
|
||||||
for (var i = start; i < length; i++) {
|
firstWinding = curve.firstWinding,
|
||||||
var curve = curves[i];
|
lastWinding = curve.lastWinding;
|
||||||
if (curve.winding) {
|
end = start + curve.length;
|
||||||
if (!firstCurve)
|
|
||||||
firstCurve = curve;
|
|
||||||
lastCurve = curve;
|
|
||||||
}
|
|
||||||
if (curve.next !== curves[i + 1]) {
|
|
||||||
end = i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Walk through one single loop of curves.
|
// Walk through one single loop of curves.
|
||||||
var startCounted = false,
|
var startCounted = false,
|
||||||
prevCurve, // non-horizontal curve before the current curve.
|
prevCurve, // non-horizontal curve before the current curve.
|
||||||
|
@ -374,8 +365,8 @@ PathItem.inject(new function() {
|
||||||
curve = null;
|
curve = null;
|
||||||
for (var i = start; i < end; i++) {
|
for (var i = start; i < end; i++) {
|
||||||
if (!curve) {
|
if (!curve) {
|
||||||
prevCurve = lastCurve;
|
prevCurve = lastWinding;
|
||||||
nextCurve = firstCurve;
|
nextCurve = firstWinding;
|
||||||
} else if (curve.winding) {
|
} else if (curve.winding) {
|
||||||
prevCurve = curve;
|
prevCurve = curve;
|
||||||
}
|
}
|
||||||
|
@ -407,17 +398,16 @@ PathItem.inject(new function() {
|
||||||
if (!( // = the following conditions will be excluded:
|
if (!( // = the following conditions will be excluded:
|
||||||
// Detect and exclude intercepts at 'end' of loops
|
// Detect and exclude intercepts at 'end' of loops
|
||||||
// if the start of the loop was already counted.
|
// if the start of the loop was already counted.
|
||||||
t > tMax && startCounted && curve === lastCurve
|
t > tMax && startCounted && curve === lastWinding
|
||||||
// Detect 2nd case of a consecutive intercept
|
// Detect 2nd case of a consecutive intercept
|
||||||
|| t < tMin && prevT > tMax)) {
|
|| t < tMin && prevT > tMax)) {
|
||||||
var x = Curve.getPoint(values, t).x,
|
var x = Curve.getPoint(values, t).x,
|
||||||
slope = Curve.getTangent(values, t).y,
|
|
||||||
counted = false;
|
counted = false;
|
||||||
// Take care of cases where the curve and the
|
// Take care of cases where the curve and the
|
||||||
// preceding curve merely touches the ray towards
|
// preceding curve merely touches the ray towards
|
||||||
// +-x direction, but proceeds to the same side of
|
// +-x direction, but proceeds to the same side of
|
||||||
// the ray. This essentially is not a crossing.
|
// the ray. This essentially is not a crossing.
|
||||||
if (Numerical.isZero(slope)
|
if (Numerical.isZero(Curve.getTangent(values, t).y)
|
||||||
&& !Curve.isStraight(values)
|
&& !Curve.isStraight(values)
|
||||||
// Does the winding over the edges change?
|
// Does the winding over the edges change?
|
||||||
|| t < tMin && prevCurve
|
|| t < tMin && prevCurve
|
||||||
|
@ -437,7 +427,7 @@ PathItem.inject(new function() {
|
||||||
counted = true;
|
counted = true;
|
||||||
}
|
}
|
||||||
// Mark the start of the path as counted.
|
// Mark the start of the path as counted.
|
||||||
if (curve === firstCurve) {
|
if (curve === firstWinding) {
|
||||||
startCounted = t < tMin && counted;
|
startCounted = t < tMin && counted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,19 +932,22 @@ Path.inject(/** @lends Path# */{
|
||||||
*/
|
*/
|
||||||
_getMonoCurves: function() {
|
_getMonoCurves: function() {
|
||||||
var monoCurves = this._monoCurves,
|
var monoCurves = this._monoCurves,
|
||||||
prevCurve;
|
prevCurve,
|
||||||
|
firstWinding = null,
|
||||||
|
lastWinding;
|
||||||
|
|
||||||
// Insert curve values into a cached array
|
// Insert curve values into a cached array
|
||||||
function insertCurve(v) {
|
function insertCurve(v) {
|
||||||
var y0 = v[1],
|
var y0 = v[1],
|
||||||
y1 = v[7],
|
y1 = v[7],
|
||||||
|
winding = y0 === y1
|
||||||
|
? 0 // Horizontal
|
||||||
|
: y0 > y1
|
||||||
|
? -1 // Decreasing
|
||||||
|
: 1, // Increasing
|
||||||
curve = {
|
curve = {
|
||||||
values: v,
|
values: v,
|
||||||
winding: y0 === y1
|
winding: winding,
|
||||||
? 0 // Horizontal
|
|
||||||
: y0 > y1
|
|
||||||
? -1 // Decreasing
|
|
||||||
: 1, // Increasing
|
|
||||||
// Add a reference to neighboring curves.
|
// Add a reference to neighboring curves.
|
||||||
previous: prevCurve,
|
previous: prevCurve,
|
||||||
next: null // Always set it for hidden class optimization.
|
next: null // Always set it for hidden class optimization.
|
||||||
|
@ -963,6 +956,12 @@ Path.inject(/** @lends Path# */{
|
||||||
prevCurve.next = curve;
|
prevCurve.next = curve;
|
||||||
monoCurves.push(curve);
|
monoCurves.push(curve);
|
||||||
prevCurve = curve;
|
prevCurve = curve;
|
||||||
|
// Keep track of the first and last curves with winding numbers.
|
||||||
|
if (winding) {
|
||||||
|
if (!firstWinding)
|
||||||
|
firstWinding = curve;
|
||||||
|
lastWinding = curve;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle bezier curves. We need to chop them into smaller curves with
|
// Handle bezier curves. We need to chop them into smaller curves with
|
||||||
|
@ -1034,6 +1033,11 @@ Path.inject(/** @lends Path# */{
|
||||||
last = monoCurves[monoCurves.length - 1];
|
last = monoCurves[monoCurves.length - 1];
|
||||||
first.previous = last;
|
first.previous = last;
|
||||||
last.next = first;
|
last.next = first;
|
||||||
|
// Add information about the loop length and the first / last
|
||||||
|
// curve with non-zero winding (Used in getWinding()).
|
||||||
|
first.length = monoCurves.length;
|
||||||
|
first.firstWinding = firstWinding;
|
||||||
|
first.lastWinding = lastWinding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return monoCurves;
|
return monoCurves;
|
||||||
|
|
Loading…
Reference in a new issue