LWJGL:使用 "partial" 轴的奇怪矩阵旋转效果
LWJGL: Strange Matrix rotation effect using "partial" axis
我目前正在学习 https://learnopengl.com/ 上的 OpenGL 教程,除了我在 Java 而不是 C++ 中学习。进展顺利,但我偶然发现了一些可能由实施差异引起的问题,除非我做错了什么。
我在刚刚渲染并旋转立方体的部分。教程给出了以下代码:
model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));```
为了详细说明,model
是模型矩阵。 GLM 库用于旋转此矩阵,使用 glfwGetTime()
其中 returns 自初始化以来的时间(以秒为单位)。我很好奇的部分是 vec3(0.5f, 1.0f, 0.0f)
。在这里,他们指定要围绕哪个 Euler angles/axes 旋转,从外观上看,为 X 轴指定 0.5f
与此处的 Y 相比,它在 X 轴上旋转了一半的量。生成的立方体如下所示:
https://i.imgur.com/caK1BTS.mp4
回到Java,我设置了一个类似的东西。我 运行 模型矩阵上的以下内容:
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.5f, 1.0f, 0.0f), model, model);
生成的立方体像这样旋转,很奇怪:
https://i.imgur.com/0ZqpgEA.mp4
如果我通过分离每次旋转影响哪个轴来改变情况,立方体看起来很正常,就像这个视频中一样:
https://i.imgur.com/u2zV2Zo.mp4
代码:
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.0f, 1.0f, 0.0f), model, model);
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(25), new Vector3f(1.0f, 0.0f, 0.0f), model, model);
这里的不同之处在于,我不是做 "half" 一个轴,而是在一个完整的轴上做一半的度数。
那么我的问题是: 尝试绕未设置为 1.0f
的轴旋转是我的错误吗? 4x4 矩阵 rotate
函数的 GLM 实现是否与 LWJGL-Utils 的 Matrix4f
class 不同?
PS:我正在使用 LWJGL 2 和 Java 8u141。如果需要,我很乐意提供更多关于我的设置的代码,但渲染立方体的整个过程非常复杂。我已经从头开始完成本教程 2-3 次,结果相同,所以我认为这里有问题。
根据 this source in GLM GitHub repository GLM does rotation axis normalization before constructing transformation matrix. LWJGL-Utils Matrix4f class 不会这样做。所以你可能应该自己标准化旋转轴 (0.5f, 1.0f, 0.0f)
。
此外,我不确定您将旋转轴称为 'Euler angles' 时是否正确。欧拉角可以定义围绕第一轴的旋转,然后定义围绕派生的第二轴的旋转,依此类推。他们基本上将旋转定义为围绕两个或三个基轴的三个旋转的组合。这里有一个旋转轴和一个旋转角度。
参见:
- Wikipedia: Euler Angles
- Wikipedia: Axis–angle representation。它说由于单位长度只需要旋转轴的两个分量,但要在笛卡尔坐标中描述旋转轴,您将需要 3 个分量单位长度向量。
我目前正在学习 https://learnopengl.com/ 上的 OpenGL 教程,除了我在 Java 而不是 C++ 中学习。进展顺利,但我偶然发现了一些可能由实施差异引起的问题,除非我做错了什么。
我在刚刚渲染并旋转立方体的部分。教程给出了以下代码:
model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));```
为了详细说明,model
是模型矩阵。 GLM 库用于旋转此矩阵,使用 glfwGetTime()
其中 returns 自初始化以来的时间(以秒为单位)。我很好奇的部分是 vec3(0.5f, 1.0f, 0.0f)
。在这里,他们指定要围绕哪个 Euler angles/axes 旋转,从外观上看,为 X 轴指定 0.5f
与此处的 Y 相比,它在 X 轴上旋转了一半的量。生成的立方体如下所示:
https://i.imgur.com/caK1BTS.mp4
回到Java,我设置了一个类似的东西。我 运行 模型矩阵上的以下内容:
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.5f, 1.0f, 0.0f), model, model);
生成的立方体像这样旋转,很奇怪:
https://i.imgur.com/0ZqpgEA.mp4
如果我通过分离每次旋转影响哪个轴来改变情况,立方体看起来很正常,就像这个视频中一样:
https://i.imgur.com/u2zV2Zo.mp4
代码:
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.0f, 1.0f, 0.0f), model, model);
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(25), new Vector3f(1.0f, 0.0f, 0.0f), model, model);
这里的不同之处在于,我不是做 "half" 一个轴,而是在一个完整的轴上做一半的度数。
那么我的问题是: 尝试绕未设置为 1.0f
的轴旋转是我的错误吗? 4x4 矩阵 rotate
函数的 GLM 实现是否与 LWJGL-Utils 的 Matrix4f
class 不同?
PS:我正在使用 LWJGL 2 和 Java 8u141。如果需要,我很乐意提供更多关于我的设置的代码,但渲染立方体的整个过程非常复杂。我已经从头开始完成本教程 2-3 次,结果相同,所以我认为这里有问题。
根据 this source in GLM GitHub repository GLM does rotation axis normalization before constructing transformation matrix. LWJGL-Utils Matrix4f class 不会这样做。所以你可能应该自己标准化旋转轴 (0.5f, 1.0f, 0.0f)
。
此外,我不确定您将旋转轴称为 'Euler angles' 时是否正确。欧拉角可以定义围绕第一轴的旋转,然后定义围绕派生的第二轴的旋转,依此类推。他们基本上将旋转定义为围绕两个或三个基轴的三个旋转的组合。这里有一个旋转轴和一个旋转角度。
参见:
- Wikipedia: Euler Angles
- Wikipedia: Axis–angle representation。它说由于单位长度只需要旋转轴的两个分量,但要在笛卡尔坐标中描述旋转轴,您将需要 3 个分量单位长度向量。