Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确地从Euler角度转换并乘以四元数?_C++_Unity3d_Quaternions - Fatal编程技术网

C++ 如何正确地从Euler角度转换并乘以四元数?

C++ 如何正确地从Euler角度转换并乘以四元数?,c++,unity3d,quaternions,C++,Unity3d,Quaternions,我们正在尝试将Euler(X,Y,Z)=俯仰偏航滚转中的局部空间增量旋转转换为绝对世界空间旋转四元数 我们通过将每个增量旋转转换为四元数,并累积(通过乘法)四元数旋转来生成世界空间四元数 但是,我们的结果旋转显示对象围绕世界空间轴而不是局部对象轴旋转 我遵循这个伪代码循环和C++,并且在UnyDIS3D中构建了相同的(自从四元数运算被提供以来,它工作正常)。p> 有人对这里出了什么问题有什么指点吗 Quaternion qacc; Quaternion q1; loop { quacc

我们正在尝试将Euler(X,Y,Z)=俯仰偏航滚转中的局部空间增量旋转转换为绝对世界空间旋转四元数

我们通过将每个增量旋转转换为四元数,并累积(通过乘法)四元数旋转来生成世界空间四元数

但是,我们的结果旋转显示对象围绕世界空间轴而不是局部对象轴旋转

我遵循这个伪代码循环和C++,并且在UnyDIS3D中构建了相同的(自从四元数运算被提供以来,它工作正常)。p> 有人对这里出了什么问题有什么指点吗

Quaternion qacc;
Quaternion q1;

loop
{
    quacc = quacc * q1.degreeToQuaternion(xRot, yRot, zRot);
}

...


void Quaternion::degreeToQuaternion( double yaw, double pitch, double roll) // yaw (Z), pitch (Y), roll (X)
{
    yaw = yaw * M_PI / 180.;
    pitch = pitch * M_PI / 180.;
    roll = roll * M_PI / 180.;

    radianToQuaternion(yaw, pitch, roll);
}


void Quaternion::radianToQuaternion( double yaw, double pitch, double roll) // yaw (Z), pitch (Y), roll (X)
{
    double cy = cos(yaw * 0.5);
    double sy = sin(yaw * 0.5);
    double cp = cos(pitch * 0.5);
    double sp = sin(pitch * 0.5);
    double cr = cos(roll * 0.5);
    double sr = sin(roll * 0.5);

    this->w = cy * cp * cr + sy * sp * sr;
    this->x = cy * cp * sr - sy * sp * cr;
    this->y = sy * cp * sr + cy * sp * cr;
    this->z = sy * cp * cr - cy * sp * sr;
}

Quaternion operator * (Quaternion q0, Quaternion q1)
{
    Quaternion q2;
    double mag;

    q2.w = q0.w * q1.w - q0.x * q1.x - q0.y * q1.y - q0.z * q1.z;
    q2.x = q0.w * q1.x + q0.x * q1.w + q0.y * q1.z - q0.z * q1.y;
    q2.y = q0.w * q1.y - q0.x * q1.z + q0.y * q1.w + q0.z * q1.x;
    q2.z = q0.w * q1.z + q0.x * q1.y - q0.y * q1.x + q0.z * q1.w;

    mag = sqrt (q2.w * q2.w + q2.x * q2.x + q2.y * q2.y + q2.z * q2.z);

    q2.w /= mag;
    q2.x /= mag;
    q2.y /= mag;
    q2.z /= mag;

    return q2;
}

怎么回事?在编写复杂的数学代码时,请确保有单元测试。不要只期望这会奏效。如果输入的
sr
实际上是
cr
可能会毁了你的一天。人们还没有真正意识到,如果我们普遍采用四元数,并从所有软件和文献中去掉欧拉角,世界和平是可以实现的。更严肃的是,欧拉角增量的来源是什么?这告诉我,你有一些数值积分,以欧拉角及其导数作为状态向量。这是正确的吗?处理这种情况的最佳方法是使用四元数A及其导数作为状态向量。有一个封闭式方程可以将三维角速度转换为四元数的导数,您应该能够从任何标准文本中查找这些导数。您应该仅对关键帧使用Euler角,对UI使用Euler角。在运行时,您应该使用SLERP处理四元数计算中间帧在使用Eigen库进行一些测试以替换我的代码后,似乎Unity和我的代码使用不同的坐标系是问题所在,并且交换x和y分量以及反转z会给出适当的Unity四元数。我会进一步测试。将三维角速度转换为导数的封闭式方程听起来在未来很有用@怎么回事?在编写复杂的数学代码时,请确保有单元测试。不要只期望这会奏效。如果输入的
sr
实际上是
cr
可能会毁了你的一天。人们还没有真正意识到,如果我们普遍采用四元数,并从所有软件和文献中去掉欧拉角,世界和平是可以实现的。更严肃的是,欧拉角增量的来源是什么?这告诉我,你有一些数值积分,以欧拉角及其导数作为状态向量。这是正确的吗?处理这种情况的最佳方法是使用四元数A及其导数作为状态向量。有一个封闭式方程可以将三维角速度转换为四元数的导数,您应该能够从任何标准文本中查找这些导数。您应该仅对关键帧使用Euler角,对UI使用Euler角。在运行时,您应该使用SLERP处理四元数计算中间帧在使用Eigen库进行一些测试以替换我的代码后,似乎Unity和我的代码使用不同的坐标系是问题所在,并且交换x和y分量以及反转z会给出适当的Unity四元数。我会进一步测试。将三维角速度转换为导数的封闭式方程听起来在未来很有用@松鼠