diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 39c4ebb6..9435b6af 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -91,44 +91,47 @@ PathItem.inject({ function sortIx(a, b) { return b.parameter - a.parameter; } - var paths = {}; + var pathIds = {}, + paths = []; for (var i = 0, l = _ixs.length; i < l; i++) { - var ix = other ? _ixs[i].getIntersection() : _ixs[i]; - if (!paths[ix.path.id]) - paths[ix.path.id] = ix.path; - if (!ix.curve._ixParams) - ix.curve._ixParams = []; - ix.curve._ixParams.push({ - parameter: ix.parameter, + var ix = other ? _ixs[i].getIntersection() : _ixs[i], + path = ix.getPath(), + curve = ix.getCurve(); + // Add each path only once to the array + if (!pathIds[path._id]) { + paths.push(path); + pathIds[path._id] = true; + } + if (!curve._ixParams) + curve._ixParams = []; + curve._ixParams.push({ + parameter: ix.getParameter(), pair: ix.getIntersection() }); } - for (var k in paths) { - if (!paths.hasOwnProperty(k)) - continue; - var path = paths[k], - lastNode = path.lastSegment, - firstNode = path.firstSegment, - nextNode = null; - while (nextNode !== firstNode) { - nextNode = (nextNode)? nextNode.previous: lastNode; - if (nextNode.curve._ixParams) { - var ixs = nextNode.curve._ixParams, - crv = nextNode.getCurve(), - isLinear = crv.isLinear(), + for (var i = 0, l = paths.length; i < l; i++) { + var path = paths[i], + segments = path._segments; + for (var j = segments.length - 1; j >= 0; j--) { + var nextNode = segments[j], + curve = nextNode.getCurve(), + ixs = curve._ixParams, + amount = ixs && ixs.length; + if (amount > 0) { + ixs.sort(sortIx); + var isLinear = curve.isLinear(), vals = null, segment; - ixs.sort(sortIx); - for (var i = 0, l = ixs.length; i < l; i++) { - var ix = ixs[i], + for (var k = 0; k < amount; k++) { + var ix = ixs[k], t = ix.parameter; if (!vals) - vals = crv.getValues(); + vals = curve.getValues(); if (t === 0 || t === 1) { // Intersection is on an existing node: No need to // create a new segment, we just link the // corresponding intersections together - segment = t === 0 ? crv.segment1 : crv.segment2; + segment = t === 0 ? curve.segment1 : curve.segment2; } else { var parts = Curve.subdivide(vals, t), left = parts[0], @@ -136,10 +139,10 @@ PathItem.inject({ segment = new Segment( new Point(right[0], right[1])); if (!isLinear) { - crv.segment1.handleOut = new Point( + curve.segment1.handleOut = new Point( left[2] - left[0], left[3] - left[1]); - crv.segment2.handleIn = new Point( + curve.segment2.handleIn = new Point( right[4] - right[6], right[5] - right[7]); segment.handleIn = new Point( @@ -149,15 +152,15 @@ PathItem.inject({ right[2] - left[6], right[3] - left[7]); } - path.insert(nextNode.index + 1, segment); - crv = nextNode.getCurve(); + path.insert(j + 1, segment); + curve = nextNode.getCurve(); vals = left; } segment._ixPair = ix.pair; segment._ixPair._segment = segment; // Readjust parameters after splitting - for (var j = i + 1; j < l; j++) - ixs[j].parameter /= t; + for (var n = k + 1; n < amount; n++) + ixs[n].parameter /= t; } } }