c++ - glm::rotate() 改变旋转轴,但为什么呢?

标签 c++ glm-math

简单的测试代码

glm::mat4 m = glm::rotate(glm::mat4(1.0f), 0.78f, glm::vec3(0,1,0));

while (true) {
    glm::vec3 axis = glm::normalize(glm::vec3(m[0]));  // right vector
    PRINT_VEC("{0:.3f} {1:.3f} {2:.3f}", axis.x, axis.y, axis.z);
    m = glm::rotate(m, glm::radians(5.f), axis);  // 5 degrees each iteration
}

因此,假设我有一个模型矩阵从标识绕 y 轴旋转 0.78 弧度,然后每一帧我都将围绕局部右 vector 旋转,这是矩阵的第一列(假设右手系统)。由于右 vector 是我旋转的轴,我希望它是恒定的,但事实并非如此。我不明白为什么 glm::rotate 也会改变旋转轴。

输出变化非常大,所以我不认为这是浮点精度错误。

0.657 -0.424 -0.623
0.643 -0.482 -0.595
0.626 -0.539 -0.563
0.608 -0.593 -0.527
0.588 -0.646 -0.487
0.566 -0.696 -0.442
0.543 -0.742 -0.393
0.518 -0.785 -0.339
0.491 -0.824 -0.281
0.464 -0.858 -0.219
0.435 -0.887 -0.153
0.406 -0.910 -0.084
0.377 -0.926 -0.012
0.347 -0.936 0.063
0.319 -0.937 0.140
0.292 -0.931 0.218
0.267 -0.917 0.296
0.244 -0.895 0.374
0.224 -0.864 0.450
0.208 -0.826 0.524

最佳答案

m[0] 并不是真正的“局部右 vector ”。它是 world 坐标中的右 vector 。 local 坐标中的右 vector 是 vec3(1,0,0),您应该使用它来实现所需的旋转:

glm::mat4 m = glm::rotate(glm::mat4(1.0f), 0.78f, glm::vec3(0,1,0));

while (true) {
    glm::vec3 axis = glm::normalize(glm::vec3(m[0]));  // right vector
    PRINT_VEC("{0:.3f} {1:.3f} {2:.3f}", axis.x, axis.y, axis.z);
    m = glm::rotate(m, glm::radians(5.f), glm::vec3(1,0,0));  // 5 degrees each iteration
}

打印:

0.711 0.000 -0.703
0.711 0.000 -0.703
0.711 0.000 -0.703
...

请注意,GLM 转换函数,如 glm::rotate,在右侧应用转换;即

m = m * glm::rotate(glm::mat4(1.0f), glm::radians(5.f), axis);

他们希望轴位于转换前的坐标系中——即本地坐标系。相反,您的代码将 vector vec3(1,0,0) 转换为世界坐标系,然后围绕具有这些数字坐标的局部 vector 应用局部旋转,结果是任意 vector 。

事实上,您可以使用世界空间中的 来执行相同的旋转。但是,您需要在左侧手动相乘:

m = glm::rotate(glm::mat4(1.0f), glm::radians(5.f), axis) * m;

给出的结果与上面的第一个版本相同。

编辑:使用正确代码与错误代码呈现的列 vector :

enter image description here enter image description here

关于c++ - glm::rotate() 改变旋转轴,但为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70515349/

相关文章:

c++ - QListWidget 中可交互调整大小的行

c++ - 使用键旋转对象

c++ - OpenGL - 将变换应用于 3D 空间中的多边形

c++ - 是否实例化了所有有效模板?

c# - C/C++ 等同于 C# 参数

c++ - 是否有一个函数返回 glm 中两个 4x4 矩阵之间的变化

c++ - 在带有 glm vector 的结构中没有合适的默认构造函数可用

c++ - 在glm中重用矩阵?

c++ - 构造函数和 operator= 具有动态内存分配

c++ - 非静态数据成员的无效使用