マウスやタッチで描いた軌跡を扱う際にすべての頂点を用いるのは煩雑なので点群を簡略化したい、といった時にどうしたらいいか調べてみた。
線を引く場合に mousemove
イベントコールバックで得られた点をつないでいくが、のちのち扱う場合にはまっすぐな部分の途中の点は無駄なので省いてしまいたい。
まっすぐかどうかをどうやって判定したらいいか、曲率を考慮して求められないかなどと考えていたんだけど、
Ramer–Douglas–Peucker法
というアルゴリズムがあるとのことで試してみた。
アルゴリズムは非常に簡潔で、
- 始点と終点を結ぶ直線に対して垂線をおろしたとき、中点の中で距離が一番遠いものを選ぶ
- 距離が基準値以下だったら直線とみなして、間の点は省く
- 基準値以上だったら中点で分割して、再帰的に繰り返す
// Ramer-Douglas-Peucker algorithm. |
精度も制御できて、結果もいい感じ。
このアルゴリズムを使えば、例えば一定時間ごとにGPSで緯度経度を記録したものをマップ上に表示する際にズームに合わせて間引くなど、いろいろ応用できると思う。