2013-10-07 189 views
1

我有一個來自傳感器設備的三維單元四元數= {w,x,y,z}。我想獲得關於X,Y和Z軸的角度(ax,ay,az)的數量(但角度應該是獨立,其他人應該不會改變)。我碰到過,四元數歐拉角度轉換,他們有萬向節鎖問題&他們是依賴。 所以我想採取不同的方法。使用三維向量x = [1,0,0],y = [0,1,0]和z = [0,0,1]。如果我用四元數旋轉這些向量x,y和z,我們得到3個向量xx,yy和zz。然後計算x,xx向量之間的角度。 y,yy和z,zz之間的類似角度。這似乎也不起作用。 以下是我寫的C#代碼。角度範圍應爲-180至180或0至360度。 acos不是首選,因爲它有精度問題。四維旋轉的3D中的兩個3D矢量之間的夾角

如何完成這項工作?有沒有標準方法?如何將三元四元數分解爲3個四元數的X,Y和Z軸?

Vector3D rotVecX = QuatVecRotation(Quaternion, new Vector3D(1,0,0)); 
Vector3D rotVecY = QuatVecRotation(Quaternion, new Vector3D(0,1,0)); 
Vector3D rotVecZ = QuatVecRotation(Quaternion, new Vector3D(0,0,1));     
float aX = (float)GetXangle(new Vector3D(1, 0, 0), rotVec1); 
float aY = (float)GetYangle(new Vector3D(0, 1, 0), rotVec2); 
float aZ = (float)GetZangle(new Vector3D(0, 0, 1), rotVec3); 

Vector3D QuatVecRotation(Quaternion quat, Vector3D vec) 
    {    
     Quaternion Qvec = new Quaternion(0,vec.X,vec.Y,vec.Z);    
     Quaternion QvecR = Quaternion.Multiply(quat, Qvec); 
     Quaternion Qinv = new Quaternion(quat.W, -quat.X, -quat.Y, -quat.Z); // conjugate or Inverse 
     Quaternion Qr = Quaternion.Multiply(QvecR, Qinv); 
     Vector3D resultVec = new Vector3D(Qr.X, Qr.Y, Qr.Z); 
     resultVec.Normalize(); 
     return resultVec; 
    } 
    public double GetXangle(Vector3D vec1, Vector3D vec2) 
    {    
     Vector3D axis = Vector3D.CrossProduct(vec1, vec2); 
     double angle = Rad2Deg((float)Math.Atan2(axis.Length, Vector3D.DotProduct(vec1, vec2)));    
     double dir = Vector3D.DotProduct(Vector3D.CrossProduct(axis, vec1), new Vector3D(0, 1, 1)); 
     if(dir<0) 
      angle = angle * Math.Sign(dir);    
     return angle; 
    } 

回答

0

如果歐拉角從季度三角形變得更大,那麼如果它們較小(在兩個連續的四元數之間),我們將遇到萬向鎖定問題,那麼應該沒有問題。我們可能只是將目前的角度添加到以前的角度&可能會讓他們在所需的範圍內。

0

使用點積:

X·XX = | X || XX | COS(角度)

這樣:

角= ACOS(X ·xx /(| x || xx |))

0

我會建議首先計算Rodriguez旋轉。這很簡單

考慮到你有兩個載體ab

旋轉軸將通過叉積Ñ = 一個 X b來限定。

旋轉角度將通過歸一化點積 COS(THETA)= 一個 * b /(|| 一個 || || b ||)

的被定義公式之間轉換羅德里格斯旋轉和它的四元數是here