目录
说在前面
- 原文地址:Hexagonal Grids,强烈建议原文体验一下
- 上一篇:【算法记录/六边形网格】(二)坐标转换
- 友链:kwen.page
- 其他:不说了,我就是个渣渣
引言
- 给你一个正六边形,如何确定与它相邻的六个正六边形的坐标呢?也许和你想的差不多,在立方体坐标和纵向坐标中是非常简单的,在偏移坐标中就有些难办了。有时,我们还希望可以算正六边形的“对角”上的六个正六边形。
立方体坐标(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])
-
和以前一样,我们可以通过删除三个坐标之一将其转换为轴向坐标,或者通过预先计算结果将其转换为偏移/倍数。