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?
我有一个三维数组。把它想象成砖块。这个砖块有24种可能的旋转(保持其边缘与坐标轴平行)。如何生成所有对应的三维数组?
3 个解决方案
#1
3
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.
一个骰子(半对骰子)可以方便地观察24种不同的方向,并可以建议操作序列来生成它们。您将看到,任何六个面都可以是最上面的,下面的边可以旋转成四个不同的主方向。让我们表示两个操作:“把”和“卷”,在转绕z轴旋转模具从一个红衣主教,和辊旋转90°远离你死,所以away-face成为底部的脸和脸顶部附近。这些操作可以用Felipe Lopes回答中提到的旋转矩阵来表示,也可以用简单的函数来表示,当给定(x,y,z)返回(-y,x,z)或(x,z,-y)时。
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.
不管怎样,如果你把一个骰子放在近面上,右边是2,上面是3,你会发现下面的步骤会产生12个不同的方向,上面有1、2或3个点:rtttrtttrttttttt。然后序列RTR暴露6、4、5,其中1、2、3是原来的位置,序列rtttrttt的重复序列在顶部有4、5或6个位置,生成12个方向。下面的python代码中嵌入了上述序列。
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
.
打印出一列经过排序的变换对点列表的原理是双重的:(i)任何朝向都可以由其两个角的位置来指定;(ii)这样就可以很容易地检查每一对的唯一性,例如通过管道向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))
#2
2
You can use rotation matrices. Rotating a 3D array around the x-axis means that the element at position (i,j,k)
will be mapped to position (i,-k,j)
. Of course, if your array is 0-indexed, you probably have to replace -k
with size-1-k
or something like that.
你可以用旋转矩阵。围绕x轴旋转一个3D数组意味着位置(i,j,k)的元素将被映射到位置(i,-k,j)。当然,如果你的数组是0索引的,你可能需要用size-1-k或者类似的东西来替换-k。
Similarly, rotating around the y-axis maps (i,j,k)
to (k,j,-i)
. These two rotations can be represented as matrices. For the x-axis rotation:
类似地,绕y轴图旋转(i,j,k)到(k,j, i)。这两个旋转可以表示为矩阵。轴旋转:
|i'| |1 0 0| |i|
|j'| = |0 0 -1|*|j|
|k'| |0 1 0| |k|
And for the y-axis rotation:
y轴旋转:
|i'| |0 0 1| |i|
|j'| = |0 1 0|*|j|
|k'| |-1 0 0| |k|
Any general rotation can be described as a sequence of those two rotations. Applying two rotations consecutively is just multiplying the 3x3 matrices. So, if you find all possible products of them, you'd get 24 matrices (including the identity), each one corresponds to a valid rotation of your array. It's a little tricky to find all possible multiplications, because they don't commute.
任何一般的旋转都可以被描述为这两个旋转的序列。连续应用两个旋转就是把3x3矩阵相乘。如果你找到它们的所有可能的乘积,你会得到24个矩阵(包括单位),每一个都对应于你的数组的有效旋转。找到所有可能的乘法有点棘手,因为它们不通勤。
I think you can just brute-force all products of the form (A^p)*(B^q)*(A^r)*(B^s)
, where A and B are the two matrices before and p,q,r,s
are their powers, and range from 0 to 3 (exponentiating A or B to 4 will take them back to the identity matrix).
我认为你可以强力表单的所有产品(^ p)*(B ^ q)*(r ^)*(B ^ s),A和B是前两个矩阵和p,q,r,s是他们的权力,范围从0到3(取幂4 A或B将带他们回到单位矩阵)。
Doing it this way, you can generate all 24 valid rotation matrices, and rotate the 3D array using each one of them, taking the care to shift the negative indexes so that you don't access out of bounds.
这样做,您可以生成所有24个有效的旋转矩阵,并使用它们中的每一个旋转3D数组,小心地移动负索引,这样您就不会访问越界。
#3
0
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):
让X围绕X轴旋转90度,Y围绕Y轴旋转90度,那么24种可能的唯一组合是(除了4次相同旋转的组合外,所有可能的组合都有5次旋转(如XXXX、XXXXY xyyy等):
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.
当然你可以用任意两个90度的旋转来代替X和Y,例如Y和Z。
Or, if you also use Z, a 90 degree rotation around the Z axis then 4 rotations suffice:
或者,如果你也用Z,围绕Z轴旋转90度,那么4个旋转就足够了:
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.
这24个矩阵都存在三个列向量每个列向量都有两个0和一个- 1或+ 1。每一行都有两个0。因此,它们可以很容易地生成:第一列向量有六种可能性((1,0,0),(- 1,0,0,0),(0,0,0,0),(0,0,0),(0,0,0),(0,0,0),这相当于将正x轴移动到正x轴或负x轴,y或z轴。第二列向量只有四种可能,因为它必须包含一个0,其中第一列的值是非零的。最后,第三列向量只剩下一个位置它的正负一可以是。这就得到了6 * 4 * 2 = 48个矩阵,其中有一半也是原来的(它们是镜像的组合,也可以是旋转)。因此只有24个是纯旋转。镜像操作的矩阵的行列式等于-1,纯旋转的行列式等于1。
#1
3
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.
一个骰子(半对骰子)可以方便地观察24种不同的方向,并可以建议操作序列来生成它们。您将看到,任何六个面都可以是最上面的,下面的边可以旋转成四个不同的主方向。让我们表示两个操作:“把”和“卷”,在转绕z轴旋转模具从一个红衣主教,和辊旋转90°远离你死,所以away-face成为底部的脸和脸顶部附近。这些操作可以用Felipe Lopes回答中提到的旋转矩阵来表示,也可以用简单的函数来表示,当给定(x,y,z)返回(-y,x,z)或(x,z,-y)时。
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.
不管怎样,如果你把一个骰子放在近面上,右边是2,上面是3,你会发现下面的步骤会产生12个不同的方向,上面有1、2或3个点:rtttrtttrttttttt。然后序列RTR暴露6、4、5,其中1、2、3是原来的位置,序列rtttrttt的重复序列在顶部有4、5或6个位置,生成12个方向。下面的python代码中嵌入了上述序列。
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
.
打印出一列经过排序的变换对点列表的原理是双重的:(i)任何朝向都可以由其两个角的位置来指定;(ii)这样就可以很容易地检查每一对的唯一性,例如通过管道向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))
#2
2
You can use rotation matrices. Rotating a 3D array around the x-axis means that the element at position (i,j,k)
will be mapped to position (i,-k,j)
. Of course, if your array is 0-indexed, you probably have to replace -k
with size-1-k
or something like that.
你可以用旋转矩阵。围绕x轴旋转一个3D数组意味着位置(i,j,k)的元素将被映射到位置(i,-k,j)。当然,如果你的数组是0索引的,你可能需要用size-1-k或者类似的东西来替换-k。
Similarly, rotating around the y-axis maps (i,j,k)
to (k,j,-i)
. These two rotations can be represented as matrices. For the x-axis rotation:
类似地,绕y轴图旋转(i,j,k)到(k,j, i)。这两个旋转可以表示为矩阵。轴旋转:
|i'| |1 0 0| |i|
|j'| = |0 0 -1|*|j|
|k'| |0 1 0| |k|
And for the y-axis rotation:
y轴旋转:
|i'| |0 0 1| |i|
|j'| = |0 1 0|*|j|
|k'| |-1 0 0| |k|
Any general rotation can be described as a sequence of those two rotations. Applying two rotations consecutively is just multiplying the 3x3 matrices. So, if you find all possible products of them, you'd get 24 matrices (including the identity), each one corresponds to a valid rotation of your array. It's a little tricky to find all possible multiplications, because they don't commute.
任何一般的旋转都可以被描述为这两个旋转的序列。连续应用两个旋转就是把3x3矩阵相乘。如果你找到它们的所有可能的乘积,你会得到24个矩阵(包括单位),每一个都对应于你的数组的有效旋转。找到所有可能的乘法有点棘手,因为它们不通勤。
I think you can just brute-force all products of the form (A^p)*(B^q)*(A^r)*(B^s)
, where A and B are the two matrices before and p,q,r,s
are their powers, and range from 0 to 3 (exponentiating A or B to 4 will take them back to the identity matrix).
我认为你可以强力表单的所有产品(^ p)*(B ^ q)*(r ^)*(B ^ s),A和B是前两个矩阵和p,q,r,s是他们的权力,范围从0到3(取幂4 A或B将带他们回到单位矩阵)。
Doing it this way, you can generate all 24 valid rotation matrices, and rotate the 3D array using each one of them, taking the care to shift the negative indexes so that you don't access out of bounds.
这样做,您可以生成所有24个有效的旋转矩阵,并使用它们中的每一个旋转3D数组,小心地移动负索引,这样您就不会访问越界。
#3
0
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):
让X围绕X轴旋转90度,Y围绕Y轴旋转90度,那么24种可能的唯一组合是(除了4次相同旋转的组合外,所有可能的组合都有5次旋转(如XXXX、XXXXY xyyy等):
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.
当然你可以用任意两个90度的旋转来代替X和Y,例如Y和Z。
Or, if you also use Z, a 90 degree rotation around the Z axis then 4 rotations suffice:
或者,如果你也用Z,围绕Z轴旋转90度,那么4个旋转就足够了:
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.
这24个矩阵都存在三个列向量每个列向量都有两个0和一个- 1或+ 1。每一行都有两个0。因此,它们可以很容易地生成:第一列向量有六种可能性((1,0,0),(- 1,0,0,0),(0,0,0,0),(0,0,0),(0,0,0),(0,0,0),这相当于将正x轴移动到正x轴或负x轴,y或z轴。第二列向量只有四种可能,因为它必须包含一个0,其中第一列的值是非零的。最后,第三列向量只剩下一个位置它的正负一可以是。这就得到了6 * 4 * 2 = 48个矩阵,其中有一半也是原来的(它们是镜像的组合,也可以是旋转)。因此只有24个是纯旋转。镜像操作的矩阵的行列式等于-1,纯旋转的行列式等于1。