Further simplify getNearestPoint() algorithm.

This commit is contained in:
Jürg Lehni 2013-05-07 00:07:18 -07:00
parent f34fe102a4
commit 7b8e27ddd9
2 changed files with 13 additions and 17 deletions

View file

@ -910,46 +910,41 @@ statics: {
}, },
getNearestLocation: function(point) { getNearestLocation: function(point) {
point = Point.read(arguments);
var values = this.getValues(), var values = this.getValues(),
precision = 1 / 100, step = 1 / 100,
tolerance = Numerical.TOLERANCE, tolerance = Numerical.TOLERANCE,
minDist = Infinity, minDist = Infinity,
minT = 0, minT = 0,
max = 1 + tolerance; // Accomodate imprecision max = 1 + tolerance; // Accomodate imprecision
// First scan roughly for a close location function refine(t) {
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) {
if (t >= 0 && t <= 1) { if (t >= 0 && t <= 1) {
var dist = point.getDistance( var dist = point.getDistance(
Curve.evaluate(values, t, true, 0), true); Curve.evaluate(values, t, true, 0), true);
if (dist < minDist) { if (dist < minDist) {
minT = t;
minDist = dist; minDist = dist;
minT = t;
return true; return true;
} }
} }
} }
for (var t = 0; t <= max; t += step)
refine(t);
// Now iteratively refine solution until we reach desired precision. // Now iteratively refine solution until we reach desired precision.
while (precision > tolerance) { step /= 2;
if (!closer(minT - precision) && !closer(minT + precision)) while (step > tolerance) {
precision /= 2; if (!refine(minT - step) && !refine(minT + step))
step /= 2;
} }
var pt = Curve.evaluate(values, minT, true, 0); var pt = Curve.evaluate(values, minT, true, 0);
return new CurveLocation(this, minT, pt, null, point.getDistance(pt)); return new CurveLocation(this, minT, pt, null, point.getDistance(pt));
}, },
getNearestPoint: function(point) { getNearestPoint: function(point) {
return this.getNearestLocation(point).getPoint(); return this.getNearestLocation.apply(this, arguments).getPoint();
} }
/** /**

View file

@ -1539,6 +1539,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
* the specified point * the specified point
*/ */
getNearestLocation: function(point) { getNearestLocation: function(point) {
point = this._matrix.inverseTransform(Point.read(arguments));
var curves = this.getCurves(), var curves = this.getCurves(),
minDist = Infinity, minDist = Infinity,
minLoc = null; minLoc = null;