六边形网格中螺旋坐标与轴坐标之间的转换

问题描述 投票:0回答:2

我正在制作一个基于六边形图块的游戏,它会生成螺旋形状的六边形的蜂窝排列。我的目标是将世界位置(例如鼠标单击)转换为螺旋坐标(索引/图层/图层周围的位置)。我想不出如何做到这一点,所以我一直在寻找通过首先转换为轴坐标或从轴坐标转换来简化问题。这怎么办?

我的配置是尖顶的,如下: spiral coordinates layer/position

这是螺旋索引: spiral coordinates index

参考轴坐标:

axial coordinates

我已经有了这些螺旋坐标方程:

const Layer = (index: number): number => {
    return Math.floor((3 + Math.sqrt(12 * index - 3)) / 6);
}
const Position = (index: number, layer: number): number => {
    return index - 3 * layer * (layer - 1) - 1;
}
const Index = (layer: number, position: number): number => {
    return 3 * layer * (layer - 1) + 1 + position;
}
math coordinate-systems hexagonal-tiles
2个回答
2
投票

您可以按以下方式查看个别案例。这里

L
是图层,
P
是位置,
(x, y)
是轴坐标;坐标与您的图像一致。

(L, P)
(x, y)

if L == 0:
   return (0,0)

otherwise:
k = floor(P/L) mod 6
j = P mod L

k   x     y     z
-------------------
0   j     L-j   -L
1   L     -j    j-L
2   L-j   -L    j
3   -j    j-L   L
4   -L    j     L-j
5   j-L   L     -j

(x, y)
(L, P)

z = -x-y
L = max(abs(x), abs(y), abs(z))

  x    y    z       P
------------------------
>=0  >=0              x
      <0   <0     L - y
>=0       >=0    2L + z
 <0   <0         3L - x
     >=0  >=0    4L + y
 <0        <0    5L - z

免责声明:我没有对此进行测试。

您还可以通过利用对称性来折叠某些情况,但直接编码可能会更容易,尽管有点冗长。

您已经编写了在

(L, P)
和螺旋之间运行的函数。


0
投票

我正在寻找这个问题的答案,不需要条件。我提出的解决方案基于Amit Patel 的六角网格指南中的螺旋算法。

它依赖于您可以对轴坐标进行求和和缩放的事实。六边形有 6 个邻居,其相对轴坐标为 [(1, 0), (1, -1), (0, -1), (-1, 0), (-1, 1), (0, 1)]。您可以将任何十六进制定义为两个相对轴坐标的总和。我不太知道如何用文字解释这一点,所以图表: Explanation of how to find an example hexagon (in this case hexagon 23) by summing two neighbor axial vectors [-3, 0] and [0, -2]

我的图表适用于“平顶”六边形,但“点顶”六边形的逻辑是相同的。计算轴向位置的步骤是。

  1. 计算层数,以及位置。
  2. 位置和模数加 1 6*层。这并不是绝对必要的,但使其遵循之前相同的索引结构。
  3. 按层、楼层划分位置。这为您提供了图层“周围”的方向。在图中,这是向量 [0, -1]。
  4. 方向加 4,模数加 6。根据您是平顶还是点顶,这可能会改变,因此请进行实验。确保您的轴向相邻向量列表位于“循环”中。我上面分享的列表效果很好。这为您提供了“到”图层的方向。在图中,这是向量 [-1, 0]。
  5. 将“out to”向量乘以层数,将“around”向量乘以层数的位置模数。
  6. 将两个最终向量相加,得到轴坐标!

Python 的实现可能是:

neighbor_vec = ((1, 0), (1, -1), (0, -1), (-1, 0), (-1, 1), (0, 1))

layer = int(3 + Math.sqrt(12 * index - 3)) // 6
position = (index - 3 * layer * (layer - 1)) % (6 * layer)

direction = position // layer
along = neighbor_vec[direction]
out_to = neighbor_vec[(direction + 4) % 6]

along_scale = position % layer

q = along[0]*along_scale + out_to[0]*layer
r = along[1]*along_scale + out_to[1]*layer
© www.soinside.com 2019 - 2024. All rights reserved.