2013-05-09 58 views
11

我有一個3維數組。把它想象成一塊磚頭。這塊磚有24個可能的旋轉(保持其邊緣平行於座標軸)。我如何生成所有相應的三維數組?如何獲得三維陣列的所有24個旋轉?

+0

你應該讓自己嘗試... – 2013-05-09 00:35:22

+2

@ MitchWheat-這是一個很難的問題!即使我確實付出了努力,我想我會很快陷入困境。 – templatetypedef 2013-05-09 01:05:39

回答

2

您可以使用旋轉矩陣。圍繞x軸旋轉3D陣列意味着位置(i,j,k)上的元素將被映射到位置(i,-k,j)。當然,如果你的數組是0索引的,你可能需要用size-1-k或者類似的東西替換-k

類似地,圍繞y軸旋轉地圖(i,j,k)(k,j,-i)。這兩個旋轉可以表示爲矩陣。對於x軸旋轉:

|i'| |1 0 0| |i| 
|j'| = |0 0 -1|*|j| 
|k'| |0 1 0| |k| 

而對於y軸旋轉:

|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陣列,小心地移動負向索引,以便不會出現界限。

3

模具(一對骰子)便於觀察24個不同的方向,並可以建議操作順序來生成它們。你會看到六個面中的任何一個都可以在最上面,下面的兩面可以旋轉成四個不同的基本方向。讓我們表示兩個操作:「」和「」,其中繞Z軸到下一個模具從一個基數,並旋轉,從你死90°了,所以離開臉部變成底部臉部,並且將臉部靠近頂部。這些操作可以用Felipe Lopes的答案中提到的旋轉矩陣來表示,或者可以表示爲當給定(x,y,z)返回(-y,x,z)或(x,z, - )時的簡單函數。 y)。無論如何,如果你在近人臉上,右邊2人,頂部3人的位置放置骰子,你會發現以下步驟順序產生了12個不同的方位,其上有1,2或3個點頂部:RTTTRTTTRTTT。然後,序列RTR暴露出6,4,5,其中1,2,3最初是,並且序列RTTTRTTTRTTT的重複序列產生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))