Fix curve-bounds check in getIntersections()

Closes #1197
This commit is contained in:
Jürg Lehni 2016-11-20 20:19:38 -05:00
parent 6dd7cc5b6a
commit 8946f44ed9
2 changed files with 36 additions and 22 deletions

View file

@ -1899,34 +1899,26 @@ new function() { // Scope for intersection using bezier fat-line clipping
// If v2 is not provided, search for a self-intersection on v1. // If v2 is not provided, search for a self-intersection on v1.
return Curve._getSelfIntersection(v1, c1, locations, param); return Curve._getSelfIntersection(v1, c1, locations, param);
} }
// Avoid checking curves if completely out of control bounds. As // Avoid checking curves if completely out of control bounds.
// a little optimization, we can scale the handles with 0.75
// before calculating the control bounds and still be sure that
// the curve is fully contained.
var epsilon = /*#=*/Numerical.EPSILON, var epsilon = /*#=*/Numerical.EPSILON,
c1p1x = v1[0], c1p1y = v1[1], c1p1x = v1[0], c1p1y = v1[1],
c1h1x = v1[2], c1h1y = v1[3],
c1h2x = v1[4], c1h2y = v1[5],
c1p2x = v1[6], c1p2y = v1[7], c1p2x = v1[6], c1p2y = v1[7],
c2p1x = v2[0], c2p1y = v2[1], c2p1x = v2[0], c2p1y = v2[1],
c2h1x = v2[2], c2h1y = v2[3],
c2h2x = v2[4], c2h2y = v2[5],
c2p2x = v2[6], c2p2y = v2[7], c2p2x = v2[6], c2p2y = v2[7],
// 's' stands for scaled handles...
c1s1x = (3 * v1[2] + c1p1x) / 4,
c1s1y = (3 * v1[3] + c1p1y) / 4,
c1s2x = (3 * v1[4] + c1p2x) / 4,
c1s2y = (3 * v1[5] + c1p2y) / 4,
c2s1x = (3 * v2[2] + c2p1x) / 4,
c2s1y = (3 * v2[3] + c2p1y) / 4,
c2s2x = (3 * v2[4] + c2p2x) / 4,
c2s2y = (3 * v2[5] + c2p2y) / 4,
min = Math.min, min = Math.min,
max = Math.max; max = Math.max;
if (!( max(c1p1x, c1s1x, c1s2x, c1p2x) + epsilon > if (!( max(c1p1x, c1h1x, c1h2x, c1p2x) + epsilon >
min(c2p1x, c2s1x, c2s2x, c2p2x) && min(c2p1x, c2h1x, c2h2x, c2p2x) &&
min(c1p1x, c1s1x, c1s2x, c1p2x) - epsilon < min(c1p1x, c1h1x, c1h2x, c1p2x) - epsilon <
max(c2p1x, c2s1x, c2s2x, c2p2x) && max(c2p1x, c2h1x, c2h2x, c2p2x) &&
max(c1p1y, c1s1y, c1s2y, c1p2y) + epsilon > max(c1p1y, c1h1y, c1h2y, c1p2y) + epsilon >
min(c2p1y, c2s1y, c2s2y, c2p2y) && min(c2p1y, c2h1y, c2h2y, c2p2y) &&
min(c1p1y, c1s1y, c1s2y, c1p2y) - epsilon < min(c1p1y, c1h1y, c1h2y, c1p2y) - epsilon <
max(c2p1y, c2s1y, c2s2y, c2p2y))) max(c2p1y, c2h1y, c2h2y, c2p2y)))
return locations; return locations;
// Now detect and handle overlaps: // Now detect and handle overlaps:
var overlaps = Curve.getOverlaps(v1, v2); var overlaps = Curve.getOverlaps(v1, v2);

View file

@ -195,4 +195,26 @@ test('#1174', function() {
testIntersection(path1.getIntersections(path2), [ testIntersection(path1.getIntersections(path2), [
{ point: { x: 20, y: 100 }, index: 1, time: 0.00004, crossing: true } { point: { x: 20, y: 100 }, index: 1, time: 0.00004, crossing: true }
]); ]);
}) });
test('#1197', function() {
var path1 = new Path({
segments: [
[99, 106],
[99, 200]
],
strokeColor: 'green'
});
var path2 = new Path({
segments: [
[100, 193, 0, 0, 0, -28],
[140, 106, -52, -12, 0, 0]
],
strokeColor: 'red'
});
testIntersection(path1.getIntersections(path2), [
{ point: { x: 99, y: 148.74959 }, index: 0, time: 0.46982, crossing: true },
{ point: { x: 99, y: 167.82203 }, index: 0, time: 0.60674, crossing: true }
]);
});