【发布时间】:2018-07-22 07:34:30
【问题描述】:
我有以下代码:
#define GLM_ENABLE_EXPERIMENTAL
#include <iostream>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
// combines 2 XYZ euler angles given in degrees
glm::vec3 EulerCombine(const glm::vec3& first, const glm::vec3& second)
{
glm::vec3 output;
glm::mat4 m1 = glm::eulerAngleXYZ(glm::radians(first.x), glm::radians(first.y), glm::radians(first.z));
glm::mat4 m2 = glm::eulerAngleXYZ(glm::radians(second.x), glm::radians(second.y), glm::radians(second.z));
glm::extractEulerAngleXYZ(m2 * m1, output.x, output.y, output.z);
return glm::degrees(output);
}
// applies the XYZ euler rotation on p
glm::vec3 EulerRotate(const glm::vec3& p, const glm::vec3& euler)
{
glm::vec3 output;
output = glm::rotateX(p, glm::radians(euler.x));
output = glm::rotateY(output, glm::radians(euler.y));
output = glm::rotateZ(output, glm::radians(euler.z));
return output;
}
int main(void)
{
glm::vec3 euler1(30, 20, 90); // euler angles in degrees
glm::vec3 euler2(20, 30, 10);
glm::vec3 euler3 = EulerCombine(euler1, euler2);
glm::vec3 p(-10, 7, 23);
glm::vec3 result1 = EulerRotate(EulerRotate(p, euler1), euler2);
glm::vec3 result2 = EulerRotate(p, euler3);
std::cout << result1.x << " " << result1.y << " " << result1.z << std::endl;
std::cout << result2.x << " " << result2.y << " " << result2.z << std::endl;
}
但它会打印:
17.9056 -6.99702 17.5622
17.2369 4.15094 19.0699
这是一个问题,因为 result1 和 result2(正在打印的矢量)应该是相同的。
我觉得我的 EulerCombine 函数必须是正确的,因为它几乎完全是 glm,但这意味着 EulerRotate 不正确 - 但我认为 XYZ 欧拉角意味着你先在 X 轴上旋转它,然后在 Y 轴上旋转其次是Z轴。
怎么了?
【问题讨论】:
-
正确的轮换顺序 - 每次都很容易绊倒......恕我直言,你必须在
EulerRotate()glm::rotateX(glm::rotateY(glm::rotateZ(p, glm::radians(euler.z)), glm::radians(euler.y)), glm::radians(euler.x))申请。如果我只能在我们的软件中找到一些我做对的代码......(......我会写一个答案。) -
我认为 XYZ 欧拉角意味着你先在 X 轴上旋转它,然后在 Y 轴上再在 Z 轴上旋转。 把它转过来:p 绕 Z 轴旋转,旋转p' 绕 Y 轴,p'' 绕 X 轴旋转。旋转不是可交换的(与平移相反)-因此顺序非常重要(并且使旋转在某种程度上变得复杂)。
标签: c++ glm-math euler-angles