任意の距離にわたって線形のままでありdistance^2
、(正方形のチェビシェフやダイヤモンドのようなマンハッタンの距離とは異なり)漠然と円形に見えるものが必要な場合は、後者の2つの手法を平均して八角形の距離の近似値を取得できます:
dx = abs(x1 - x0)
dy = abs(y1 - y0)
dist = 0.5 * (dx + dy + max(dx, dy))
Wolfram Alphaのおかげで、関数の視覚化(等高線図)ができました。
そして、ユークリッド距離(ラジアン、第1象限のみ)と比較した場合の誤差関数のプロットは次のとおりです。
ご覧のとおり、エラーの範囲は軸上の0%からローブの約+ 12%までです。係数を少し変更することで、+ /-4%に下げることができます。
dist = 0.4 * (dx + dy) + 0.56 * max(dx, dy)
更新
上記の係数を使用すると、最大誤差は+/- 4%以内になりますが、平均誤差は+ 1.3%のままです。平均誤差がゼロになるように最適化されており、以下を使用できます。
dist = 0.394 * (dx + dy) + 0.554 * max(dx, dy)
-5%から+ 3%のエラーと+ 0.043%の平均エラーが発生します
このアルゴリズムの名前をWebで検索しているときに、次のような8角形近似が見つかりました。
dist = 1007/1024 * max(dx, dy) + 441/1024 * min(dx, dy)
これは本質的に同等であることに注意してください(指数は異なりますが、これらは-1.5%から7.5%の誤差を与えますが、+ /-4%にマッサージすることができます)max(dx, dy) + min(dx, dy) == dx + dy
。このフォームを使用すると、min
とのmax
呼び出しを除外して次のことを行うことができます。
if (dy > dx)
swap(dx, dy)
dist = 1007/1024 * dx + 441/1024 * dy
これは私のバージョンよりも速くなりますか?誰が知っている...コンパイラと、それがターゲットプラットフォーム用に最適化する方法に依存します。私の推測では、違いを見ることはかなり難しいでしょう。