How to calculate all 24 rotations of 3d array?

后端 未结 9 743
清酒与你
清酒与你 2021-02-12 10:45

I have a 3d numpy array describing a polycube (imagine a 3d tetris piece). How can I calculate all 24 rotations?

Numpy\'s array manipulation routines includes a rot90 me

9条回答
  •  醉话见心
    2021-02-12 11:04

    First let's determine the 48 isometries, as matrices that permute the basis vectors, possibly flipping some signs:

    def isometries():
        basis = numpy.eye(3)
        for ix in range(3):
          for iy in range(3):
            if iy == ix:
              continue
            for iz in range(3):
              if iz == ix or iz == iy:
                continue
    
              for sx in range(-1, 2, 2): # -1, 1
                for sy in range(-1, 2, 2):
                  for sz in range(-1, 2, 2):
                    yield numpy.array([sx * basis[ix], sy * basis[iy], sz * basis[iz]])
    

    Then let's filter for the rotations, which are the isometries of determinant 1:

    def rotations():
        return filter(lambda x: numpy.linalg.det(x) > 0, isometries())
    

    Finally, we can apply such a rotation to a polycube by shifting the array indices such that the inner point is the origin, and multiplying the index vector by the rotation matrix:

    def rotate(rotation, shape):
        shift = numpy.array([1,1,1])
        res = numpy.zeros(27).reshape(3,3,3)
        it = numpy.nditer(shape, flags=['multi_index'])
        while not it.finished:
            v = numpy.array(it.multi_index) - shift
            w = rotation.dot(v)
            dest = tuple(w + shift)
            res[dest] = it[0]
            it.iternext()
        return res
    

    For example:

    >>> rotate(list(rotations())[5], polycube)
    array([[[ 0.,  0.,  0.],
            [ 0.,  0.,  0.],
            [ 0.,  0.,  0.]],
    
           [[ 0.,  1.,  1.],
            [ 0.,  0.,  0.],
            [ 0.,  0.,  0.]],
    
           [[ 1.,  1.,  0.],
            [ 1.,  1.,  0.],
            [ 0.,  0.,  0.]]])
    

提交回复
热议问题