Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何获得三维阵列的所有24次旋转?_Arrays_Algorithm_Multidimensional Array_Rotation - Fatal编程技术网

Arrays 如何获得三维阵列的所有24次旋转?

Arrays 如何获得三维阵列的所有24次旋转?,arrays,algorithm,multidimensional-array,rotation,Arrays,Algorithm,Multidimensional Array,Rotation,我有一个三维数组。把它想象成一块砖头。此砖有24种可能的旋转(使其边缘与坐标轴平行)。如何生成所有相应的三维数组 可以使用旋转矩阵。围绕x轴旋转3D阵列意味着位置(i,j,k)处的元素将映射到位置(i,-k,j)。当然,如果您的数组是0索引的,那么您可能必须将-k替换为size-1-k或类似的内容 类似地,围绕y轴旋转将(i,j,k)映射到(k,j,-i)。这两个旋转可以表示为矩阵。对于x轴旋转: |i'| |1 0 0| |i| |j'| = |0 0 -1|*|j| |k'|

我有一个三维数组。把它想象成一块砖头。此砖有24种可能的旋转(使其边缘与坐标轴平行)。如何生成所有相应的三维数组

可以使用旋转矩阵。围绕x轴旋转3D阵列意味着位置
(i,j,k)
处的元素将映射到位置
(i,-k,j)
。当然,如果您的数组是0索引的,那么您可能必须将
-k
替换为
size-1-k
或类似的内容

类似地,围绕y轴旋转将
(i,j,k)
映射到
(k,j,-i)
。这两个旋转可以表示为矩阵。对于x轴旋转:

|i'|   |1  0  0| |i|
|j'| = |0  0 -1|*|j|
|k'|   |0  1  0| |k|
|i'|   |0  0  1| |i|
|j'| = |0  1  0|*|j| 
|k'|   |-1 0  0| |k|
对于y轴旋转:

|i'|   |1  0  0| |i|
|j'| = |0  0 -1|*|j|
|k'|   |0  1  0| |k|
|i'|   |0  0  1| |i|
|j'| = |0  1  0|*|j| 
|k'|   |-1 0  0| |k|
任何一般旋转都可以描述为这两个旋转的序列。连续应用两次旋转只是将3x3矩阵相乘。因此,如果你找到它们的所有可能乘积,你会得到24个矩阵(包括恒等式),每个矩阵对应于数组的一个有效旋转。找到所有可能的乘法有点棘手,因为它们不需要通勤

我想你可以用蛮力强制所有形式的乘积
(A^p)*(B^q)*(A^r)*(B^s)
,其中A和B是前面的两个矩阵,
p,q,r,s是它们的幂,范围从0到3(将A或B求幂到4将使它们回到单位矩阵)

通过这种方式,您可以生成所有24个有效的旋转矩阵,并使用其中的每一个旋转3D阵列,注意移动负索引,以避免访问超出范围。

一个骰子(半对骰子)便于观察24个不同的方向,并且可以建议生成它们的操作序列。您将看到,六个面中的任何一个都可以位于最上面,下面的边可以旋转到四个不同的基本方向。让我们表示两种操作:“旋转”和“滚动”,其中“旋转”将模具围绕z轴从一个基数旋转到下一个基数,而“滚动”将模具旋转90°,使远离的面成为底部面,而靠近的面成为顶部面。这些运算可以使用Felipe Lopes答案中提到的旋转矩阵表示,或者可以表示为简单函数,当给定(x,y,z)时,它们分别返回(-y,x,z)或(x,z,-y)

无论如何,如果您将模具放置在近面上,2在右侧,3在顶部,您将发现以下步骤序列生成12个不同方向,顶部有1、2或3个点:rtttrttt。然后序列RTR曝光6、4、5,其中1、2、3原来是,并且序列RTTTTTTT的重复生成12个方向,顶部有4、5或6个点。上述序列嵌入在以下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
打印出转换点对的排序列表的基本原理有两个:(i)任何面方向都可以通过其两个角的位置来指定;(ii)然后很容易检查每对的唯一性,例如通过管道输出到
uniq

以下是排序输出的开始方式:

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

让X绕X轴旋转90度,Y绕Y轴旋转90度,则24种可能的唯一组合为(除具有四次相同旋转的组合(例如XXXX、XXXXY、XYYYY等)外,给出了最多5次旋转的所有可能组合):

当然,您可以使用任意两个90度旋转来代替X和Y。例如,Y和Z

或者,如果也使用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
这24个矩阵都有三个列向量,每个列向量都有两个零和一个负一或正一。每行上也正好有两个零。因此,它们很容易生成:第一个列向量有六种可能性((1,0,0),(-1,0,0),(0,-1,0),(0,1,0),(0,0,-1)和(0,0,1)),这对应于将正X轴移动到正或负X、y或z轴。第二列向量只有四种可能性,因为它必须包含一个零,其中第一列的值为非零值。最后,第三列向量只剩下一个位置,其正负一个可以。这给出了6*4*2=48个矩阵,但是,其中一半也镜像原始图像(它们是镜像和可选旋转的组合)因此,只有24个是纯旋转。镜像操作的矩阵的行列式将等于-1,纯旋转的行列式为1。

的答案令人鼓舞,我想添加一个稍微改进的版本,只有两个for循环

我们知道有24个独特的方向。我通过想象一个骰子来计算:上面有6个可能的选择,上面的每个面有4个可能的旋转

如果我们重复这个想法呢?我想。如果我们能找到一种方法来移动骰子的所有6个面,那么我们只需要观察每个面上的4个旋转,我们就完成了

因此,我抓起最近的“砖块”(在我的例子中,是一个Vitasoy纸盒),开始旋转,看看哪种模式最容易访问所有6个面。如果我们引入额外的逆时针旋转,那么我们的操作是:

  • 滚动(沿固定方向,例如,使面向您的面现在向下旋转)
  • 顺时针转动(沿固定轴转动,例如,使面向您的面顺时针转动,但仍面向您)
  • 逆时针转动(沿与上一个轴相同的轴)
然后,我们可以通过执行以下操作访问所有人脸:

滚动->连续旋转->滚动->逆时针旋转->滚动->连续旋转->滚动->逆时针旋转->滚动->连续旋转->滚动->逆时针旋转

通过最后一次滚动和转弯,我们回到了原始方向。正如你所看到的,这是一个滚动+交替顺时针转弯和逆时针转弯的重复序列

现在,如果我们将其扩展到包括我们访问的每个面的所有旋转,