【算法记录/六边形网格】(三)邻域

说在前面

引言

  • 给你一个正六边形,如何确定与它相邻的六个正六边形的坐标呢?也许和你想的差不多,在立方体坐标和纵向坐标中是非常简单的,在偏移坐标中就有些难办了。有时,我们还希望可以算正六边形的“对角”上的六个正六边形。

立方体坐标(Cube coordinates)

  • 在该坐标系下,每走一步意味着要将三坐标中的其中一个+1,另外还有一个要-1(三坐标之和要保持0)。从三坐标中选一个+1,在剩下两个中选一个-1,那么总共有6中可能(排列问题)。每一个可能都代表着六边形的一个边的方向。最简单、最快捷的方法是预先计算出对应关系并且将其存储到列表中。
  • 伪代码
    var cube_directions = [
        Cube(+1, -1, 0) /*右*/, Cube(+1, 0, -1) /*右上*/, Cube(0, +1, -1) /*左上*/, 
        Cube(-1, +1, 0) /*左*/, Cube(-1, 0, +1) /*左下*/, Cube(0, -1, +1) /*右下*/, 
    ]
    
    /* 0,1,2,3,4,5 代表着 右,右上,左上,左,左下,右下 */
    function cube_direction(direction):
        return cube_directions[direction]
    
    /* 计算在某个方向上相邻的六边形 */
    function cube_neighbor(cube, direction):
        return cube_add(cube, cube_direction(direction))
    
    在这里插入图片描述

纵向坐标(Axial coordinates)

  • 和之前一样,依旧将立方体坐标去掉一维,并且将对应关系存储到列表中。
  • 伪代码
    var axial_directions = [
        Hex(+1, 0), Hex(+1, -1), Hex(0, -1), 
        Hex(-1, 0), Hex(-1, +1), Hex(0, +1), 
    ]
    /* 0,1,2,3,4,5 代表着 右,右上,左上,左,左下,右下 */
    function hex_direction(direction):
        return axial_directions[direction]
    /* 计算在某个方向上相邻的六边形 */
    function hex_neighbor(hex, direction):
        var dir = hex_direction(direction)
        return Hex(hex.q + dir.q, hex.r + dir.r)
    

偏移坐标(Offset coordinates)

  • 在偏移坐标中,相邻六边形的坐标取决于我们在网格中位置。在偏移行(列)中的六边形的邻域规则和不在偏移行(列)中的不同(其实是奇偶行(列)的规则不同)。

  • 和之前一样,我们依旧会创建对应关系并将其存储到列表中,以便我们可以简单的进行运算。但是,偏移坐标并不能安全地进行加减。对于奇偶行(列),我们需要不同的列表来存储。

  • odd-r

    // 三维数组 oddr_directions[2][6][2]
    var oddr_directions = [
        /* 偶数规则 */
        [[+1,  0], [ 0, -1], [-1, -1], 
         [-1,  0], [-1, +1], [ 0, +1]],
        /* 奇数规则 */
        [[+1,  0], [+1, -1], [ 0, -1], 
         [-1,  0], [ 0, +1], [+1, +1]],
    ]
    
    function oddr_offset_neighbor(hex, direction):
        // 判断奇偶
        var parity = hex.row & 1 
        // 取奇/偶对应的规则
        var dir = oddr_directions[parity][direction]
        // 运算
        return OffsetCoord(hex.col + dir[0], hex.row + dir[1])
    

    在这里插入图片描述

  • even-r

    var evenr_directions = [
        [[+1,  0], [+1, -1], [ 0, -1], 
         [-1,  0], [ 0, +1], [+1, +1]],
        [[+1,  0], [ 0, -1], [-1, -1], 
         [-1,  0], [-1, +1], [ 0, +1]],
    ]
    
    function evenr_offset_neighbor(hex, direction):
        var parity = hex.row & 1
        var dir = evenr_directions[parity][direction]
        return OffsetCoord(hex.col + dir[0], hex.row + dir[1])
    

在这里插入图片描述

  • odd-q
    var oddq_directions = [
        [[+1,  0], [+1, -1], [ 0, -1], 
         [-1, -1], [-1,  0], [ 0, +1]],
        [[+1, +1], [+1,  0], [ 0, -1], 
         [-1,  0], [-1, +1], [ 0, +1]],
    ]
    
    function oddq_offset_neighbor(hex, direction):
        var parity = hex.col & 1
        var dir = oddq_directions[parity][direction]
        return OffsetCoord(hex.col + dir[0], hex.row + dir[1])
    

在这里插入图片描述

  • even-q
    var evenq_directions = [
        [[+1, +1], [+1,  0], [ 0, -1], 
         [-1,  0], [-1, +1], [ 0, +1]],
        [[+1,  0], [+1, -1], [ 0, -1], 
         [-1, -1], [-1,  0], [ 0, +1]],
    ]
    
    function evenq_offset_neighbor(hex, direction):
        var parity = hex.col & 1
        var dir = evenq_directions[parity][direction]
        return OffsetCoord(hex.col + dir[0], hex.row + dir[1])
    

在这里插入图片描述

倍化坐标(Doubled coordinates)

  • 不同于偏移坐标,倍化坐标下的六边形的邻域不取决于在网格中的行/列。邻域规则是相同的,就像在立方体坐标或者纵向坐标中。同样,不同于偏移坐标,我们可以在倍化坐标中安全地进行加减,这意味着在倍化坐标下的运算将比偏移坐标简单。
  • 倍化宽度
    var doublewidth_directions = [
        [+2,  0], [+1, -1], [-1, -1], 
        [-2,  0], [-1, +1], [+1, +1], 
    ]
    
    function doublewidth_neighbor(hex, direction):
        var dir = doublewidth_directions[direction]
        return DoubledCoord(hex.col + dir[0], hex.row + dir[1])
    

在这里插入图片描述

  • 倍化高度
    var doubleheight_directions = [
        [+1, +1], [+1, -1], [ 0, -2], 
        [-1, -1], [-1, +1], [ 0, +2], 
    ]
    
    function doubleheight_neighbor(hex, direction):
        var dir = doubleheight_directions[direction]
        return DoubledCoord(hex.col + dir[0], hex.row + dir[1])
    

在这里插入图片描述

对角域

  • 在六边形网格下移动到对角线空间将使其中一个立方体坐标改变2,另外两个将改变1(和必须保持为0)。

    var cube_diagonals = [
        Cube(+2, -1, -1), Cube(+1, +1, -2), Cube(-1, +2, -1), 
        Cube(-2, +1, +1), Cube(-1, -1, +2), Cube(+1, -2, +1), 
    ]
    
    function cube_diagonal_neighbor(cube, direction):
        return cube_add(cube, cube_diagonals[direction])
    

    在这里插入图片描述

  • 和以前一样,我们可以通过删除三个坐标之一将其转换为轴向坐标,或者通过预先计算结果将其转换为偏移/倍数。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值