Monday, November 7, 2016

algorithm - Get ring of tiles in hexagon grid



Thanks to this post: Hexagonal tiles and finding their adjacent neighbours, I'm able to collect adjacent tiles to a given tile. But I'm pretty much stuck on an algorithm that gives me only a "ring" of tiles specified by an offset. The algorithm given in that Stack Overflow post doesn't exactly care about the order in which it collects the tiles.


I know that with every offset 6 tiles are added.



  • Offset 1 gives you 6 tiles (the first adjacent tiles).

  • Offset 2 gives you 12.

  • Offset 3 gives you 18, etc.


There is a constant growth of 6 with each offset. So I assume there should be a rule which adapts to these offsets. I can't exactly figure this one out. Anyone?



Answer



A hexagonal ring with the radius of N consists of 6 straight lines, each with length N - see my extremely crude example below :) For N=2:



enter image description here


The arrows cover 2 hexes each.


I assume you have some functions which give you the neighbouring tile in a specific direction, like north(), southeast() etc. So your algorithm, in pseudocode, should be something like this:


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);

Note that this should work also for edge cases N=1, returning 6 tiles, and N=0 returning an empty set.


I know the code isn't perfect :) There is some redundancy here. In my projects using regularly tiled maps (hexagonal or otherwise) I usually have an enum "Direction", which allows me to do this more smoothly:


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);

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...