如何最好地表示六角晶格。

24
我们有一个六边形的晶格:
 _   _   _
/ \_/ \_/ \_ 
\_/ \_/ \_/ \ 
/ \_/ \_/ \_/
\_/ \_/ \_/

最好的方式是使用二维数组或任何其他方法来表示它。


你对节点还是区域感兴趣? - Paul Nathan
2
你想要表示什么?无限格子?矩形有限格子?顶点数据?边缘数据? - Jason S
取决于@Jason列出的事情,以及您计划如何使用它,以及您希望如何存储或访问数据。 - Tom Zych
我对领域感兴趣。格子是无限的。数据在领域中。 - Eugeny89
你想用数据做哪些常见的处理过程? - andrew cooke
3个回答

21
用2D数组表示六边形网格的最简单方法是倾斜坐标轴:每一行六边形都比前一行多偏移半步。每一行向前或向后偏移都无所谓,只要保持一致即可;下面的示例中,每一行都向前偏移半个六边形:
(0,0) (0,1) (0,2) (0,3) (0,4)

   (1,0) (1,1) (1,2) (1,3) (1,4)

      (2,0) (2,1) (2,2) (2,3) (2,4)

         (3,0) (3,1) (3,2) (3,3) (3,4)

确定任何给定六边形的最近邻很容易:在上面的情况下,对于给定的数组地址(r,s),您有:

(r-1, s)
(r-1, s+1)
(r, s-1)
(r, s+1)
(r+1, s-1)
(r+1, s)

另外,请注意绘图位置很简单:上方六边形(r,s)的中心位于屏幕位置:

x= dx * (s + 0.5*r)
y= dy * r

作为替代方案,您可以通过偏移半个十六进制绝对值来交替排列行。这将为给定的数组提供更加矩形的形状,但确定绘图位置和最近邻居则需要分别考虑偶数行和奇数行两种情况。
还有其他可用的坐标系统,但它们不太方便且更加晦涩。

由于OP想了解更多,我会添加一个链接到我最喜欢的不太常见的十六进制索引系统:一个"螺旋蜂窝马赛克"。该系统使用基数为七的系统来索引越来越大的“超级六边形”组合的六边形位置,如下所示(请注意,它是用基数7而不是10标记的):

7 elements:              49 elements:

  2   3
                            22  23
1   0   4  -->
                  12  13  21  20  24
  6   5
                11  10  14  26  25  32  33

                  16  15  02  03  31  30  34   --> [3 base-7 digits
                                                    -> 343 elements...]
                62  63  01  00  04  36  35

              61  60  64  06  05  42  43

                66  65  52  53  41  40  44

                      51  50  54  46  45

                        56  55

这个链接包含一些处理该坐标系的代码,但我还没有真正尝试评估它....


你的解决方案实际上并没有代表答案中所显示的晶格 - 它被旋转了90度。问题的晶格没有直接的水平邻居,但有垂直的邻居。 - andrew cooke
@andrew cooke:真的吗?今天感觉有点挑剔了? :-) 也许用ASCII画图更容易。可以交换r和s的角色并翻转图片... - phkahler
我在想r代表行,s代表倾斜列;C风格的数组约定通常是A[row][column]。当然,正如phkahler所说,你可以按照自己喜欢的方式绘制它... - comingstorm
@comingstorm,感谢您的回答!这是一个有趣的想法。2all,还有其他的想法吗? - Eugeny89
2
在GameDev StackExchange上最近有一个关于转换螺旋蜂窝镶嵌和倾斜坐标系的方法的问题:http://gamedev.stackexchange.com/questions/71785/converting-between-spiral-honeycomb-mosaic-and-axial-hex-coordinates(以及其他索引样式的链接)。 - DMGregory

3
请注意,有四种不同的方式来表示六边形晶格。我花了很多时间搜索解决方案,但无法将它们匹配起来。后来我意识到,建立和表示晶格有四种不同的方法。因此,在选择一种方法时,请确保您要使用哪种格式。以下是四种格式:

enter image description here 图片来源:https://www.redblobgames.com/grids/hexagons/#conversions


3

使用2行=1个六边形高度和1列=1个六边形宽度的2D数组是可以的。

4,1,5,2,6,3
4,7,5,8,6,9
A,7,B,8,C,9
A,D,B,E,C,F
  • 每一对数字是一个十六进制瓷砖。
  • 找到12点和6点只需要进行+-Y操作,直到您到达不同的瓷砖。
  • 找到2点和4点
    • 检查Y+1是否是相同的瓷砖
      • 如果是,2点是X+1,4点是X+1,Y+1
      • 如果不是,2点是X+1,Y-1,4点是X+1

另一种思考这个模式的方式是:取一个正方形格子,根据奇偶性丢弃一半的坐标(例如,只接受/使用那些满足 x+y 为偶数的坐标 (x,y))。当然,你不想浪费一半的数组条目——因此,@LastCoder 上面的排列。 - comingstorm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接