Rolling balls - changing direction

Started by
0 comments, last by Dexus 18 years, 7 months ago
From various threads and websites I've figured out how to rotate a ball based on its velocity and direction. I know how to work out the angular velocity and the axis of rotation. The problem comes when I want the ball to change direction or when the ball collides with something. My first code went something like this:

glPushMatrix();

    //Translate to the position of the ball
    glTranslatef(pos.x,pos.y,pos.z);

    //Angle to rotate the ball - note this is cumulative for each render
    angle += RAD_TO_PI * ((vel.length() / radius));

    //Axis of rotation is perpedicular to velocity vector and vertical vector
    Vector3D axis = vel.cross(Vector3D(0.0,-1.0,0.0));
    axis.normalize();

    //Apply rotation
    glRotatef(angle,axis.x,axis.y,axis.z);

    //Draw the ball
    glCallList(displayList);
glPopMatrix();


The problem with this is that when the ball changes direction (eg when it hits a wall) the orientation of the ball changes drastically. This is because the orientation of the ball in the previous frame is not stored anywhere - only the angle is stored. This means that all rotations are performed from an initial default orientation. My other method I adapted from this post: http://www.gamedev.net/community/forums/viewreply.asp?ID=1189690 Here's more or less what my rotation code looks like now:

//initialize rotation matrix class
Matrix4f rotationMatrix;
//set initial rotation to the identity matrix
rotationMatrix.setIdentity();


//During the render routine:
glPushMatrix();

    //Translate to the position of the ball
    glTranslatef(pos.x,pos.y,pos.z);

    //Angle to rotate the ball
    angle = RAD_TO_PI * ((vel.length() / radius));

    //Axis of rotation is perpedicular to velocity vector and vertical vector
    Vector3D axis = vel.cross(Vector3D(0.0,-1.0,0.0));
    axis.normalize();

    //Rotate the matrix using the matrix class' rotate method - this
    //appears to be equivelent to glRotate
    rotationMatrix.rotate(angle,axis);

    //Multiply the current model view matrix with the rotation matrix
    glMultMatrix(rotationMatrix);

    //Draw the ball
    glCallList(displayList);
glPopMatrix();


This code uses a matrix class called rotationMatrix to store the rotation. As in the first method it works fine until it changes direction; the orientation of the ball is preserved which is good but it seems to combine the previous rotation matrix with the new one and then the ball seems to spin in any arbitary direction. Somehow I need to preserve the orientation from the previous spinning direction but not the actual rotation. This is getting pretty hard to explain but I know that it's quite a common problem. I've seen it come up quite a few times in previous forum posts but I haven't found any real solutions to it. I know I could use Quaternions but I don't really want to have to deal with those just yet. I have an example from a pool game which only seems to use matrices and matrix transformations but it's written in DirectX which I haven't had any experience in yet. Can anyone point out the flaws in my code or point me in the direction of a solution that works?
Advertisement
Right ok, looks like my request was harder than I thought. In fact I managed to figure out how to do exactly what I wanted using Quaternions. I wasn't sure if it work as I couldn't understand the concepts behind it. Even after figuring out the code I wasn't able to combine the rotations until I read somewhere that you have to multiply the quaternions in reverse order! Now it works perfectly. Quaternions rock! :D

This topic is closed to new replies.

Advertisement