2014-05-08 74 views
0

想象一下,6個牆壁中的每一個都是不同顏色的立方體。立方體圍繞其中心點隨機旋轉。當用戶點擊或點擊屏幕時,旋轉立即停止。立方體被凍結在隨機位置。在用戶釋放鼠標按鈕或從屏幕上移開手指後,立方體應該「變直」,這意味着它應該圍繞某個軸以儘可能小的角度旋轉,這足以在「屏幕平面」中呈現最明顯的立方體牆,所有邊緣平行於屏幕邊緣的方式。舍入3D隨機立方體旋轉至90度角

有沒有辦法找到這個最接近的'直線'旋轉,假設我們可以通過旋轉矩陣或四元數(取其更方便)給出'凍結'位置?看着一個矩陣頂部的3x3部分

+0

如果同時沿着多軸旋轉並不是一個硬性要求,我會使用隨機的90°補間旋轉連續立方體,然後在點擊時不會產生更多的補間,之後最後一個補間將立即終止立方體想。 – opyate

回答

2

的方法之一是,它只是一個基礎向量作爲說明,如果你要申請一個到一個點:

[A D G] [x] [A*x + D*y + G*z]  [A]  [D]  [G] 
[B E H] [y] = [B*x + E*y + H*z] = x * [B] + y * [E] + z * [H] 
[C F I] [z] [C*x + F*y + I*z]  [C]  [F]  [I] 

也就是說,如果你申請的是矩陣,那麼輸入x軸將最終沿(A,B,C)運行,輸入y軸將最終沿(D,E,F)運行,並且輸入z軸將最終沿(G,H,一世)。

我想你問的是「哪根軸沿輸出z的變化最小,即最接近垂直於屏幕」?因此,您可以通過查找具有最小幅度的(C,F,I)的值來確定。

然後,您可以使用(A,B,C)和(D,E,F)的叉積的z符號來決定您是沿着軸正向還是負向查看相同的邏輯您可以使用該測試來進行反面刪除 - 如果相機假設向後移動到無窮大,那麼無論哪個面部都可以看到,這是真正面臨的問題。

這也表明您可能更喜歡的替代測試:做轉換,最接近垂線的面是可見和最大的。這與蘭伯特照明模型背後的邏輯是一致的,事實上,首先考慮的面部大小統一。該測試的優勢在於,您可以使用遮擋查詢在GPU上直接進行測試,假設沒有其中的一部分實際上是閉塞的。

+0

謝謝@Tommy!你引導我到最後的解決方案:-)。和所有的「直線」旋轉矩陣一樣,每行/列中總是隻有一個-1或1,我最終使用下面的算法:(1)找到(C,F,I)中最大的幅度,並保存價值的代價到一個新的'停車'矩陣。(2)找到剩餘的4個矩陣元素(A,B,D,E,G,H中沒有那些高於步驟(1)中選擇的元素的2)的最大量級,並將該值的符號保存爲新的「停車「矩陣。 (3)將剩餘值的符號保存到新的「停車」矩陣中。 (4)將0保存到所有其他值。 – Voyteck

0

簡單的解決方案。

1)找到所需要的壁,並構造從立方體中心向量到壁的中心,讓它成爲DIR1

2)從立方體中心到相機矢量,讓它成爲DIR2

3)建立這些矢量之間的四元數「rotation_arc」。 http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

4)通過從「3)」

爲了找到壁四元數旋轉立方體:建立從立方體的中心6個向量壁的中心。比從立方體的中心到相機建立矢量。估計第一個向量和第二個向量之間的6個角度,並選擇角度最小的牆。

+0

感謝@minorlogic。這肯定會將所需的牆帶到屏幕上,但它並沒有回答基本問題「_how to find_ ** required wall **?」。此外,我不確定是否與前壁垂直的牆壁會平行於屏幕邊緣定位它們的位置(我恐怕它們將處於隨機角度,但我沒有檢查它)。 – Voyteck

+0

它也很簡單。從立方體的中心到牆的中心構建6個矢量。比從立方體的中心到相機建立矢量。估計第一個向量和第二個向量之間的6個角度,並選擇角度最小的牆。 – minorlogic