From 0ce89fa47c11868e089e9c127fc2449988d7b9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 20 Feb 2014 17:02:32 +0100 Subject: [PATCH] Simplify self-intersecting code in PathItem#getIntersections() by passing on tMin, tMax, uMin & uMax to Curve#getIntersections(). --- src/path/Curve.js | 32 +++++++++++++++++++++----------- src/path/PathItem.js | 44 ++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/path/Curve.js b/src/path/Curve.js index 8b42e93a..3962c3a7 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -1134,7 +1134,8 @@ new function() { // Scope for methods that require numerical integration if ((Curve.isLinear(v1) || Curve.isFlatEnough(v1, tolerance)) && (Curve.isLinear(v2) || Curve.isFlatEnough(v2, tolerance))) { // See if the parametric equations of the lines interesct. - addLineIntersection(v1, v2, curve1, curve2, locations); + addLineIntersection(v1, v2, curve1, curve2, locations, + tMin, tMax, uMin, uMax); } else { // Subdivide both curves, and see if they intersect. // If one of the curves is flat already, no further subdivion @@ -1144,7 +1145,7 @@ new function() { // Scope for methods that require numerical integration for (var i = 0; i < 2; i++) for (var j = 0; j < 2; j++) Curve.getIntersections(v1s[i], v2s[j], curve1, curve2, - locations); + locations, tMin, tMax, uMin, uMax); } } return locations; @@ -1273,7 +1274,8 @@ new function() { // Scope for methods that require numerical integration * line is on the X axis, and solve the implicit equations for the X axis * and the curve. */ - function addCurveLineIntersections(v1, v2, curve1, curve2, locations) { + function addCurveLineIntersections(v1, v2, curve1, curve2, locations, + tMin, tMax, uMin, uMax) { var flip = Curve.isLinear(v1), vc = flip ? v2 : v1, vl = flip ? v1 : v2, @@ -1313,14 +1315,16 @@ new function() { // Scope for methods that require numerical integration var tl = Curve.getParameterOf(rvl, x, 0), t1 = flip ? tl : tc, t2 = flip ? tc : tl; - locations.push(new CurveLocation( - curve1, t1, Curve.evaluate(v1, t1, 0), - curve2, t2, Curve.evaluate(v2, t2, 0))); + if (t1 >= tMin && t1 <= tMax && t2 >= uMin && t2 <= uMax) + locations.push(new CurveLocation( + curve1, t1, Curve.evaluate(v1, t1, 0), + curve2, t2, Curve.evaluate(v2, t2, 0))); } } } - function addLineIntersection(v1, v2, curve1, curve2, locations) { + function addLineIntersection(v1, v2, curve1, curve2, locations, + tMin, tMax, uMin, uMax) { var point = Line.intersect( v1[0], v1[1], v1[6], v1[7], v2[0], v2[1], v2[6], v2[7]); @@ -1329,7 +1333,10 @@ new function() { // Scope for methods that require numerical integration // since they will be used for sorting var t1 = Curve.getParameterOf(v1, point.x, point.y), t2 = Curve.getParameterOf(v2, point.x, point.y); - locations.push(new CurveLocation(curve1, t1, point, curve2, t2, point)); + if (t1 >= tMin && t1 <= tMax && t2 >= uMin && t2 <= uMax) + locations.push(new CurveLocation( + curve1, t1, point, + curve2, t2, point)); } } @@ -1337,7 +1344,8 @@ new function() { // Scope for methods that require numerical integration // We need to provide the original left curve reference to the // #getIntersections() calls as it is required to create the resulting // CurveLocation objects. - getIntersections: function(v1, v2, curve1, curve2, locations) { + getIntersections: function(v1, v2, curve1, curve2, locations, + tMin, tMax, uMin, uMax) { var linear1 = Curve.isLinear(v1), linear2 = Curve.isLinear(v2); (linear1 && linear2 @@ -1347,8 +1355,10 @@ new function() { // Scope for methods that require numerical integration : addCurveIntersections)(v1, v2, curve1, curve2, locations, // Define the defaults for these parameters of // addCurveIntersections(): - // tMin, tMax, uMin, uMax, oldTDiff, reverse, recursion - 0, 1, 0, 1, 0, false, 0); + // tMin, tMax, uMin, uMax + tMin || 0, tMax || 1, uMin || 0, uMax || 1, + // oldTDiff, reverse, recursion + 0, false, 0); return locations; } }}; diff --git a/src/path/PathItem.js b/src/path/PathItem.js index f7e12138..15640539 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -69,7 +69,6 @@ var PathItem = Item.extend(/** @lends PathItem# */{ if (!selfOp && !this.getBounds().touches(path.getBounds())) return []; var locations = [], - locs = [], curves1 = this.getCurves(), curves2 = selfOp ? curves1 : path.getCurves(), matrix1 = this._matrix.orNullIfIdentity(), @@ -96,37 +95,30 @@ var PathItem = Item.extend(/** @lends PathItem# */{ // property. if (new Line(seg1._point.subtract(h1), h1, true).intersect( new Line(seg2._point.subtract(h2), h2, true), false)) { - locs.length = 0; - var parts = Curve.subdivide(values1); + var parts = Curve.subdivide(values1), + before = locations.length; Curve.getIntersections(parts[0], parts[1], curve1, curve1, - locs); - for (var j = locs.length - 1; j >= 0; j--) { - var loc = locs[j]; - if (loc._parameter <= ONE) { - loc._parameter /= 2; - loc._parameter2 = (loc._parameter2 + 1) / 2; - locations.push(loc); - break; - } + locations, 0, ONE); // tMax + // Check if a location was added by comparing length before. + if (locations.length > before) { + var loc = locations[before]; + // Since the curve has split itself, we need to adjust + // the parameters for both locations. + loc._parameter /= 2; + loc._parameter2 = 0.5 + loc._parameter2 / 2; } } } // Check for intersections with other curves for (var j = selfOp ? i + 1 : 0; j < length2; j++) { - // Avoid end point intersections on consecutive curves - if (selfOp && (j === i + 1 || (j === length2 - 1 && i === 0))) { - locs.length = 0; - Curve.getIntersections(values1, values2[j], curve1, - curves2[j], locs); - for (var k = locs.length - 1; k >= 0; k--) { - var loc = locs[k], - t = loc.getParameter(); - if (t > ZERO && t < ONE) - locations.push(loc); - } - } else { - Curve.getIntersections(values1, values2[j], curve1, - curves2[j], locations); + // Avoid end point intersections on consecutive curves whe self + // intersecting. + var excludeEnds = selfOp && (j === i + 1 + || (j === length2 - 1 && i === 0)); + Curve.getIntersections(values1, values2[j], curve1, + curves2[j], locations, + excludeEnds ? ZERO : 0, // tMin + excludeEnds ? ONE : 1); // tMax } } }