私は3次元のnumpy配列を持っていますポリキューブ(3D テトリスのピースを想像してください)。24 回転すべてを計算するにはどうすればよいですか?
Numpyの配列操作ルーチンには、腐った90この方法では 24 のうち 4 つが得られますが、残りの計算方法がわかりません。私の唯一のアイデアは、3D 配列を 2D 座標行列に変換し、回転行列を掛けて、元に戻すことです。しかし、私はむしろ 3D 配列を直接操作したいと思います。
2x2x2配列の例:
>>> from numpy import array
>>> polycube
array([[[1, 0],
[1, 0]],
[[1, 1],
[0, 0]]])
3x3x3配列の例:
array([[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
編集: 必要なのは、48 の回転と反射すべてではなく、24 の方向保存等長変換だけです (ただし、それらを作成する方法も知っておくと興味深いでしょう)。テストに役立つかどうかはわかりませんが、3x3x3 の例には回転対称性がなく、キラルである (つまり、48 は異なる) と思います。
動機: 私はソルバーを書いていますソマキューブスタイルのパズル。
ベストアンサー1
更新: Numpy 1.12.0で軸引数が追加されたため、簡略化されました。rot90関数
24 回の回転をすべて実行した方法は次のとおりです。
from numpy import rot90, array
def rotations24(polycube):
"""List all 24 rotations of the given 3d array"""
def rotations4(polycube, axes):
"""List the four rotations of the given 3d array in the plane spanned by the given axes."""
for i in range(4):
yield rot90(polycube, i, axes)
# imagine shape is pointing in axis 0 (up)
# 4 rotations about axis 0
yield from rotations4(polycube, (1,2))
# rotate 180 about axis 1, now shape is pointing down in axis 0
# 4 rotations about axis 0
yield from rotations4(rot90(polycube, 2, axes=(0,2)), (1,2))
# rotate 90 or 270 about axis 1, now shape is pointing in axis 2
# 8 rotations about axis 2
yield from rotations4(rot90(polycube, axes=(0,2)), (0,1))
yield from rotations4(rot90(polycube, -1, axes=(0,2)), (0,1))
# rotate about axis 2, now shape is pointing in axis 1
# 8 rotations about axis 1
yield from rotations4(rot90(polycube, axes=(0,1)), (0,2))
yield from rotations4(rot90(polycube, -1, axes=(0,1)), (0,2))
24 回転すべてが実際に異なることをテストします。
polycube = array([[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
assert len(set(str(x) for x in rotations24(polycube))) == 24