How to calculate all 24 rotations of 3d array?
Look at the code for rot90
. I see 3 variations on flip
and swapaxes
, depending on k
the axis parameter.
fliplr(m).swapaxes(0, 1)
fliplr(flipud(m))
fliplr(m.swapaxes(0, 1))
fliplr(m)
is just m[:, ::-1]
, and not surprisingly, flipud
is m[::-1, ...]
.
You could flip the 3rd axis with m[:,:,::-1]
, or m[...,::-1]
.
np.transpose
is another tool for permuting axes, that may, or may not, be easier to use than swapaxes
.
If rot90
gives you 4 of the rotations, you should be able apply the same routines to produce the others. You just have to understand the logic underlying rot90
.
e.g.
def flipbf(m):
return m[:,:,::-1]
flipbf(m).swapaxes(0, 2)
flipbf(m).swapaxes(1, 2)
etc
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