2017-03-02 271 views
1

如何獲得兩個單位向量之間的x,y和z旋轉值?我不能使用點積,因爲這隻給了我一個值。我想使用旋轉矩陣在每個軸上進行旋轉,對於那些我需要每個軸上的角度差異的旋轉矩陣。 我試過只有兩個組件的點積,但我有點困惑。 有沒有一個快速簡單的方法來做到這一點?也許我對這兩件事情做錯了,但我不知道。 最好是,如果有人知道一個glsl方法來做這件事情!獲取矢量之間的xyz角度?

回答

2

如果您想獲得兩個矢量之間的x,y和z角度,請將兩個矢量的投影的點積乘積到所需軸的正交平面上。

也就是說,如果您需要兩個矢量之間的z角,請創建原件的xy平面矢量。爲此,創建一個忽略向量的z分量的向量。

vec3 u = vec3(...); // your input vector 
vec3 v = vec3(...); // your other input vector 
float x_angle = acos(dot(u.yz, v.yz)); 
float y_angle = acos(dot(u.xz, v.xz)); 
float z_angle = acos(dot(u.xy, v.xy)); 

請注意,如果您使用u.xzu.zx,因爲你會使用點產品也沒關係。只要確保在點積中使用相同的順序即可。此外,此處代碼的第3 - 5行假定單位矢量,因爲表達式中沒有提到矢量長度。

還應該注意的是,使用acos可能會導致參數值較小的錯誤。爲避免這種情況,可以採用2D投影向量之間的差異,並與atan2函數一起使用。

編輯

在建議,最終目標是建立一個旋轉矩陣重新定向與所述相同的變換的其它載體,我建議使用軸角的方法(也稱爲任意軸旋轉)。該方法包括找出兩個向量(點積)和該角度所對的適當的旋轉軸之間的角度(叉積)。

第一步,您想要使用點積來找出兩個向量之間的角度。

float angle = acos(dot(u, v)); // for unit vectors 

接下來,要找到旋轉軸,請使用叉積。知道叉積將產生一個垂直於uv的矢量,以任一順序交叉它們將給出合適的軸。

vec3 axis = cross(u, v); // again, for unit vectors 
// normalize this if need be 

你將要使用的矩陣的形式可以由軸和角度旋轉矩陣的對這個Wikipedia article的標題下找到。我建議存儲一些臨時值以使計算運行更快。

float c = cos(angle); 
float s = sin(angle); 
float t = 1 - c; 

一旦您構建了該矩陣,只需將其乘以任何向量即可重新應用原始變換。

+0

這沒什麼用:我用u和v做了同樣的矢量,我基本上得到了矢量(out =(0,0,1),in =(0,0,1)) 。它也沒有與其他vectros工作 –

+0

你的整個過程得到一個新的載體是什麼?我很想知道你的最終目標是什麼。另外,如上所述,如果您使用的是acos,則向量可能會有些相同。例如,在Lua中,我不得不限制輸入以避免產生NaN。 – Nathan

+0

好的。我的目標是獲得樹軸上的旋轉差異,所以我可以將這些值插入到旋轉矩陣中,並使用這些值旋轉另一個向量。然後旋轉的矢量Y軸將與我的其他矢量對齊。 –