目录
说在前面
- 原文地址:Hexagonal Grids,强烈建议原文体验一下
- 上一篇:【算法记录/六边形网格】(三)邻域
- 友链:kwen.page
- 其他:不说了,我就是个渣渣
立方体坐标(Cube coordinates)
-
在立方体坐标表示中,网格中的每一个正六边形其实对应的是三维空间中的一个立方体(见第一节)。在正六边形网格,相邻元素之间的距离是1,而对应到立方体网格中的立方体之后,相邻距离其实是2(想象下
x+y+z=0
这个平面)。 -
我们知道,在方形网格中,两个点的曼哈顿距离为
abs(dx)+abs(dy)
。而在立方体网格中,两点间的曼哈顿距离为abs(dx)+abs(dy)+abs(dz)
,六边形网格中两点距离就是它的一半。 -
伪代码
function cube_distance(a, b): return (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z)) / 2
-
另一种等效的方法是选取三个轴上距离的最大值,这是因为三轴上的距离必须会满足其中一个等于另外两个之和(例如
abs(a.x - b.x) + abs(a.y - b.y) = abs(a.z - b.z)
)。 -
伪代码
function cube_distance(a, b): return max(abs(a.x - b.x), abs(a.y - b.y), abs(a.z - b.z))
-
我们还可以使用
abs(dx-dy)
、abs(dy-dz)
、abs(dz-dx)
的最值来判断两个六边形之间的相对方位;详见这里
纵向坐标(Axial coordinates)
- 在纵向坐标系中,由于第三个坐标是隐式的,所以我们可以简单将其转换为立方体坐标再进行计算。
- 伪代码
function hex_distance(a, b): // 将纵向坐标转换为立方体坐标 var ac = axial_to_cube(a) var bc = axial_to_cube(b) // 使用立方体坐标进行计算 return cube_distance(ac, bc)
- 更直接一点的伪代码
function hex_distance(a, b): return (abs(a.q - b.q) /* abs( (-a.q-a.r) - (-b.q-b.r) ) */ + abs(a.q + a.r - b.q - b.r) + abs(a.r - b.r)) / 2
- 事实上,纵向坐标距离表达式有许多种不同的形式,但是记住一点,他们都继承于立方体网格上的曼哈顿距离。
偏移坐标(Offset coordinates)
- 和纵向坐标一样,我们将偏移坐标转换为立方体坐标之后再进行计算。
- 伪代码
function offset_distance(a, b): // 偏移坐标转换为立方体坐标后进行计算 var ac = offset_to_cube(a) var bc = offset_to_cube(b) return cube_distance(ac, bc)
- 在许多情景下,我们都会使用这种模式:先将坐标转换为立方体坐标,执行立方体坐标系下的算法,最后将结果转换到原来的坐标系下。虽然我们也有一些直接的计算坐标的算法,例如rot.js
倍化坐标(Doubled coordinates)
- 尽管将倍化坐标转换为立方体坐标再进行运算是一种方式,但是这里我们使用一种直接一点的方法。
- 伪代码
function doublewidth_distance(a, b): var dx = abs(a.col - b.col) var dy = abs(a.row - b.row) return dy + max(0, (dx-dy)/2) function doubleheight_distance(a, b): var dx = abs(a.col - b.col) var dy = abs(a.row - b.row) return dx + max(0, (dy−dx)/2)