From cac86627be3f6bb8b765c70203880dae021f5bd7 Mon Sep 17 00:00:00 2001 From: hkrish Date: Mon, 24 Feb 2014 19:08:39 +0100 Subject: [PATCH] Correct winding number calculation when horizontal curves are involved. --- src/path/PathItem.Boolean.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 2cafe4b4..86a2e258 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -258,7 +258,9 @@ PathItem.inject(new function() { windLeft = 0, windRight = 0, roots = [], - abs = Math.abs; + abs = Math.abs, + ONE = 1 - TOLERANCE, + rootMaxLimit = ONE; // Absolutely horizontal curves may return wrong results, since // the curves are monotonic in y direction and this is an // indeterminate state. @@ -298,7 +300,8 @@ PathItem.inject(new function() { for (var i = 0, l = curves.length; i < l; i++) { var curve = curves[i], values = curve.values, - winding = curve.winding; + winding = curve.winding, + next = curve.next; // Since the curves are monotone in y direction, we can just // compare the endpoints of the curve to determine if the // ray from query point along +-x direction will intersect @@ -306,8 +309,12 @@ PathItem.inject(new function() { var interceptTest = winding === 1 ? (y >= values[1] && y <= values[7]) : (y >= values[7] && y <= values[1]); + // If the next curve is horizontal, we have to include the end + // points of this curve to make sure we won't miss an intercept + rootMaxLimit = (next.winding === 0 && next.values[1] === y) + ? 1 : ONE; if (winding !== 0 && interceptTest && Curve.solveCubic( - values, 1, y, roots, 0, 1 - TOLERANCE) === 1) { + values, 1, y, roots, 0, rootMaxLimit) === 1) { var t = roots[0], x0 = Curve.evaluate(values, t, 0).x, slope = Curve.evaluate(values, t, 1).y;