I have a 3-dimensional array. Think of it as a brick. There are 24 possible rotations of this brick (that keep its edges parallel to coordinate axes). How do I generate all corresponding 3-dimensional arrays?
A die (half a pair of dice) is handy for observing the 24 different orientations, and can suggest operation sequences to generate them. You will see that any of six faces can be uppermost, and the sides below can be rotated into four different cardinal directions. Let us denote two operations: “turn” and “roll”, where turn rotates the die about the z axis from one cardinal to the next, and roll rotates the die 90° away from you, so the away-face becomes the bottom face and the near face the top. These operations can be expressed using rotation matrices as mentioned in the answer of Felipe Lopes, or can be expressed as simple functions that when given (x,y,z) return (-y,x,z) or (x,z,-y), respectively.
Anyhow, if you place the die with 1 on the near face, 2 at right, and 3 on top, you will find that the following sequence of steps generates the twelve different orientations with 1, 2, or 3 spots on top: RTTTRTTTRTTT. Then the sequence RTR exposes 6, 4, 5 where 1, 2, 3 originally were, and a repeat of the sequence RTTTRTTTRTTT generates the twelve orientations with 4, 5, or 6 spots on top. The mentioned sequence is embedded in the following python code.
def roll(v): return (v[0],v[2],-v[1])
def turn(v): return (-v[1],v[0],v[2])
def sequence (v):
for cycle in range(2):
for step in range(3): # Yield RTTT 3 times
v = roll(v)
yield(v) # Yield R
for i in range(3): # Yield TTT
v = turn(v)
yield(v)
v = roll(turn(roll(v))) # Do RTR
p = sequence(( 1, 1, 1))
q = sequence((-1,-1, 1))
for i in sorted(zip(p,q)):
print i
The rationale for printing out a sorted list of transformed pairs of points is twofold: (i) any face orientation can be specified by the locations of two of its corners; (ii) it then is easy to check for uniqueness of each pair, eg by piping output to uniq
.
Here is how the sorted output begins:
((-1, -1, -1), (-1, 1, 1))
((-1, -1, -1), (1, -1, 1))
((-1, -1, -1), (1, 1, -1))
((-1, -1, 1), (-1, 1, -1))
((-1, -1, 1), (1, -1, -1))
((-1, -1, 1), (1, 1, 1))
((-1, 1, -1), (-1, -1, 1))
((-1, 1, -1), (1, -1, -1))
((-1, 1, -1), (1, 1, 1))
Let X rotate 90 degrees around the X-axis and Y rotate 90 degrees around the Y-axis then the 24 possible unique combinations are (all possible combinations up to 5 rotations are given except those with four times the same rotation (eg XXXX, XXXXY XYYYY, etc):
1. I
2. X
3. Y
4. XX = YXXY
5. XY
6. YX
7. YY = XYYX
8. XXX = XYXXY = YXXYX = YXYXY = YYXYY
9. XXY = YXXYY = YYYXX
10. XYX = YXY
11. XYY = XXYYX = YYXXX
12. YXX = XXYYY = YYXXY
13. YYX = XXXYY = XYYXX
14. YYY = XXYXX = XYXYX = XYYXY = YXYYX
15. XXXY
16. XXYX = XYXY = YXYY
17. XXYY = YYXX
18. XYXX = YXYX = YYXY
19. XYYY
20. YXXX
21. YYYX
22. XXXYX = XXYXY = XYXYY = YXYYY
23. XYXXX = YXYXX = YYXYX = YYYXY
24. XYYYX = YXXXY
Of course you can use any two 90 degree rotations in place of the X and Y. For example, Y and Z.
Or, if you also use Z, a 90 degree rotation around the Z axis then 4 rotations suffice:
1. I
2. X = YXZ
3. Y = ZYX
4. Z = XZY
5. XX = XYXZ = YXXY = YXYZ = YXZX = YYZZ = YZXZ = ZXXZ = ZZYY
6. XY = YZ = ZX = XZYX = YXZY = ZYXZ
7. XZ = XXZY = YXZZ = YYYX = ZYYY
8. YX = XZZZ = YYXZ = ZYXX = ZZZY
9. YY = XXZZ = XYYX = YZYX = ZXYX = ZYXY = ZYYZ = ZYZX = ZZXX
10. ZY = XXXZ = XZYY = YXXX = ZZYX
11. ZZ = XXYY = XYZY = XZXY = XZYZ = XZZX = YYXX = YZZY = ZXZY
12. XXX
13. XXY = XYZ = XZX = YZZ = ZXZ
14. XXZ = ZYY
15. XYX = YXY = YYZ = YZX = ZXX
16. XYY = YZY = ZXY = ZYZ = ZZX
17. XZZ = YYX
18. YXX = ZZY
19. YYY
20. ZZZ
21. XXXY = XXYZ = XXZX = XYZZ = XZXZ = YZZZ = ZXZZ = ZYYX
22. XXYX = XYXY = XYYZ = XYZX = XZXX = YXYY = YYZY = YZXY = YZYZ = YZZX = ZXXY = ZXYZ = ZXZX = ZYZZ = ZZXZ
23. XYXX = XZZY = YXYX = YYXY = YYYZ = YYZX = YZXX = ZXXX
24. XYYY = YXXZ = YZYY = ZXYY = ZYZY = ZZXY = ZZYZ = ZZZX
These 24 matrices all exist of three column vectors that each exist of two zeroes and a minus one or plus one. On every row there are also exactly two zeroes. As such, they can easily be generated: the first column vector has six possibilities ((1,0,0), (-1,0,0), (0,-1,0), (0,1,0), (0,0,-1) and (0,0,1)), this corresponds to moving the positive X-axis to the positive or negative x, y or z axis. The second column vector only has four possibilities because it must contain a zero where the first column has a non-zero value. Finally the third column vector has only one place left where its plus or minus one can be. This gives 6 * 4 * 2 = 48 matrices, half of them mirror the original as well however (they are combination of a mirror and optionally a rotation). Hence only 24 are pure rotations. The matrices that are mirror operations will have a determinant equal to -1, the determinant of the pure rotations is 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With