Hexagonal matrix in Python

Asked

Viewed 296 times

2

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

Follow on this image:

inserir a descrição da imagem aqui

Following the vector used:

mapa = [
    [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
    [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6],
    [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6],
    [3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6],
    [4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 0.6],
    [5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6],
    [6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6]
]

Using row 3 node and column 3:

We have the respective exits

In R = 0:

[3.3]

In R = 1:

[2.2, 2.3, 3.2, 3.4, 4.2, 4.3]

In R = 2:

[1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4, 3.1, 3.2, 3.4, 3.5, 4.1, 4.2, 4.3, 4.4, 5.2, 5.3, 5.4]

If we still used an R = 3 we would have the outputs:

[0.1, 0.2, 0.3, 0.4, 1.1, 1.2, 1.3, 1.4, 1.5, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 3.0, 3.1, 3.2, 3.4, 3.5, 3.6, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 5.1, 5.2, 5.3, 5.4, 5.5, 6.1, 6.2, 6.3, 6.4]

I had made a weird code for learning returning in rectangular shape to help (https://github.com/MuriloChaves/Kohonen_Fausett/blob/master/vizinhanca/codigos/vizinhos_bidimensional_retangular.py)

  • 1

    A hexagonal matrix is identical to a "square" matrix, what changes is the calculation of the distance of the coordinates> When processing the distances you have to treat the diagonals of the right (or only of the left) in the same way as the vertical, or subtract/sum an offset of one of the axes when calculating the distances to each even (or odd, line depends on how organized). Do not forget that the Y (in the case of your chart) is not 1, you have to calculate the diagonal distance, and add with the horizontal offset (when it exists) * horizontal factor.

  • 1

    PS: In your case you can simplify using only offset, if only to determine concentric hexagons (without calculating real distance)

  • Does the order of the rotation (and the beginning) matter? Or can I pick up from any angle in any direction?

1 answer

3


As you can see, inside Python, you will not use a "hexagonal matrix" - you will use a two-dimensional structure.

What you need is a way to (1) traverse the interesting coordinates for you (in this case the Hexagono) and (2) map these coordinates "on top of Hexagono" to numbers in the rectangular matrix.

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

So, you can think about generating the coordinates for 6 line segments - we can put in a "for" the 6 segments as directions. For each R ring, we find the coordinate in the upper left corner, and we go through the six directions in sequence from there. To get the data in the order you present, just sort each coordinate prioritizing the row and then the column in ascending order - this is possible with the use of the "key" parameter in the Python "Sorted" function: we use a function that receives a coordinate, and returns it as a tuple "row, column" - this tuple is used as a comparison in the ordering of 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):
            coords.append(normaliza(cursor))
            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 from the same outputs 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 for taking concentric hexagon rings, not the data in a round "R" radius - for larger matrices there is difference. Also, if your problem depends on this geometry myth, it’s worth putting it into a class, and specializing both the __repr__ how much the __getitem__ and __setitem__ of the class, so that you can think directly about this mapping that allows the hexagons, and not have to worry about the "unbroken coordinates" in each operation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.