mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
Start handling self-overlapping paths in getOverlaps()
Relates to #874 and #887
This commit is contained in:
parent
a6e1a1a76d
commit
0d172a74f4
1 changed files with 41 additions and 31 deletions
|
@ -1383,8 +1383,10 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
|
|
||||||
function addLocation(locations, param, v1, c1, t1, p1, v2, c2, t2, p2,
|
function addLocation(locations, param, v1, c1, t1, p1, v2, c2, t2, p2,
|
||||||
overlap) {
|
overlap) {
|
||||||
var startConnected = param.startConnected,
|
// Do not exclude connecting points between two curves if they were part
|
||||||
endConnected = param.endConnected,
|
// of overlap checks. They could be self-overlapping.
|
||||||
|
var excludeStart = !overlap && param.startConnected,
|
||||||
|
excludeEnd = !overlap && param.endConnected,
|
||||||
tMin = /*#=*/Numerical.CURVETIME_EPSILON,
|
tMin = /*#=*/Numerical.CURVETIME_EPSILON,
|
||||||
tMax = 1 - tMin;
|
tMax = 1 - tMin;
|
||||||
if (t1 == null)
|
if (t1 == null)
|
||||||
|
@ -1396,12 +1398,12 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
// which connects back to the beginning, but only if it's not part of
|
// which connects back to the beginning, but only if it's not part of
|
||||||
// a found overlap. The normal intersection will already be found at
|
// a found overlap. The normal intersection will already be found at
|
||||||
// the beginning, and would be added twice otherwise.
|
// the beginning, and would be added twice otherwise.
|
||||||
if (t1 !== null && t1 >= (startConnected ? tMin : 0) &&
|
if (t1 !== null && t1 >= (excludeStart ? tMin : 0) &&
|
||||||
t1 <= (endConnected ? tMax : 1)) {
|
t1 <= (excludeEnd ? tMax : 1)) {
|
||||||
if (t2 == null)
|
if (t2 == null)
|
||||||
t2 = Curve.getParameterOf(v2, p2);
|
t2 = Curve.getParameterOf(v2, p2);
|
||||||
if (t2 !== null && t2 >= (endConnected ? tMin : 0) &&
|
if (t2 !== null && t2 >= (excludeEnd ? tMin : 0) &&
|
||||||
t2 <= (startConnected ? tMax : 1)) {
|
t2 <= (excludeStart ? tMax : 1)) {
|
||||||
var renormalize = param.renormalize;
|
var renormalize = param.renormalize;
|
||||||
if (renormalize) {
|
if (renormalize) {
|
||||||
var res = renormalize(t1, t2);
|
var res = renormalize(t1, t2);
|
||||||
|
@ -1717,7 +1719,6 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
max(c2p1y, c2s1y, c2s2y, c2p2y)))
|
max(c2p1y, c2s1y, c2s2y, c2p2y)))
|
||||||
return locations;
|
return locations;
|
||||||
// Now detect and handle overlaps:
|
// Now detect and handle overlaps:
|
||||||
if (!param.startConnected && !param.endConnected) {
|
|
||||||
var overlaps = Curve.getOverlaps(v1, v2);
|
var overlaps = Curve.getOverlaps(v1, v2);
|
||||||
if (overlaps) {
|
if (overlaps) {
|
||||||
for (var i = 0; i < 2; i++) {
|
for (var i = 0; i < 2; i++) {
|
||||||
|
@ -1728,7 +1729,6 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
}
|
}
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var straight1 = Curve.isStraight(v1),
|
var straight1 = Curve.isStraight(v1),
|
||||||
straight2 = Curve.isStraight(v2),
|
straight2 = Curve.isStraight(v2),
|
||||||
|
@ -1856,7 +1856,7 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
geomEpsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
|
geomEpsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
|
||||||
straight1 = Curve.isStraight(v1),
|
straight1 = Curve.isStraight(v1),
|
||||||
straight2 = Curve.isStraight(v2),
|
straight2 = Curve.isStraight(v2),
|
||||||
straight = straight1 && straight2;
|
straightBoth = straight1 && straight2;
|
||||||
|
|
||||||
function getLineLengthSquared(v) {
|
function getLineLengthSquared(v) {
|
||||||
var x = v[6] - v[0],
|
var x = v[6] - v[0],
|
||||||
|
@ -1864,7 +1864,6 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
return x * x + y * y;
|
return x * x + y * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (straight) {
|
|
||||||
// Linear curves can only overlap if they are collinear. Instead
|
// Linear curves can only overlap if they are collinear. Instead
|
||||||
// of using the #isCollinear() check, we pick the longer of the
|
// of using the #isCollinear() check, we pick the longer of the
|
||||||
// two lines and see how far the starting and end points of the
|
// two lines and see how far the starting and end points of the
|
||||||
|
@ -1873,10 +1872,21 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
l1 = flip ? v2 : v1,
|
l1 = flip ? v2 : v1,
|
||||||
l2 = flip ? v1 : v2,
|
l2 = flip ? v1 : v2,
|
||||||
line = new Line(l1[0], l1[1], l1[6], l1[7]);
|
line = new Line(l1[0], l1[1], l1[6], l1[7]);
|
||||||
if (line.getDistance(new Point(l2[0], l2[1])) > geomEpsilon ||
|
if (line.getDistance(new Point(l2[0], l2[1])) < geomEpsilon &&
|
||||||
line.getDistance(new Point(l2[6], l2[7])) > geomEpsilon)
|
line.getDistance(new Point(l2[6], l2[7])) < geomEpsilon) {
|
||||||
|
if (!straightBoth &&
|
||||||
|
line.getDistance(new Point(l1[2], l1[3])) < geomEpsilon &&
|
||||||
|
line.getDistance(new Point(l1[4], l1[5])) < geomEpsilon &&
|
||||||
|
line.getDistance(new Point(l2[2], l2[3])) < geomEpsilon &&
|
||||||
|
line.getDistance(new Point(l2[4], l2[5])) < geomEpsilon) {
|
||||||
|
straight1 = straight2 = straightBoth = true;
|
||||||
|
}
|
||||||
|
} else if (straightBoth) {
|
||||||
|
// If both curves are straight and not within geometric epsilon
|
||||||
|
// of each other, there can't be a solution.
|
||||||
return null;
|
return null;
|
||||||
} else if (straight1 ^ straight2) {
|
}
|
||||||
|
if (straight1 ^ straight2) {
|
||||||
// If one curve is straight, the other curve must be straight,
|
// If one curve is straight, the other curve must be straight,
|
||||||
// too, otherwise they cannot overlap.
|
// too, otherwise they cannot overlap.
|
||||||
return null;
|
return null;
|
||||||
|
@ -1908,7 +1918,7 @@ new function() { // Scope for intersection using bezier fat-line clipping
|
||||||
}
|
}
|
||||||
if (pairs.length !== 2) {
|
if (pairs.length !== 2) {
|
||||||
pairs = null;
|
pairs = null;
|
||||||
} else if (!straight) {
|
} else if (!straightBoth) {
|
||||||
// Straight pairs don't need further checks. If we found
|
// Straight pairs don't need further checks. If we found
|
||||||
// 2 pairs, the end points on v1 & v2 should be the same.
|
// 2 pairs, the end points on v1 & v2 should be the same.
|
||||||
var o1 = Curve.getPart(v1, pairs[0][0], pairs[1][0]),
|
var o1 = Curve.getPart(v1, pairs[0][0], pairs[1][0]),
|
||||||
|
|
Loading…
Reference in a new issue