diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 31783fb9..a38aac3d 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -97,6 +97,17 @@ PathItem.inject(new function() { return result; } + function filterIntersection(inter) { + // TODO: Change isCrossing() to also handle overlaps (hasOverlap()) + // that are actually involved in a crossing! For this we need proper + // overlap range detection / merging first... But as we call + // #resolveCrossings() first in boolean operations, removing all + // self-touching areas in paths, this works for the known use cases. + // The ideal implementation would deal with it in a way outlined in: + // https://github.com/paperjs/paper.js/issues/874#issuecomment-168332391 + return inter.hasOverlap() || inter.isCrossing(); + } + function traceBoolean(path1, path2, operation, options) { // Only support subtract and intersect operations when computing stroke // based boolean operations (options.split = true). @@ -121,8 +132,8 @@ PathItem.inject(new function() { _path2.reverse(); // Split curves at crossings on both paths. Note that for self- // intersection, path2 is null and getIntersections() handles it. - var crossings = divideLocations( - CurveLocation.expand(_path1.getCrossings(_path2))), + var crossings = divideLocations(CurveLocation.expand( + _path1.getIntersections(_path2, filterIntersection))), paths1 = getPaths(_path1), paths2 = _path2 && getPaths(_path2), segments = [], @@ -182,7 +193,7 @@ PathItem.inject(new function() { function splitBoolean(path1, path2, operation) { var _path1 = preparePath(path1), _path2 = preparePath(path2), - crossings = _path1.getCrossings(_path2), + crossings = _path1.getIntersections(_path2, filterIntersection), subtract = operation === 'subtract', divide = operation === 'divide', added = {}, diff --git a/src/path/PathItem.js b/src/path/PathItem.js index e7ff2d17..01000361 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -351,14 +351,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{ */ getCrossings: function(path) { return this.getIntersections(path, function(inter) { - // TODO: Only return overlaps that are actually crossings! For this - // we need proper overlap range detection / merging first... - // But as we call #resolveCrossings() first in boolean operations, - // removing all self-touching areas in paths, this currently works - // as it should in the known use cases. - // The ideal implementation would deal with it in a way outlined in: - // https://github.com/paperjs/paper.js/issues/874#issuecomment-168332391 - return inter.hasOverlap() || inter.isCrossing(); + return inter.isCrossing(); }); }, diff --git a/test/tests/Path_Intersections.js b/test/tests/Path_Intersections.js index 46100e6d..71de7ca9 100644 --- a/test/tests/Path_Intersections.js +++ b/test/tests/Path_Intersections.js @@ -380,3 +380,23 @@ test('#1262', function() { { point: { x: 567.05562, y: 634.62043 }, time: 1 } ]); }); + +test('#1409', function() { + var path1 = new Path({ + segments: [[20, 20], [20, 80], [80, 80], [80, 20]], + closed: true + }); + var path2 = new Path({ + segments: [[80, 20], [80, 80], [140, 80], [140, 20]], + closed: true + }); + testIntersections(path1.getCrossings(path2), []); + + var rect1 = new Path.Rectangle(new Point(100, 100), new Size(100, 100)); + var rect2 = rect1.clone(); + testIntersections(rect1.getCrossings(rect2), []); + + var circ1 = new Path.Circle(new Point(300,300), 40); + var circ2 = circ1.clone(); + testIntersections(circ1.getCrossings(circ2), []); +});