mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-08-28 22:08:54 -04:00
Fix bug in Curve.filterIntersections() and clean up code a bit.
This commit is contained in:
parent
b2261fd512
commit
4ed9ef54f2
3 changed files with 25 additions and 23 deletions
|
@ -1414,18 +1414,19 @@ new function() { // Scope for methods that require numerical integration
|
||||||
},
|
},
|
||||||
|
|
||||||
filterIntersections: function(locations, _expand) {
|
filterIntersections: function(locations, _expand) {
|
||||||
var max = locations.length - 1;
|
var max = locations.length - 1,
|
||||||
|
tMax = 1 - /*#=*/Numerical.TOLERANCE;
|
||||||
// Merge intersections very close to the end of a curve to the
|
// Merge intersections very close to the end of a curve to the
|
||||||
// beginning of the next curve.
|
// beginning of the next curve.
|
||||||
for (var i = max; i >= 0; i--) {
|
for (var i = max; i >= 0; i--) {
|
||||||
var loc = locations[i],
|
var loc = locations[i],
|
||||||
next = loc._curve.getNext(),
|
next = loc._curve.getNext(),
|
||||||
next2 = loc._curve2.getNext();
|
next2 = loc._curve2.getNext();
|
||||||
if (next && loc._parameter >= MAX) {
|
if (next && loc._parameter >= tMax) {
|
||||||
loc._parameter = 0;
|
loc._parameter = 0;
|
||||||
loc._curve = next;
|
loc._curve = next;
|
||||||
}
|
}
|
||||||
if (next2 && loc._parameter2 >= MAX) {
|
if (next2 && loc._parameter2 >= tMax) {
|
||||||
loc._parameter2 = 0;
|
loc._parameter2 = 0;
|
||||||
loc._curve2 = next2;
|
loc._curve2 = next2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ PathItem.inject(new function() {
|
||||||
* @param {CurveLocation[]} intersections Array of CurveLocation objects
|
* @param {CurveLocation[]} intersections Array of CurveLocation objects
|
||||||
*/
|
*/
|
||||||
function splitPath(intersections) {
|
function splitPath(intersections) {
|
||||||
var TOLERANCE = /*#=*/Numerical.TOLERANCE,
|
var tolerance = /*#=*/Numerical.TOLERANCE,
|
||||||
linearSegments;
|
linearSegments;
|
||||||
|
|
||||||
function resetLinear() {
|
function resetLinear() {
|
||||||
|
@ -200,9 +200,9 @@ PathItem.inject(new function() {
|
||||||
segment = newCurve._segment1;
|
segment = newCurve._segment1;
|
||||||
curve = newCurve.getPrevious();
|
curve = newCurve.getPrevious();
|
||||||
} else {
|
} else {
|
||||||
segment = t < TOLERANCE
|
segment = t < tolerance
|
||||||
? curve._segment1
|
? curve._segment1
|
||||||
: t > 1 - TOLERANCE
|
: t > 1 - tolerance
|
||||||
? curve._segment2
|
? curve._segment2
|
||||||
: curve.getPartLength(0, t) < curve.getPartLength(t, 1)
|
: curve.getPartLength(0, t) < curve.getPartLength(t, 1)
|
||||||
? curve._segment1
|
? curve._segment1
|
||||||
|
@ -224,22 +224,22 @@ PathItem.inject(new function() {
|
||||||
* with respect to a given set of monotone curves.
|
* with respect to a given set of monotone curves.
|
||||||
*/
|
*/
|
||||||
function getWinding(point, curves, horizontal, testContains) {
|
function getWinding(point, curves, horizontal, testContains) {
|
||||||
var TOLERANCE = /*#=*/Numerical.TOLERANCE,
|
var tolerance = /*#=*/Numerical.TOLERANCE,
|
||||||
|
tMax = 1 - tolerance,
|
||||||
x = point.x,
|
x = point.x,
|
||||||
y = point.y,
|
y = point.y,
|
||||||
windLeft = 0,
|
windLeft = 0,
|
||||||
windRight = 0,
|
windRight = 0,
|
||||||
roots = [],
|
roots = [],
|
||||||
abs = Math.abs,
|
abs = Math.abs;
|
||||||
MAX = 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.
|
||||||
if (horizontal) {
|
if (horizontal) {
|
||||||
var yTop = -Infinity,
|
var yTop = -Infinity,
|
||||||
yBottom = Infinity,
|
yBottom = Infinity,
|
||||||
yBefore = y - TOLERANCE,
|
yBefore = y - tolerance,
|
||||||
yAfter = y + TOLERANCE;
|
yAfter = y + tolerance;
|
||||||
// Find the closest top and bottom intercepts for the same vertical
|
// Find the closest top and bottom intercepts for the same vertical
|
||||||
// line.
|
// line.
|
||||||
for (var i = 0, l = curves.length; i < l; i++) {
|
for (var i = 0, l = curves.length; i < l; i++) {
|
||||||
|
@ -264,8 +264,8 @@ PathItem.inject(new function() {
|
||||||
if (yBottom < Infinity)
|
if (yBottom < Infinity)
|
||||||
windRight = getWinding(new Point(x, yBottom), curves);
|
windRight = getWinding(new Point(x, yBottom), curves);
|
||||||
} else {
|
} else {
|
||||||
var xBefore = x - TOLERANCE,
|
var xBefore = x - tolerance,
|
||||||
xAfter = x + TOLERANCE;
|
xAfter = x + tolerance;
|
||||||
// Find the winding number for right side of the curve, inclusive of
|
// Find the winding number for right side of the curve, inclusive of
|
||||||
// the curve itself, while tracing along its +-x direction.
|
// the curve itself, while tracing along its +-x direction.
|
||||||
for (var i = 0, l = curves.length; i < l; i++) {
|
for (var i = 0, l = curves.length; i < l; i++) {
|
||||||
|
@ -284,7 +284,8 @@ PathItem.inject(new function() {
|
||||||
// If the next curve is horizontal, we have to include
|
// If the next curve is horizontal, we have to include
|
||||||
// the end of this curve to make sure we won't miss an
|
// the end of this curve to make sure we won't miss an
|
||||||
// intercept.
|
// intercept.
|
||||||
!next.winding && next.values[1] === y ? 1 : MAX) === 1){
|
!next.winding
|
||||||
|
&& next.values[1] === y ? 1 : tMax) === 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;
|
||||||
|
@ -292,8 +293,8 @@ PathItem.inject(new function() {
|
||||||
// curve merely touches the ray towards +-x direction, but
|
// curve merely touches the ray towards +-x direction, but
|
||||||
// proceeds to the same side of the ray. This essentially is
|
// proceeds to the same side of the ray. This essentially is
|
||||||
// not a crossing.
|
// not a crossing.
|
||||||
if (abs(slope) < TOLERANCE && !Curve.isLinear(values)
|
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;
|
||||||
|
@ -572,12 +573,12 @@ Path.inject(/** @lends Path# */{
|
||||||
var a = 3 * (y1 - y2) - y0 + y3,
|
var a = 3 * (y1 - y2) - y0 + y3,
|
||||||
b = 2 * (y0 + y2) - 4 * y1,
|
b = 2 * (y0 + y2) - 4 * y1,
|
||||||
c = y1 - y0,
|
c = y1 - y0,
|
||||||
TOLERANCE = /*#=*/Numerical.TOLERANCE,
|
tolerance = /*#=*/Numerical.TOLERANCE,
|
||||||
roots = [];
|
roots = [];
|
||||||
// Keep then range to 0 .. 1 (excluding) in the search for y
|
// Keep then range to 0 .. 1 (excluding) in the search for y
|
||||||
// extrema.
|
// extrema.
|
||||||
var count = Numerical.solveQuadratic(a, b, c, roots, TOLERANCE,
|
var count = Numerical.solveQuadratic(a, b, c, roots, tolerance,
|
||||||
1 - TOLERANCE);
|
1 - tolerance);
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
insertCurve(v);
|
insertCurve(v);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -76,8 +76,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
||||||
length1 = curves1.length,
|
length1 = curves1.length,
|
||||||
length2 = path ? curves2.length : length1,
|
length2 = path ? curves2.length : length1,
|
||||||
values2 = [],
|
values2 = [],
|
||||||
MIN = /*#=*/Numerical.EPSILON,
|
tMin = /*#=*/Numerical.EPSILON,
|
||||||
MAX = 1 - /*#=*/Numerical.EPSILON;
|
tMax = 1 - tMin;
|
||||||
// First check the bounds of the two paths. If they don't intersect,
|
// First check the bounds of the two paths. If they don't intersect,
|
||||||
// we don't need to iterate through their curves.
|
// we don't need to iterate through their curves.
|
||||||
if (path && !this.getBounds(matrix1).touches(path.getBounds(matrix2)))
|
if (path && !this.getBounds(matrix1).touches(path.getBounds(matrix2)))
|
||||||
|
@ -106,7 +106,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
||||||
Curve.getIntersections(
|
Curve.getIntersections(
|
||||||
parts[0], parts[1], curve1, curve1, locations,
|
parts[0], parts[1], curve1, curve1, locations,
|
||||||
function(loc) {
|
function(loc) {
|
||||||
if (loc._parameter <= MAX) {
|
if (loc._parameter <= tMax) {
|
||||||
// Since the curve was split above, we need to
|
// Since the curve was split above, we need to
|
||||||
// adjust the parameters for both locations.
|
// adjust the parameters for both locations.
|
||||||
loc._parameter /= 2;
|
loc._parameter /= 2;
|
||||||
|
@ -127,7 +127,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
||||||
!path && (j === i + 1 || j === length2 - 1 && i === 0)
|
!path && (j === i + 1 || j === length2 - 1 && i === 0)
|
||||||
&& function(loc) {
|
&& function(loc) {
|
||||||
var t = loc._parameter;
|
var t = loc._parameter;
|
||||||
return t >= MIN && t <= MAX;
|
return t >= tMin && t <= tMax;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue