Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate all 24 rotations of 3d array?

Tags:

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 method, which gives 4 of the 24, but I'm clueless how to calculate the rest. My only idea is to convert the 3d array to a 2d matrix of co-ordinates, multiply by a rotation matrix, and convert back. But I'd rather work directly with the 3d array.

Example 2x2x2 array:

>>> from numpy import array >>> polycube array([[[1, 0],         [1, 0]],         [[1, 1],         [0, 0]]]) 

Example 3x3x3 array:

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]]]) 

Edit: I only want the 24 orientation-preserving isometries, not all 48 rotations and reflections (though it would be interesting to know how to make them too). If it helps to test, I believe the 3x3x3 example has no rotational symmetry and is chiral (so the 48 are distinct).

Motivation: I'm writing a solver for a Soma cube-style puzzle.

like image 594
Colonel Panic Avatar asked Oct 17 '15 18:10

Colonel Panic


People also ask

How is 3D rotation performed?

3D Rotation is a process of rotating an object with respect to an angle in a three dimensional plane. Consider a point object O has to be rotated from one angle to another in a 3D plane.

What is rotation matrix formula?

The trace of a rotation matrix is equal to the sum of its eigenvalues. For n = 2, a rotation by angle θ has trace 2 cos θ. For n = 3, a rotation around any axis by angle θ has trace 1 + 2 cos θ. For n = 4, and the trace is 2(cos θ + cos φ), which becomes 4 cos θ for an isoclinic rotation.

What is 3D rotation matrix?

The most general three-dimensional rotation matrix represents a counterclockwise rotation by an angle θ about a fixed axis that lies along the unit vector n. The rotation matrix operates on vectors to produce rotated vectors, while the coordinate axes are held fixed. This is called an active transformation.


1 Answers

Update: Simplified after Numpy 1.12.0 added an axes argument to the rot90 function

Here's how I made all 24 rotations:

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)) 

Test that all 24 rotations are indeed distinct:

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 
like image 119
Colonel Panic Avatar answered Oct 18 '22 08:10

Colonel Panic