对象坐标上的旋转和平移
Posted
技术标签:
【中文标题】对象坐标上的旋转和平移【英文标题】:Rotation and Translation on Object coordinate 【发布时间】:2014-10-02 08:53:32 【问题描述】:我正在用 OpenGL 编写一个简单的应用程序。我有一个模型,我想围绕它的中心(局部坐标)旋转,然后将它连同它的局部坐标一起平移。我做了两个场景, 旋转然后平移,反之亦然。在第一种情况下,我得到了正确的旋转,但是模型然后根据世界坐标而不是模型(本地)坐标进行平移。当我首先翻译时,我得到了正确的翻译,但旋转不再围绕模型中心。 这是代码,
glPushMatrix();
// ignore this
/*glRotatef(_zRoll, 0.0, 0.0, 1.0);
glRotatef(_yTilt, 1.0, 0.0, 0.0);
glRotatef(_xPan, 0.0, 1.0, 0.0);*/
glScalef(scale, scale, scale);
glTranslatef(0.0, 0.0, -2.0);
glTranslatef(_xTranslate, _yTranslate, _zTranslate); // The required translation
// The required rotation
glRotatef(_yangle, 0.0, 1.0, 0.0);
glRotatef(_zangle, 0.0, 0.0, 1.0);
glRotatef(_xangle, 1.0, 0.0, 0.0);
glTranslatef(coord.x, coord.y, coord.z); // translate to the model center
glCallList(aHelix);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glPopMatrix();
glutSwapBuffers();
【问题讨论】:
插入关于已弃用的固定函数管道的标准免责声明,目前的做法是使用着色器并管理您自己的转换矩阵 不清楚你想做什么以及你的价值观意味着什么。很少有带有 cmets 的插图或屏幕截图会很好。据我所知,您需要先翻译所有内容,然后再进行旋转。 @keltar 我想做的基本上是用旋转方向移动(平移)模型。例如,如果我将模型向左旋转 90 度(围绕 z 轴),然后沿 -x 轴移动对象,模型应该向下移动(根据模型(本地)坐标,而不是根据世界坐标。 @jouzef19 您的最后一条评论与“旋转不再围绕模型中心”相矛盾。无论如何,我已经说出了我想说的 - 是你在寻找答案,所以你可以用其他人可以理解的方式来描述问题。从我的角度来看,情况并非如此,对不起。由于只有 两种 组合可能,并且两种 都不能让你满意 - 我真的不明白你想要它是什么。 @jouzef19 从您的评论来看,您似乎想先翻译,然后旋转。翻译然后旋转的结果(记住操作是按与代码相反的顺序应用的)与期望的结果有何不同?你得到什么和你期望什么的图片真的很有帮助。 【参考方案1】:我想我现在明白你在寻找什么了。我会尝试重述你想要的,所以如果我弄错了,请纠正我。
让我们使用以下顶点坐标(列即顶点)的简单模型:
[3 2 3 4]
[5 2 3 2]
[0 0 0 0]
[1 1 1 1]
所以第一个点在 x=3, y=5, z=0。绘制这个模型我们得到:
如果我们简单地旋转模型(在本例中为 43°),然后在 Y 方向(向上)平移它,比如 4 个单位,我们会得到:
模型现在在 Y 方向移动了 4 个单位,但在世界坐标系中。据我了解,上面的结果是您不想要的。
如果我们将模型沿旋转后指向的方向平移,我们会得到:
我相信,这正是您确实想要的。这是我使用的代码。
glTranslatef(3.0, 3.0, 0.0);
glTranslatef(-2.728, 2.924, 0.0);
glRotatef(43.0, 0.0, 0.0, 1.0);
glTranslatef(-3.0, -3.0, 0.0);
我先将模型旋转 43 度,然后根据更新后的局部 Y 方向进行平移。我通过获取矢量[0 4 0 0]
并使用我用于模型的相同 43° 旋转矩阵旋转它来获得硬编码的平移矢量。这并不容易以编程方式完成(至少在固定管道中),并且随着后续轮换变得更糟。
但事实证明,通过先执行 [0 4 0 0]
的转换,然后进行旋转,您会得到完全相同的结果(您可以手动验证):
glTranslatef(3.0, 3.0, 0.0);
glRotatef(43.0, 0.0, 0.0, 1.0);
glTranslatef(0.0, 4.0, 0.0);
glTranslatef(-3.0, -3.0, 0.0);
下面是第二组代码对比的结果:
问题在于,如果您进行任何后续旋转/平移,您的坐标系仍然会一团糟。为了解决这个问题,您需要确保使用累加器进行旋转和平移,并将它们一次全部应用于原始模型,而不是进行小的增量更改。因此,每按一次向上箭头键,为您的 _yTranslate
变量添加一些增量值,每按一次“旋转”按钮,从 _zangle
中添加或减去一些值,等等。
【讨论】:
是的,你明白我想要传达的想法。您的解决方案实际上就是我所做的,并且在某种程度上有效。谢谢以上是关于对象坐标上的旋转和平移的主要内容,如果未能解决你的问题,请参考以下文章