获取六角形网格中的瓷砖环


17

感谢这篇文章:六角砖并找到它们的相邻邻居,我能够将相邻砖收集到给定的砖中。但是我几乎迷上了一种算法,该算法只给我一个由偏移量指定的图块“环”。Stack Overflow帖子中给出的算法并不完全在乎它收集图块的顺序。

我知道每个偏移量都会添加6个图块。

  • 偏移1为您提供6个图块(第一个相邻图块)。
  • 偏移2给您12。
  • 偏移3给您18,依此类推。

每个偏移量持续增长6。因此,我认为应该有一个适应这些偏移的规则。我不能完全弄清楚这一点。任何人?

Answers:


23

半径为N的六边形环由6条直线组成,每条直线的长度为N-参见下面的示例::对于N = 2:

在此处输入图片说明

箭头各覆盖2个十六进制。

我假设您有一些函数可以为您提供特定方向的相邻图块,例如north(),southeast()等。因此,您的算法(采用伪代码)应如下所示:

var point = startingPoint.north(N)
for i = 0..N-1:
    result.add(point)
    point = point.southeast(1);
for i = 0..N-1:
    result.add(point)
    point = point.south(1);
for i = 0..N-1:
    result.add(point)
    point = point.southwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.northwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.north(1);
for i = 0..N-1:
    result.add(point)
    point = point.northeast(1);

注意,这对于N = 1,返回6个图块,N = 0,返回空集的边缘情况也适用。

我知道代码不是完美的:)这里有些冗余。在使用规则平铺地图(六角形或其他形式)的项目中,我通常会有一个枚举“ Direction”,这使我可以更顺畅地执行此操作:

var point = startingPoint.inDir(N, Direction.North)
var dir = Direction.SouthEast.
for d = 0..Direction.count():
    for i = 0..N-1:
        result.add(point)
        point = point.inDir(1, dir);
    dir = nextDirection(dir);

这应该将我推向正确的方向。谢谢!
2013年

2
请注意,该代码示例将为前五个段添加重复点。但是,这是一个很好的答案。
MichaelHouse

@ Byte56是的,我知道了。但是至少我看到方向转换之间的联系!
2013年

1
@ Byte56真的吗?嗯 我试图避免那种情况... 0..N-1对于N = 2给出0..1,所以i = 0和i = 1,这是2个值。每个6方向的2个值应为12个图块,因为它应该是...?

不。你是对的。由于每个循环都在最后一个循环中添加了一个点,因此我错了一个循环。这是一个聪明的算法。
MichaelHouse

2

我发现本文是六角网格算法的很好参考,其“距离”部分提供了一种确定两个图块之间步数的方法。如果将轴向坐标(xy)转换为立方体坐标(xyz),则该距离始终等于两个图块之间的最大坐标偏移量,即max(| dx |,| dy |,| dz |)。

在整个网格中详尽搜索所需距离的图块是 Øñ2 与网格尺寸有关,但这是一个简单的实现,适用于小型网格。

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.