Fix overlap sequence handling in Path#compare()

Closes #1223
This commit is contained in:
Jürg Lehni 2016-12-31 06:49:57 +01:00
parent 88453914e5
commit c21e19b303
2 changed files with 13 additions and 17 deletions

View file

@ -2105,31 +2105,27 @@ new function() { // Scope for intersection using bezier fat-line clipping
} }
var v = [v1, v2], var v = [v1, v2],
insert = 'push',
pairs = []; pairs = [];
// Iterate through all end points: // Iterate through all end points:
// First p1 and p2 of curve 1, then p1 and p2 of curve 2. // First p1 of curve 1 & 2, then p2 of curve 1 & 2.
for (var i = 0, t1 = 0; for (var i = 0; i < 4 && pairs.length < 2; i++) {
i < 2 && pairs.length < 2; var i1 = i & 1, // 0, 1, 0, 1
i += t1 === 0 ? 0 : 1, t1 = t1 ^ 1) { i2 = i1 ^ 1, // 1, 0, 1, 0
var t2 = Curve.getTimeOf(v[i ^ 1], new Point( t1 = i >> 1, // 0, 0, 1, 1
v[i][t1 === 0 ? 0 : 6], t2 = Curve.getTimeOf(v[i1], new Point(
v[i][t1 === 0 ? 1 : 7])); v[i2][t1 === 0 ? 0 : 6],
v[i2][t1 === 0 ? 1 : 7]));
if (t2 != null) { // If point is on curve if (t2 != null) { // If point is on curve
var pair = i === 0 ? [t1, t2] : [t2, t1]; var pair = i1 ? [t1, t2] : [t2, t1];
// Filter out tiny overlaps. // Filter out tiny overlaps.
if (!pairs.length || if (!pairs.length ||
abs(pair[0] - pairs[0][0]) > timeEpsilon && abs(pair[0] - pairs[0][0]) > timeEpsilon &&
abs(pair[1] - pairs[0][1]) > timeEpsilon) { abs(pair[1] - pairs[0][1]) > timeEpsilon) {
pairs[insert](pair); pairs.push(pair);
// If the first pair isn't found in the first iteration,
// invert insertion to preserve overlap orientation.
if (i || t1)
insert = 'unshift';
} }
} }
// We checked 3 points but found no match, curves can't overlap. // We checked 3 points but found no match, curves can't overlap.
if (i && !pairs.length) if (i > 2 && !pairs.length)
break; break;
} }
if (pairs.length !== 2) { if (pairs.length !== 2) {

View file

@ -158,11 +158,11 @@ test('PathItem#compare()', function() {
}, true, 'Comparing a square with an identical square with additional segments should return true.'); }, true, 'Comparing a square with an identical square with additional segments should return true.');
equals(function() { equals(function() {
return square2.compare(square); return square2.compare(square);
}, true, 'Comparing a square with an identical square with additional segments should return true.'); }, true, 'Comparing a square with additional segments with an identical square should return true.');
equals(function() { equals(function() {
return circle.compare(circle2); return circle.compare(circle2);
}, true, 'Comparing a circle with an identical circle with additional segments should return true.'); }, true, 'Comparing a circle with an identical circle with additional segments should return true.');
equals(function() { equals(function() {
return circle2.compare(circle); return circle2.compare(circle);
}, true, 'Comparing a circle with an identical circle with additional segments should return true.'); }, true, 'Comparing a circle with additional segments with an identical circle should return true.');
}); });