From c5ddbf19da04d55a6f12fa435bc72b0dbd640331 Mon Sep 17 00:00:00 2001 From: hkrish Date: Sun, 26 Jan 2014 05:38:09 +0100 Subject: [PATCH] Remove duplicate intersections in #getIntersections --- src/path/PathItem.js | 54 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/path/PathItem.js b/src/path/PathItem.js index 9ae3f2f0..5a76602e 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -59,7 +59,18 @@ var PathItem = Item.extend(/** @lends PathItem# */{ * } * } */ - getIntersections: function(path) { + getIntersections: function(path, expand) { + function compare(loc1, loc2) { + var path1 = loc1.getPath(), + path2 = loc2.getPath(); + return path1 === path2 + // We can add parameter (0 <= t <= 1) to index + // (a integer) to compare both at the same time + ? (loc1.getIndex() + loc1.getParameter()) + - (loc2.getIndex() + loc2.getParameter()) + // Sort by path id to group all locations on the same path. + : path1._id - path2._id; + } // First check the bounds of the two paths. If they don't intersect, // we don't need to iterate through their curves. if (!this.getBounds().touches(path.getBounds())) @@ -71,7 +82,10 @@ var PathItem = Item.extend(/** @lends PathItem# */{ matrix2 = path._matrix.orNullIfIdentity(), length1 = curves1.length, length2 = curves2.length, - values2 = []; + values2 = [], + tolerance = Numerical.EPSILON, + tolerance1 = 1 - tolerance, + abs = Math.abs; for (var i = 0; i < length2; i++) values2[i] = curves2[i].getValues(matrix2); for (var i = 0; i < length1; i++) { @@ -81,6 +95,42 @@ var PathItem = Item.extend(/** @lends PathItem# */{ Curve.getIntersections(values1, values2[j], curve1, curves2[j], locations); } + // Remove duplicate intersections near curve endings + var loc, locNext; + // Merge intersections very close to the end of a curve to the + // begining of the next curve + for (var i = locations.length-1; i >= 0; i--) { + loc = locations[i]; + locNext = loc._curve.getNext(); + if (loc._parameter >= tolerance1 && locNext) { + loc._parameter = 0; + loc._curve = locNext; + } + locNext = loc._curve2.getNext(); + if (loc._parameter2 >= tolerance1 && locNext) { + loc._parameter2 = 0; + loc._curve2 = locNext; + } + } + locations.sort(compare); + for (var length1 = locations.length - 1, i = length1; i >= 0; i--) { + loc = locations[i]; + locNext = (i === 0)? locations[length1] : locations[i-1]; + if (abs(loc._parameter - locNext._parameter) < tolerance && + loc._curve === locNext._curve && + abs(loc._parameter2 - locNext._parameter2) < tolerance && + loc._curve2 === locNext._curve2) { + locations.splice(i, 1); + --length1; + } + } + if (expand) { + for (var i = locations.length-1; i >= 0; i--) { + loc = locations[i]; + locations.push(loc.getIntersection()); + } + locations.sort(compare); + } return locations; },