1

我有一个来自传感器设备的 3D 单位四元数 = {w,x,y,z}。我想获得关于 X、Y 和 Z 轴的角度(ax、ay、az)的数量(但角度应该是独立的,当另一个变化时一个不应该改变)。我遇到过,四元数欧拉角的转换,他们有万向节锁定问题并且他们是依赖项。所以我想采取不同的方法。

取 3D 向量 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 四元数分解为 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;
    }
4

3 回答 3

0

使用点积:

x·xx = |x||xx|cos(角度)

所以:

角度 = acos( x·xx / ( |x||xx| ) )

于 2013-10-07T09:34:50.927 回答
0

如果从一个四元数得到的欧拉角变大,那么我们就会遇到万向节锁定问题,如果它们变小(在两个连续的四元数之间),那么应该没有问题。我们可能只是将当前角度添加到以前的角度,并且有可能使它们处于所需的范围内。

于 2013-11-05T07:34:37.177 回答
0

我建议先计算罗德里格斯旋转。这很简单

考虑到您有两个向量ab

旋转轴将由它们的叉积N = a x b定义。

旋转角度将由它们的归一化点积 cos(theta) = a * b /(|| a || || b ||)定义

罗德里格斯旋转和四元数之间的转换公式在这里

于 2016-06-04T12:56:42.557 回答