简体   繁体   中英

OpenGL translation and rotation object

I have object which moves around circle. The object is a fish.
The moving:

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

I need to calculate rotation to move the fish forward (head first). Something like this:

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

The non-transformed orientation of the fish has the head pointing to the right.

I can not find the correct formula.

As you probably know, the basic parametric equation for a circle is, with rad being the radius and phi the angle in the range [0, 2*PI]:

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

As phi sweeps from 0 to 2 * PI, this starts on the right (positive x-axis), and moves counter-clockwise. Which means that the initial movement is upwards, in the direction of the positive y-axis.

The exact calculation you need depends on whether you want the animation to go clockwise or counter-clockwise, and where it starts. Since it's just a slight variation, I'll cover them in order.

For the counter-clockwise orientation, we can generalize the start point by simply adding a start angle. We'll also express the angle as a function of time t :

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

This gives you the components of the translation. For the rotation of the fish, since its base position is pointing right, but the initial movement of the circular motion is pointing up, we need to rotate it by 90 degrees before applying the circular motion. Which means that 0.5 * PI (90 degrees) are added to the angle used for the translation:

rotAng = 0.5 * PI + phiStart + speed * t

Without being familiar with the matrix library you are using, I hope that it uses the standard order for matrix multiplications. So expressed in code, the above would looks something like:

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));

To move clockwise instead, we can simply invert the sign of the angle. The only other difference is that since the initial movement is downwards now, the initial rotation of the fish is also 90 degrees clockwise, which corresponds to -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));

I couldn't find clear documentation for the matrix library you are using. It's possible that the second argument to glm::rotate() is the angle in degrees instead of radians. If that's true, those calls for the two cases become:

    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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM