diff --git a/src/index.html b/src/index.html index 490bdbc..ceeba06 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,7 @@ Tauri App - + diff --git a/src/main.js b/src/main.js index 9d5bc7e..50e421c 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,8 @@ const { invoke } = window.__TAURI__.core; import * as fitCurve from '/fit-curve.js'; +let simplifyPolyline = simplify + let greetInputEl; let greetMsgEl; let rootPane; @@ -96,27 +98,23 @@ class Shape { addCurve(curve) { this.curves.push(curve) } - simplify(mode="smooth") { + simplify(mode="corners") { // Mode can be corners, smooth or auto if (mode=="corners") { - let angles; - while (this.curves.length > 3) { - angles = [2*Math.PI] - for (let i=1; i 1) { + x = p2.x; + y = p2.y; + + } else if (t > 0) { + x += dx * t; + y += dy * t; + } + } + + dx = p.x - x; + dy = p.y - y; + + return dx * dx + dy * dy; +} +// rest of the code doesn't care about point format + +// basic distance-based simplification +function simplifyRadialDist(points, sqTolerance) { + + var prevPoint = points[0], + newPoints = [prevPoint], + point; + + for (var i = 1, len = points.length; i < len; i++) { + point = points[i]; + + if (getSqDist(point, prevPoint) > sqTolerance) { + newPoints.push(point); + prevPoint = point; + } + } + + if (prevPoint !== point) newPoints.push(point); + + return newPoints; +} + +function simplifyDPStep(points, first, last, sqTolerance, simplified) { + var maxSqDist = sqTolerance, + index; + + for (var i = first + 1; i < last; i++) { + var sqDist = getSqSegDist(points[i], points[first], points[last]); + + if (sqDist > maxSqDist) { + index = i; + maxSqDist = sqDist; + } + } + + if (maxSqDist > sqTolerance) { + if (index - first > 1) simplifyDPStep(points, first, index, sqTolerance, simplified); + simplified.push(points[index]); + if (last - index > 1) simplifyDPStep(points, index, last, sqTolerance, simplified); + } +} + +// simplification using Ramer-Douglas-Peucker algorithm +function simplifyDouglasPeucker(points, sqTolerance) { + var last = points.length - 1; + + var simplified = [points[0]]; + simplifyDPStep(points, 0, last, sqTolerance, simplified); + simplified.push(points[last]); + + return simplified; +} + +// both algorithms combined for awesome performance +function simplify(points, tolerance, highestQuality) { + + if (points.length <= 2) return points; + + var sqTolerance = tolerance !== undefined ? tolerance * tolerance : 1; + + points = highestQuality ? points : simplifyRadialDist(points, sqTolerance); + points = simplifyDouglasPeucker(points, sqTolerance); + + return points; +} + +// export as AMD module / Node module / browser or worker variable +if (typeof define === 'function' && define.amd) define(function() { return simplify; }); +else if (typeof module !== 'undefined') { + module.exports = simplify; + module.exports.default = simplify; +} else if (typeof self !== 'undefined') self.simplify = simplify; +else window.simplify = simplify; + +})();