如果您需要某种东西在任何距离上都保持线性(不像distance^2
),但看起来模糊地是圆形的(不像方形的切比雪夫和类似曼哈顿的菱形距离),则可以对后两种技术求平均值,以获得八边形的距离近似值:
dx = abs(x1 - x0)
dy = abs(y1 - y0)
dist = 0.5 * (dx + dy + max(dx, dy))
感谢Wolfram Alpha,这是该函数的可视化(轮廓图):
这是与欧几里得距离(弧度,仅第一象限)相比时其误差函数的图:
如您所见,误差范围从轴上的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%
在网上搜索该算法的名称时,我发现了类似的八边形近似值:
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
and max
调用排除在外,从而支持:
if (dy > dx)
swap(dx, dy)
dist = 1007/1024 * dx + 441/1024 * dy
这会比我的版本快吗?谁知道...取决于编译器以及编译器如何针对目标平台进行优化。我的猜测是很难看到任何区别。