Hexagonal Matrix in Python

Posted on

Question :

I would like to know how I could return the numbers of a vector of vectors (array) within a specific R (radius) using Python.

Based on this image:













Ihadmadeanoutdatedcodeforlearningreturninginrectangularformifithelps( link )


Answer :

As you can see from inside Python, you will not use a “hex array” – it will use a two-dimensional structure.

What you need is a way to (1) cycle through the interesting coordinates for you (in this case hexagonal) and (2) map these coordinates “over the hexagon” to numbers in the rectangular matrix. >

To generate the “hexagonal” coordinates given a center and the
ray number, a technique can be to work with an offset of “.5” for the odd lines, and round the value at the time of mapping to the data in the rectangular structure.

So you can think of generating the coordinates for 6 straight segments – we can put the 6 segments in a “for” as directions. For each R ring, we find the coordinate in the upper left corner, and traverse the 6 directions in sequence from there. To get the data in the order you present, just order each coordinate prioritizing the row and then the column in ascending order – this is possible with the use of the “key” parameter in the “sorted” Python function: we use a function that receives a coordinate, and returns it as a tuple “line, column” – this tuple is used as a comparison in ordering the coordinates.

def normaliza(coord):
    return int(coord[0]), int(coord[1])

def extrai_coords(centro, r):
    if r == 0:
        return [centro]
    cx, cy = centro
    if cy % 2 == 0:
        cx += .5
    cursor = [cx - r / 2, cy - r]
    coords = []
    for direcao in [(1, 0), (.5, 1), (-.5, 1), (-1, 0), (-.5, -1), (.5, -1)]:
        for i in range(r):
            cursor[0] += direcao[0]
            cursor[1] += direcao[1]
    return coords

def extrai_dados(mapa, coords):
     return [mapa[coord[1]][coord[0]] for coord in sorted(coords, key=lambda c: (c[1], c[0]))]

At the interactive prompt, using the map you passed, this code snippet has the same outputs as you expect:

In [17]: extrai_dados(mapa, extrai_coords((3,3), 2))
Out[17]: [1.2, 1.3, 1.4, 2.1, 2.4, 3.1, 3.5, 4.1, 4.4, 5.2, 5.3, 5.4]

Finally, note that this is the solution to get concentric rings in hexagon, not the data in a round “R” radius – for larger matrices there is difference.
Also, if your problem depends on this geometry, it’s worth putting it into a class, and specializing both the __repr__ and the __getitem__ and __setitem__ of the class, so you can think straight through this mapping that allows the hexagons , and do not have to worry about “non-integer coordinates” in each operation.


Leave a Reply

Your email address will not be published. Required fields are marked *