对象坐标上的旋转和平移

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 中添加或减去一些值,等等。

【讨论】:

是的,你明白我想要传达的想法。您的解决方案实际上就是我所做的,并且在某种程度上有效。谢谢

以上是关于对象坐标上的旋转和平移的主要内容,如果未能解决你的问题,请参考以下文章

平移,轴对称的性质是啥?旋转呢?

查找三个坐标系之间的旋转和平移

缩放、旋转、平移 w。 openGl ES 2.0 中的矩阵

平移和轴对称会使点的坐标发生怎样的变化?

矩阵的平移旋转与缩放

坐标系的概念和坐标系之间的变换