单元测试欧拉到四元数实现失败
Unit testing euler-to-quaternion implementation fails
我目前正在尝试实现一个四元数,我需要在其中进行欧拉到四元数的转换。我当前的实现看起来像这样,我从 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 的轮换吗?在这种情况下,我的单元测试失败实际上是假阴性?如果是这样,我该如何实施正确的单元测试?
通过简单的数学可以推断出您对结果的期望是错误的:z_deg == 180,即 z_rad == PI,将给出 zCos
值0.0:PI/2 的余弦为 0.0。知道了这一点,就可以简化 W
、X
、Y
、Z
的计算,忽略所有 zCos
.
的乘积
由于 x/2 和 y/2 也位于第一象限,因此 xCos
、xSin
、yCos
、ySin
的所有值和 zSin
是积极的。因此,X
的结果必须为负(0.0 减去一些正积)。而且,Y
的结果必须是正数:一些正数乘积加上 0.0.
这只是根据您的代码和给定的参数得出的。结论是,要么预期是错误的,要么你在你的算法中发现了一个错误。至少(正如预期的那样)实际结果是合理的:-)
那么,检查您的代码和期望,也许您混合了来自不同来源的实现和期望?或者,如果它们来自同一来源并且您没有复制错误,则原作者计算错误...
我目前正在尝试实现一个四元数,我需要在其中进行欧拉到四元数的转换。我当前的实现看起来像这样,我从 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 的轮换吗?在这种情况下,我的单元测试失败实际上是假阴性?如果是这样,我该如何实施正确的单元测试?
通过简单的数学可以推断出您对结果的期望是错误的:z_deg == 180,即 z_rad == PI,将给出 zCos
值0.0:PI/2 的余弦为 0.0。知道了这一点,就可以简化 W
、X
、Y
、Z
的计算,忽略所有 zCos
.
由于 x/2 和 y/2 也位于第一象限,因此 xCos
、xSin
、yCos
、ySin
的所有值和 zSin
是积极的。因此,X
的结果必须为负(0.0 减去一些正积)。而且,Y
的结果必须是正数:一些正数乘积加上 0.0.
这只是根据您的代码和给定的参数得出的。结论是,要么预期是错误的,要么你在你的算法中发现了一个错误。至少(正如预期的那样)实际结果是合理的:-)
那么,检查您的代码和期望,也许您混合了来自不同来源的实现和期望?或者,如果它们来自同一来源并且您没有复制错误,则原作者计算错误...