【发布时间】:2020-02-04 14:23:04
【问题描述】:
我目前正在尝试实现一个四元数,我需要在其中进行欧拉到四元数的转换。我当前的实现看起来像这样,我从 here 中删减出来的
void Quaternion::FromEuler(double x, double y, double z)
{
z *= Math::DegToRad;
y *= Math::DegToRad;
x *= Math::DegToRad;
double xCos = Math::Cos(x / 2);
double xSin = Math::Sin(x / 2);
double yCos = Math::Cos(y / 2);
double ySin = Math::Sin(y / 2);
double zCos = Math::Cos(z / 2);
double zSin = Math::Sin(z / 2);
W = zCos * yCos * xCos + zSin * ySin * xSin;
X = zCos * yCos * xSin - zSin * ySin * xCos;
Y = zSin * yCos * xSin + zCos * ySin * xCos;
Z = zSin * yCos * xCos - zCos * ySin * xSin;
}
我正在使用以下单元测试来测试实现
TEST(Quaternions, FromEuler)
{
Quaternion quaternion(45, 90, 180);
ExpectNear(quaternion, 0.6532815, -0.2705981, 0.6532815, 0.270598);
}
以下方式失败。
Expected | Actual
X 0.6533 -0.6533
Y -0.2706 0.2706
Z 0.6533 0.6533
W 0.2706 0.2706
预期值是从各种网站获得的,它们产生的值相同,但符号不同,类似于我当前的输出与预期输出的差异。
我也尝试了几种不同的实现,都产生了相同类型的失败。
这是因为轮换有several representations,在这种情况下,我的单元测试失败实际上是一个假阴性?如果是这样,我该如何实施正确的单元测试?
【问题讨论】:
-
Math::命名空间是什么?这是什么图书馆? -
这是我的,函数调用只是标准库的包装。 DegToRad 实现为 M_PI / 180.0
-
不能完全是reproduce,不清楚您的代码中的变量与链接的维基百科页面中的变量有何关系。
Quaternion在你的代码中是如何定义的? -
我在实现中更改了参数的顺序,所以它是 (X, Y, Z) 而不是维基百科的 (Z, Y, X) 顺序 - 如果您在你的主要功能它会输出相同的。这是完整的四元数实现。有点长添加到 OP。 hastebin.com/zoxojokiyi.cpp
-
您的问题似乎是混合了通用的
X,Y,Z名称,其中Conversion between quaternions and Euler angles 通常用yaw, pitch, roll来描述,而您选择的Axes Convention 很重要。
标签: c++ unit-testing quaternions euler-angles