我有一個來自傳感器設備的三維單元四元數= {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;
}