3D配列の24回転すべてを計算するにはどうすればいいですか? 質問する

3D配列の24回転すべてを計算するにはどうすればいいですか? 質問する

私は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

おすすめ記事