Skip to content

Instantly share code, notes, and snippets.

@nihlton
Created May 20, 2020 19:57
Show Gist options
  • Save nihlton/a4d2c6ca463fa31cfc2d4e9321cd56f7 to your computer and use it in GitHub Desktop.
Save nihlton/a4d2c6ca463fa31cfc2d4e9321cd56f7 to your computer and use it in GitHub Desktop.
Simplify SVG path points
export const pruneClosePoints = function (points, factor = .7) {
const culled = new Set()
const pointsWithD = points.map((point, i) => {
const nPoint = points[i + 1] || points[i]
const xDist = points[i][0] - nPoint[0]
const yDist = points[i][1] - nPoint[1]
return [...point, Math.hypot( xDist, yDist ), i]
}).sort((a, b) => b[2] - a[2])
return pointsWithD
.filter((point, i, self) => {
if (i > pointsWithD.length * factor) {
const pIndex = point[3]
const culledNeighbor = culled.has(pIndex - 1)
const isFirstOrLast = pIndex === 0 || pIndex === points.length
if(culledNeighbor || isFirstOrLast) {
return true
} else {
culled.add(point[3])
return false
}
} else {
return true
}
})
.sort((a, b) => a[3] - b[3])
.map(([x, y]) => [x ,y])
}
@nihlton
Copy link
Author

nihlton commented May 20, 2020

simple and fast method of pruning points which are close together.

honestly tho, unless speed is the absolute concern, you should prolly just use simplify.js >> http://mourner.github.io/simplify-js/

walk through:

iterates through all point sets, getting the distance between each point and the next.

generates a new point array (pointsWithD) of items like: [x, y, distance, original index], then sorts it by distance, so that closer points are toward the end.

it then iterates over pointsWithD, and when the iteration index reaches the simplification factor (ex: 70%), it begins culling points.

before a point is culled, the set of culled points is checked to ensure two consecutive points are not removed, to preserve some of the fidelity. This means the final result set may not (and probably will not) conform in size to the simplification factor, and may be larger.

finally, the array is resorted by the original index, and the original index and distance is stripped from the item values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment