Created
February 28, 2021 11:10
-
-
Save steveruizok/ced3e793c552f348e1bcd655fafde910 to your computer and use it in GitHub Desktop.
Simplify a line (using Ramer-Douglas-Peucker algorithm).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Simplify a line (using Ramer-Douglas-Peucker algorithm). | |
* @param points An array of points as [x, y, ...][] | |
* @param tolerance The minimum line distance (also called epsilon). | |
* @returns Simplified array as [x, y, ...][] | |
*/ | |
export function simplify(points: number[][], tolerance = 1) { | |
const len = points.length, | |
a = points[0], | |
b = points[len - 1], | |
[x1, y1] = a, | |
[x2, y2] = b | |
if (len > 2) { | |
let distance = 0, | |
index = 0, | |
max = Math.hypot(y2 - y1, x2 - x1) | |
for (let i = 1; i < len - 1; i++) { | |
const [x0, y0] = points[i], | |
d = Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / max | |
if (distance > d) continue | |
distance = d | |
index = i | |
} | |
if (distance > tolerance) { | |
let l0 = simplify(points.slice(0, index + 1), tolerance) | |
let l1 = simplify(points.slice(index + 1), tolerance) | |
return l0.concat(l1.slice(1)) | |
} | |
} | |
return [a, b] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment