2015-05-13 406 views
1

我希望能找到兩組兩個向量之間的旋轉,作爲四元數。在每一對中,矢量將彼此成直角並具有單位長度(基本上以正交基準爲基礎的兩個矢量)。兩組向量之間的四元數旋轉

我當前的代碼看起來是這樣的:

Vector3 look1, up1, right1, look2, up2, right2; 
// look1, up1, right1 form orthonormal basis, 
// ditto with look2, up2, and right2 
Vector3 lookRotateAxis = look1 % look2; 
// operator% defined as cross product for convenience 
float lookRotateAngle = acos(look1 * look2); 
// operator* defined as dot product for convenience 
Quaternion lookRotate; 
lookRotate.makeRotation(lookRotateAngle, lookRotateAxis); 
up1Transformed = lookRotate.rotateVector(up1); 
Vector3 upRotateAxis = up1Transformed % up2; 
float upRotateAngle = up1Transformed * up2; 
Quaternion upRotate; 
upRotate.makeRotation(upRotateAngle, upRotateAxis); 
Quaternion finalRotation = upRotate * lookRotate; 
// quaternion finalRotation rotates basis 1 to basis 2 

我現在使用的方法是,首先每對找到兩個向量之間的四元數旋轉,然後乘以兩者之間的四元數旋轉每一對中的第二個向量。這導致了一個單一的四元數,我可以通過旋轉兩個矢量來得到另外兩個矢量。有沒有更簡單的方法來計算四元數,而不是通過乘以兩個旋轉,而是計算單個旋轉?

謝謝!

+0

沒有代碼可以看,這純粹是一個數學問題...所以「更快地做到」只能用非常抽象的數學方法來回答......不懂數學的人不能幫助與一般的性能編碼調整。由於這是一個編程站點,您是否可以編輯您的問題(通過編輯按鈕)以提供您現在以[MCVE](http://stackoverflow.com/help/mcve)的形式寫入的內容? *(在早期的問題中,最好按照規則生活「包含一些代碼」,並且只有在稍後考慮包含哪些非代碼問題(包括主題考慮的問題)時纔會生效......)* – HostileFork

+0

@HostileFork感謝您的建議,我會考慮編輯。我對這個網站並不陌生,我的舊帳戶被意外地惡意破壞。 – Josh

+1

@Josh如果它是惡意做的,那不是偶然的。無論哪種方式。 =( – WhozCraig

回答

1

我認爲可以非常快速和有效地做你想做的事情。首先,你應該完成每一個正交正常的矢量對成正交基。這樣做的顯而易見的方法是通過前兩個向量的交叉乘積。順序很重要:如果你想u0映射到v0和u1映射到v1,那麼形成標準正交基{u0,u1,u2},其中u2 = u0 x u1(叉積),也形成標準正交基{v0,v1 ,v2}其中v2 = v0 x v1,並將u2映射到v2。如果你不小心並且設置了v2 = v1 x v0,那麼最終會出現一個不可能的情況(試圖將右手座標系映射到具有旋轉的左手座標系)。所以請注意交叉產品中的術語順序。

既然您有兩個正交基,或者,那麼很容易構造表示從{x,y,z}幀到給定幀的旋轉的正交矩陣。 (再次,您必須考慮{x,y,z}框架的方向或手性......例如,您可能必須使用{x,z,y}。)矩陣乘以表示從該幀{X,Y,Z}到{U0,U1,U2}旋轉正交矩陣是

[u00 u01 u02] 
[u10 u11 u12] 
[u20 u21 u22] 

其中,根據用於計算機圖形通常的慣例,我們通過預先乘以向量我們的矩陣。例如,我們的矩陣對(1,0,0)的影響是

 [u00 u01 u02] 
[1 0 0] [u10 u11 u12] = [u00 u01 u02] 
     [u20 u21 u22] 

這正是我們想要的;對於{x,y,z}中的其他兩個基向量也是如此。

要將一幀映射到另一幀,我們通過幀{x,y,z}作爲中介。所以我們必須找到第一個正交矩陣的逆。幸運的是,反轉正交矩陣非常簡單:你只需要轉置。因此,在框架{U0,U1,U2}映射到幀{V0,V1,V2},使用矩陣產品

[u00 u10 u20] [v00 v01 v02] 
[u01 u11 u21] [v10 v11 v12] 
[u02 u12 u22] [v20 v21 v22] 

讓我們看看會發生什麼,當我們輸入向量U1 = [U10,U11, u12]插入此矩陣產品:

   [u00 u10 u20] [v00 v01 v02]   [v00 v01 v02] 
[u10 u11 u12] [u01 u11 u21] [v10 v11 v12] = [0 1 0] [v10 v11 v12] = [v10 v11 v12] 
       [u02 u12 u22] [v20 v21 v22]   [v20 v21 v22] 

正如需要。這裏我們使用了公式u1。 u0 = 0,u1。 u1 = 1,u1。 u2 = 0,從{u0,u1,u2}是正交正常幀。

因此表示要旋轉的正交矩陣正是

[u00 u10 u20] [v00 v01 v02] 
[u01 u11 u21] [v10 v11 v12] 
[u02 u12 u22] [v20 v21 v22] 

執行矩陣乘法,以獲得一個矩陣,然後如果你想在四元數表示,從旋轉矩陣轉換通過類似的四元數方法在http://en.wikipedia.org/wiki/Rotation_matrix#Quaternion中描述。

+0

在我決定使用Quaternion之前,我正在使用矩陣並基本做到這一點。將矩陣轉換爲四元數是完全有效的,我猜我不願意使用它的最大原因是我似乎記得矩陣到四元數的轉換是一個糟糕的糟糕的代碼片段......並不是說它效率低下,一定。這並不壞,現在我再看一遍......謝謝你的回覆! – Josh