From 7b8e27ddd99880a3c5950dba7c03f953f32bb3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Tue, 7 May 2013 00:07:18 -0700 Subject: [PATCH] Further simplify getNearestPoint() algorithm. --- src/path/Curve.js | 29 ++++++++++++----------------- src/path/Path.js | 1 + 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/path/Curve.js b/src/path/Curve.js index 19f0d08f..c611f8b1 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -910,46 +910,41 @@ statics: { }, getNearestLocation: function(point) { + point = Point.read(arguments); var values = this.getValues(), - precision = 1 / 100, + step = 1 / 100, tolerance = Numerical.TOLERANCE, minDist = Infinity, minT = 0, max = 1 + tolerance; // Accomodate imprecision - // First scan roughly for a close location - for (var t = 0; t <= max; t += precision) { - var pt = Curve.evaluate(values, t, true, 0), - dist = point.getDistance(pt, true); - if (dist < minDist) { - minDist = dist; - minT = t; - } - } - - function closer(t) { + function refine(t) { if (t >= 0 && t <= 1) { var dist = point.getDistance( Curve.evaluate(values, t, true, 0), true); if (dist < minDist) { - minT = t; minDist = dist; + minT = t; return true; } } } + for (var t = 0; t <= max; t += step) + refine(t); + // Now iteratively refine solution until we reach desired precision. - while (precision > tolerance) { - if (!closer(minT - precision) && !closer(minT + precision)) - precision /= 2; + step /= 2; + while (step > tolerance) { + if (!refine(minT - step) && !refine(minT + step)) + step /= 2; } var pt = Curve.evaluate(values, minT, true, 0); return new CurveLocation(this, minT, pt, null, point.getDistance(pt)); }, getNearestPoint: function(point) { - return this.getNearestLocation(point).getPoint(); + return this.getNearestLocation.apply(this, arguments).getPoint(); } /** diff --git a/src/path/Path.js b/src/path/Path.js index 2993b114..106905be 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -1539,6 +1539,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ * the specified point */ getNearestLocation: function(point) { + point = this._matrix.inverseTransform(Point.read(arguments)); var curves = this.getCurves(), minDist = Infinity, minLoc = null;