I am currently working with a hexagonal grid of cells which are indexed like this:
I am trying to find the simplest way to iterate over a circular area of this grid. For example, with (3, 3)
as the center cell and a radius of one cell, I would want the loop to iterate over the cells (3, 3), (4, 4), (4, 3), (4, 2), (3, 2), (2, 3), (3, 4)
(in any order). Given the coordinate of the center cell and a radius (excluding the center cell), how would you construct a two-dimensional loop to iterate over each cell/coordinate?
CodePudding user response:
The basic idea:
Let's scan each row of the hexagon left-to-right.
How to do it:
Let R be the "cell radius".
- Start at the center and move left R cells. Call this cell "A". A's row has 2*R-1 cells in it.
- Now step one cell up/right. This cell begins a row with one less cell.
- Repeat step 2 until you've stepped up/right R times.
This covers the top half. Now do the lower half with similar steps (stepping down/right starting from A, to find the beginning of each of those rows).
Details
How do you step up/right? The y coordinate increases by 1. The x coordinate increases by 1 only if y was odd.
How do you step down/right? The y coordinate decreases by 1. The x coordinate increases by 1 only if y was odd.
CodePudding user response:
The choice of grid system is what makes this one complicated. Because, for example, a step down and right might change your coordinates by (1, -1)
or (0, -1)
depending on which row you are in.
Therefore I would move to a different grid system, do the calculation there, then switch back to the grid system that you're showing.
Here is a demonstration of that in Python.
def loop (center, radius):
if 0 == radius:
yield center
else:
directions = [
( 1, -1),
( 0, -1),
(-1, 0),
(-1, 1),
( 0, 1),
( 1, 0),
]
cell = list(to_normalized(center))
cell[1] = radius
for direction in directions:
for i in range(radius):
cell[0] = direction[0]
cell[1] = direction[1]
yield to_grid(cell)
def to_normalized (cell):
return (cell[0] - (cell[1] // 2), cell[1])
def to_grid (cell):
return (cell[0] (cell[1] // 2), cell[1])
for cell in loop((3, 3), 2):
print(cell)