旋转后在 3D 世界中翻译的正确方法?

Posted

技术标签:

【中文标题】旋转后在 3D 世界中翻译的正确方法?【英文标题】:Correct way to translate in a 3D world after rotating? 【发布时间】:2016-07-07 20:16:48 【问题描述】:

我在我的 3D 世界中生成了一个基本立方体。我可以围绕相机正确旋转,但是当我旋转后平移时,平移不正确。 例如,如果我旋转 90 度并平移到 Z 轴,它会像在 X 轴上平移一样移动。

glLoadIdentity();
    glRotatef(angle,0,1,0);       //Rotate around the camera.
    glTranslatef(movX,movY,movZ); //Translate after rotating around the camera.
glCallList(cubes[0]);

我需要一些帮助。另外,我尝试在旋转之前进行平移,但旋转不在相机上。它位于立方体的边缘。

【问题讨论】:

【参考方案1】:

请记住,在 OpenGL 中,变换应用于相机,而不是渲染的对象;所以你观察到你所期望的变换的

同样在 OpenGL 中,Y 轴和 Z 轴是翻转的(Y 是垂直的),因此您可以观察到水平平移而不是垂直平移。

另外,由于对象绕 Y 轴旋转了 90 度,因此 X 轴和 Z 轴相互替换(其中一个轴颠倒了)。

【讨论】:

这给了我一些有用的信息。您知道在 3D 空间中正确翻译的有用教程吗? 我想只是阅读坐标几何和线性代数教科书,特别注意矩阵变换和排序【参考方案2】:

willywonkadailyblah 的回答只对了一半。因为您使用的是旧的 OpenGL,所以您使用的是旧的矩阵堆栈。当您进行 glRotatef 和 glTranslatef 调用时,您正在修改 modelview 矩阵。模型视图矩阵实际上是模型的矩阵和相机的视图矩阵预先组合(已经相乘)。这些矩阵决定了您的对象在 3D 空间中的位置以及您的观察位置/世界方向的位置。因此,您可以将调用视为移动相机,但将它们视为移动和旋转世界可能更容易。

这些旋转和平移调用是线性变换。这有一个精确的定义,但就我们的目的而言,这意味着您可以将转换表示为一个矩阵,然后将其与点的坐标相乘以将转换应用于一个点。现在矩阵乘法不可交换,即 AB != BA。所有这些都是说当你旋转时,然后翻译它与翻译和旋转不同,我想你知道。但是,当您再次平移、旋转和平移时,可能会更难理解您实际在做什么。更糟糕的是,即使你在那里投入一些缩放。因此,如果您认真学习 OpenGL,我建议您学习线性变换的工作原理并为对象和相机维护自己的矩阵。

learnopengl.org 是一个很棒的网站,但它教给您的是现代 OpenGL,而不是您当前使用的。但是transformations 和coordinate systems 上的课程通常可能会有所帮助,即使没有确切的代码供您遵循

【讨论】:

我会检查您的链接并开始关注/学习这些教程。我从来没有意识到有一个新的和一个旧的 OpenGL,而我使用的是旧的。谢谢。 是的,直到今年早些时候我都没有,哈哈。我首先在旧的 OpenGL 中学习。在旧的 OpenGL 中,如果你想传入模型视图矩阵而不是使用转换,你仍然可以使用 LoadMatrix。

以上是关于旋转后在 3D 世界中翻译的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 3D 中组合旋转

[Unity 3d] 判断手指/鼠标按下触发在UI上的正确方法

unity3d物体旋转

[翻译]观察变换View Transform (Direct3D 9)

创建一个可旋转的 3D 地球

通过 SVD 从基本矩阵中提取翻译的正确方法