Created
February 18, 2020 02:21
-
-
Save HexDecimal/0c21a64e9a86d25603a4d1ddd2b9c397 to your computer and use it in GitHub Desktop.
Rotate a NumPy array by 45 degrees.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To the extent possible under law, Kyle Stewart has waived all copyright and | |
# related or neighboring rights to this work. | |
# This work is published from: United States. | |
import functools | |
from typing import Any, Tuple | |
import numpy as np # type: ignore | |
@functools.lru_cache | |
def ring(radius: int, offset: int = 0, roll: int = 0) -> Tuple[np.ndarray, np.ndarray]: | |
"""Return an advanced NumPy index of a ring on the array.""" | |
index: Any = [] | |
for x in range(-radius, radius + 1): | |
index.append((x, -radius)) | |
for y in range(-radius + 1, radius + 1): | |
index.append((radius, y)) | |
for x in range(radius - 1, -radius, -1): | |
index.append((x, radius)) | |
for y in range(radius, -radius, -1): | |
index.append((-radius, y)) | |
index = np.transpose(index) | |
index += offset | |
index = np.roll(index, roll, 1) | |
index.flags["WRITEABLE"] = False | |
return index[0], index[1] | |
def rotate45(arr: Any, times: int = 1) -> np.ndarray: | |
"""Return a 2D array rotated by 45 degrees. | |
`arr` is a square array-like object with an odd-numbered size. | |
`times` is the number of times to rotate the array counter-clockwise by | |
45 degrees. | |
""" | |
out = np.copy(arr) | |
assert out.shape[0] == out.shape[1] | |
assert out.shape[0] % 2 != 0 | |
times %= 8 | |
radius = offset = out.shape[0] // 2 | |
for i in range(radius + 1): | |
out[ring(i, offset)] = out[ring(i, offset, i * times)] | |
return out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You wanted diagonal tiles so you don't need to go full hexagonal anything. The hexagon examples were all using rectangular arrays, and if that's difficult to understand then I'll have a hard time explaining it.
So back to these:
They might look like two different arrays, but that is wrong. They are the same array but with a different way of representing them. The lower representation makes it clear how they're stored as a contiguous array. The above is how you want to display them.
So where X goes SW and Y goes SE:
To convert the tile index from a grid to where it's displayed you could use a transform function like this basic one:
This kind of math can be "simplified" if you understand how to use transformation matrices.
This is stuff I haven't worked with in a while, and when I did work with it I didn't have NumPy at the time. I might be too rusty on this topic to explain it any better. The best advice I can give you is to tell you that your diamond tiles are just a 2D grid that's been tilted, and you should not "tilt" your data when you store it.