42 lines
1.1 KiB
JavaScript
42 lines
1.1 KiB
JavaScript
import { pointToSegmentDist2 } from './geometry.js';
|
|
|
|
export function simplifyRDP(points, epsilon) {
|
|
if (!Array.isArray(points) || points.length < 3) return points || [];
|
|
const e = Number(epsilon);
|
|
const eps2 = Number.isFinite(e) ? e * e : 0;
|
|
|
|
function rdp(first, last, out) {
|
|
let maxD2 = 0;
|
|
let idx = -1;
|
|
|
|
const a = points[first];
|
|
const b = points[last];
|
|
|
|
for (let i = first + 1; i < last; ++i) {
|
|
const d2 = pointToSegmentDist2(points[i], a, b);
|
|
if (d2 > maxD2) {
|
|
maxD2 = d2;
|
|
idx = i;
|
|
}
|
|
}
|
|
|
|
if (maxD2 > eps2 && idx !== -1) {
|
|
rdp(first, idx, out);
|
|
out.pop();
|
|
rdp(idx, last, out);
|
|
} else {
|
|
out.push(a, b);
|
|
}
|
|
}
|
|
|
|
const out = [];
|
|
rdp(0, points.length - 1, out);
|
|
|
|
const deduped = [out[0]];
|
|
for (let i = 1; i < out.length; i++) {
|
|
const prev = deduped[deduped.length - 1];
|
|
const cur = out[i];
|
|
if (prev.x !== cur.x || prev.y !== cur.y) deduped.push(cur);
|
|
}
|
|
return deduped;
|
|
}
|