From 42f5b5e26ec3f4e15704824539434029d022e049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sun, 5 Jun 2011 21:28:49 +0100 Subject: [PATCH] =?UTF-8?q?Implement=20Douglas=E2=80=93Peucker=20algorithm?= =?UTF-8?q?=20for=20point=20reduction=20before=20the=20curve=20fitting.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/path/PathFitter.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/path/PathFitter.js b/src/path/PathFitter.js index 809e7bc5..6aab8742 100644 --- a/src/path/PathFitter.js +++ b/src/path/PathFitter.js @@ -31,6 +31,7 @@ var PathFitter = Base.extend({ prev = point; } } + this.points = this.reducePoints(this.points, 1); this.error = error; this.iterationError = error * error; }, @@ -46,6 +47,28 @@ var PathFitter = Base.extend({ return this.segments; }, + // Douglas–Peucker algorithm + reducePoints: function(points, tolerance) { + var line = new Line(points[0], points[points.length - 1], false); + var maxDistance = 0, + maxIndex = 0; + for (var i = 1; i < points.length - 1; i++) { + var distance = line.getDistance(points[i]); + if(distance > maxDistance) { + maxDistance = distance; + maxIndex = i; + } + } + if (maxDistance >= tolerance) { + var pts = this.reducePoints( + points.slice(0, maxIndex + 1), tolerance); + pts.pop(); + return pts.concat(this.reducePoints( + points.slice(maxIndex, points.length), tolerance)); + } + return [points[0], points[points.length - 1]]; + }, + // Fit a Bezier curve to a (sub)set of digitized points fitCubic: function(first, last, tHat1, tHat2) { // Use heuristic if region only has two points in it