【算法记录/六边形网格】(四)距离

说在前面

立方体坐标(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)
    
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值