OpenGL翻译和旋转对象

时间:2014-12-04 18:02:41

标签: c++ opengl

我有围绕圆圈移动的物体。对象是一条鱼 感动:

mesh->objectModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(5.0f * sin(elapsedTime), initialY, 5.0f * cos(elapsedTime)));

我需要计算旋转以使鱼向前移动(头部先行)。 像这样:

    mesh->objectModelMatrix = glm::rotate(mesh->objectModelMatrix, elapsedTime, glm::vec3(0.0f, 0.0f, 1.0f));

鱼的未转化方向的头部指向右侧。

我找不到正确的公式。

1 个答案:

答案 0 :(得分:0)

您可能知道,圆的基本参数方程是,rad是半径,phi范围内的角度为[0,2 * PI]:

x = rad * cos(phi)
y = rad * sin(phi)

phi从0扫描到2 * PI时,它从右侧(正x轴)开始,并逆时针移动。这意味着初始运动向上,在正y轴方向上。

您需要的精确计算取决于您是希望动画顺时针还是逆时针,以及它开始的位置。由于它只是一个微小的变化,我将按顺序覆盖它们。

对于逆时针方向,我们可以通过简单地添加起始角来概括起点。我们还将角度表示为时间t

的函数
x = rad * cos(phiStart + speed * t)
y = rad * sin(phiStart + speed * t)

这为您提供了翻译的组成部分。对于鱼的旋转,由于其基准位置指向右侧,但是圆形运动的初始运动朝上,我们需要在施加圆周运动之前将其旋转90度。这意味着0.5 * PI(90度)被添加到用于翻译的角度:

rotAng = 0.5 * PI + phiStart + speed * t

不熟悉您正在使用的矩阵库,我希望它使用矩阵乘法的标准顺序。如此在代码中表达,上面看起来像:

float phiStart = 0.0f;  // start at right, set different start angle if desired
float phi = phiStart + elapsedTime;  
mesh->objectModelMatrix =
    glm::translate(glm::mat4(1.0f),
                   glm::vec3(5.0f * cos(phi), initialY, 5.0f * sin(phi)));
mesh->objectModelMatrix =
    glm::rotate(mesh->objectModelMatrix,
                0.5f * M_PI + phi, glm::vec3(0.0f, 0.0f, 1.0f));

要顺时针移动,我们可以简单地反转角度的符号。唯一的另一个区别是,由于现在初始运动向下,鱼的初始旋转也是顺时针90度,相当于-0.5 * PI

float phiStart = 0.5f * M_PI;  // start at top, set different start angle if desired
float phi = phiStart - elapsedTime;  
mesh->objectModelMatrix =
    glm::translate(glm::mat4(1.0f),
                   glm::vec3(5.0f * cos(phi), initialY, 5.0f * sin(phi)));
mesh->objectModelMatrix =
    glm::rotate(mesh->objectModelMatrix,
                -0.5f * M_PI + phi, glm::vec3(0.0f, 0.0f, 1.0f));

我找不到您正在使用的矩阵库的清晰文档。 glm::rotate()的第二个参数可能是以度为单位而不是弧度的角度。如果这是真的, 这两个案件的要求变成了:

    glm::rotate(mesh->objectModelMatrix,
                90.0f + phi * (180.0f / M_PI), glm::vec3(0.0f, 0.0f, 1.0f));

    glm::rotate(mesh->objectModelMatrix,
                -90.0f + phi * (180.0f / M_PI), glm::vec3(0.0f, 0.0f, 1.0f));