Put the recursion cap back into fat-line clipping code.

But use a higher value, and have it work in conjunction with call-count cap.
Relates to #1074
This commit is contained in:
Jürg Lehni 2016-06-12 17:07:43 +02:00
parent 452bbfdaa4
commit 614c781f29
2 changed files with 28 additions and 15 deletions

View file

@ -1549,11 +1549,12 @@ new function() { // Scope for intersection using bezier fat-line clipping
}
function addCurveIntersections(v1, v2, c1, c2, locations, param, tMin, tMax,
uMin, uMax, flip, calls) {
// Avoid deeper recursion, but instead of counting recursion, we count
// the total amount of calls, to avoid massive call-trees as suggested
// by @iconexperience in #904#issuecomment-225283430. See also #565 #899
if (++calls > 4096)
uMin, uMax, flip, recursion, calls) {
// Avoid deeper recursion, by counting the total amount of recursions,
// as well as the total amount of calls, to avoid massive call-trees as
// suggested by @iconexperience in #904#issuecomment-225283430.
// See also: #565 #899 #1074
if (++recursion >= 48 || ++calls > 4096)
return calls;
// Let P be the first curve and Q be the second
var q0x = v2[0], q0y = v2[1], q3x = v2[6], q3y = v2[7],
@ -1613,24 +1614,24 @@ new function() { // Scope for intersection using bezier fat-line clipping
t = (tMinNew + tMaxNew) / 2;
calls = addCurveIntersections(
v2, parts[0], c2, c1, locations, param,
uMin, uMax, tMinNew, t, !flip, calls);
uMin, uMax, tMinNew, t, !flip, recursion, calls);
calls = addCurveIntersections(
v2, parts[1], c2, c1, locations, param,
uMin, uMax, t, tMaxNew, !flip, calls);
uMin, uMax, t, tMaxNew, !flip, recursion, calls);
} else {
var parts = Curve.subdivide(v2, 0.5),
u = (uMin + uMax) / 2;
calls = addCurveIntersections(
parts[0], v1, c2, c1, locations, param,
uMin, u, tMinNew, tMaxNew, !flip, calls);
uMin, u, tMinNew, tMaxNew, !flip, recursion, calls);
calls = addCurveIntersections(
parts[1], v1, c2, c1, locations, param,
u, uMax, tMinNew, tMaxNew, !flip, calls);
u, uMax, tMinNew, tMaxNew, !flip, recursion, calls);
}
} else { // Iterate
calls = addCurveIntersections(
v2, v1, c2, c1, locations, param,
uMin, uMax, tMinNew, tMaxNew, !flip, calls);
uMin, uMax, tMinNew, tMaxNew, !flip, recursion, calls);
}
}
return calls;
@ -1851,8 +1852,8 @@ new function() { // Scope for intersection using bezier fat-line clipping
v1, v2, c1, c2, locations, param,
// Define the defaults for these parameters of
// addCurveIntersections():
// tMin, tMax, uMin, uMax, reverse, recursion
0, 1, 0, 1, 0, 0);
// tMin, tMax, uMin, uMax, flip, recursion, calls
0, 1, 0, 1, 0, 0, 0);
// We're done if we handle lines and found one intersection already:
// #805#issuecomment-148503018
if (straight && locations.length > before)

View file

@ -20,8 +20,10 @@ function testIntersection(intersections, results) {
var name = 'intersections[' + i + ']';
equals(inter.point, new Point(values.point), name + '.point');
equals(inter.index, values.index, name + '.index');
equals(inter.time, values.time || 0, name + '.time');
equals(inter.isCrossing(), values.crossing || false, name + '.isCrossing()');
if (values.time != null)
equals(inter.time, values.time, name + '.time');
if (values.crossing != null)
equals(inter.isCrossing(), values.crossing, name + '.isCrossing()');
}
}
@ -122,7 +124,7 @@ test('#904', function() {
{ point: { x: 347.65684, y: 270.43159 }, index: 0, time: 0, crossing: false },
{ point: { x: 383.05787, y: 179.36393 }, index: 0, time: 0.99583, crossing: true }
]);
})
});
test('#1066', function() {
var path1 = new paper.Path({
@ -141,3 +143,13 @@ test('#1066', function() {
{ point: { x: 230.44479, y: 216.05441 }, index: 0, time: 0.63642, crossing: true }
]);
});
test('#1074', function() {
var path1 = new Path('M349.98644,0c-192.98072,0 -349.98644,157.00255 -349.98644,349.98327c0,35.02687 28.39313,63.42 63.42,63.42c35.02687,0 63.42,-28.39313 63.42,-63.42c0,-123.04114 100.10213,-223.14327 223.14644,-223.14327c35.02687,0 63.42,-28.39313 63.42,-63.42c0,-35.02687 -28.39313,-63.42 -63.42,-63.42z');
var path2 = new Path('M349.98644,0c-35.02687,0 -63.42,28.39313 -63.42,63.42c0,35.02687 28.39313,63.42 63.42,63.42c59.25965,0 118.69687,22.57118 158.98443,60.37584c25.54558,23.97593 65.67775,22.6885 89.64417,-2.84756c23.96959,-25.5424 22.69168,-65.67775 -2.84756,-89.64417c-63.21071,-59.31355 -155.09044,-94.72411 -245.78104,-94.72411z');
var inters = path1.getIntersections(path2);
testIntersection(path1.getIntersections(path2), [
{ point: { x: 349.98644, y: 0 }, index: 0, time: 0 },
{ point: { x: 349.98644, y: 126.84 } , index: 4, time: 0 }
]);
});