我正在使用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();
答案 0 :(得分:0)
我想我现在明白你在寻找什么。我会尝试重述你想要的东西,所以如果我弄错了,请纠正我。
让我们看一个带有以下顶点坐标的简单模型(列是顶点):
[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
中的某些值,依此类推