四元数转旋转矩阵,使用Eigen库出现错误的值

10

我正在尝试使用四元数绕Y轴将一个物体旋转45度。在指定四元数后,我尝试获取旋转矩阵。但是我看到的值是不正确的。

Eigen::Quaterniond q;
q.x() = 0;
q.y() = 1;
q.z() = 0;
q.w() = PI/8;    // Half of the rotation angle must be specified, even IDK why

Eigen::Matrix3d R = q.normalized().toRotationMatrix();
std::cout << "R=" << std::endl << R << std::endl;

输出:

R=
-0.732    -0   -0.680
     0     1       -0
 0.680     0   -0.732


由于OpenGL沿Y轴的旋转矩阵应为:

enter image description here

因此,我期望的输出应该是:

R=
 0.707     0    0.707
     0     1        0
-0.707     0    0.707

不仅值偏差很小,而且错误的符号导致了一些意外的旋转。由于有负号,我的魔方会多转180度加上指定的角度。我已经为此苦恼了一整天,有人能告诉我我错在哪里吗?


我对四元数一无所知,但我知道/8对应于22.5°。45°是/4。 - Logicrat
1
@Logicrat 即使我不知道为什么,但你必须指定角度的一半。因此,如果我要旋转 PI/4,我必须将其指定为 PI/8 - DollarAkshay
啊,是的,完全忘记了 - 已经五年没用四元数了。你的PI定义来自哪里?它有多准确? - Rostislav
我认为最好还是使用更精确的常量库 <cmath>,以避免出现误差积累。 - Rostislav
哦,等等,你初始化时没有定义w、x、y、z坐标 - 它们应该按照这里所示进行定义 - 即 w = cos(theta/2), x = axis_x * sin(theta / 2), y = axis_y * sin(theta / 2), z = axis_z * sin(theta / 2)。或者在eigen中,使用这个构造函数Quaternion (const AngleAxisType &aa) - Rostislav
显示剩余3条评论
1个回答

25
您初始化四元数的方式不正确。如果您直接初始化四元数的坐标,您应该考虑定义

enter image description here

另外,Eigen中的Quaternion类提供了从轴角表示构造函数。

以下是代码:

#include <Eigen/Geometry>
#include <iostream>

void outputAsMatrix(const Eigen::Quaterniond& q)
{
    std::cout << "R=" << std::endl << q.normalized().toRotationMatrix() << std::endl;
}

void main()
{
    auto angle = M_PI / 4;
    auto sinA = std::sin(angle / 2);
    auto cosA = std::cos(angle / 2);

    Eigen::Quaterniond q;
    q.x() = 0 * sinA;
    q.y() = 1 * sinA;
    q.z() = 0 * sinA;
    q.w() = cosA;    

    outputAsMatrix(q);
    outputAsMatrix(Eigen::Quaterniond{Eigen::AngleAxisd{angle, Eigen::Vector3d{0, 1, 0}}});
}

输出您所期望的内容:

R=
 0.707107         0  0.707107
        0         1         0
-0.707107         0  0.707107
R=
 0.707107         0  0.707107
        0         1         0
-0.707107         0  0.707107

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接