Realistic rotation of a ball as it rolls on a surface

Started by
2 comments, last by CHollman82 14 years, 8 months ago
So I have been going through the NeHe tutorials and I took one of them and started expanding on it to the point where I have a marble-like sphere resting on a surface and the arrow keys can be used to move it around on this surface. As the ball moves along the surface I rotate it to make it look like it is rolling and not just sliding on ice or something. This works fine if you go straight along any axis from the origin but as soon as you combine two directions of movement the rotation is wrong. I understand why this is happening, for example if move the ball forward and it rotates a quarter turn along the x-axis the effect is that the z-axis of the ball is rotated to match the y-axis in the world coordinate space and the y-axis now matches the z-axis of the world (essentially, the y and z axes were swapped), so now when I move left or right it starts spinning like a top (on its poles, if it were a planet) instead of rotating correctly to match its movement. I am hoping there is an easy way to correct, or bypass, this effect without having to take into account the angle of rotation on all 3 axes to calculate the amount of rotation on all 3 axes every time I want to move the ball. I was thinking you could somehow "re-align" the balls axes to match the world coordinate space without effecting the appearance of the texture itself after each discrete rotation is performed. Lacking that, I would love someone to explain the math required to calculate the correct rotation angle on all 3 axes to move the ball on any vector (2D, on a surface) given its current rotation. Thanks!
codeXtremeif(you->intelligence < radish->intelligence) you->STFU();
Advertisement
You'll need an angular velocity vector, and a sane way to store an rotation, ie quaterions. The angular vector is one whos direction is in the axis of rotation, and whos length is proportionate to the angular rate. This vector is going to be perpindicular to the velocity of the ball and the normal of the surface.

This assumes the ball will never spin like a top:
Vector angV = Normalize(Cross(normal, velocity)) * Len(velocity) / radius;

Which can be converted to a quaternion:
Quaternion qAngV = .5 * Quaternion(0,angV) * previousQAngV;

You can then use your angular quaternion to integrate your orientation:
Quaternion orientation = previousOrientation + qAngv * dt;

More info on that is available here:
http://gafferongames.com/game-physics/physics-in-3d/
Short answer...

Don't use Euler angles. Instead, represent the ball's orientation using a quaternion or 3x3 matrix, and apply incremental rotations as needed to make the ball appear to 'roll' in a realistic manner.

To update the ball's orientation (you'll only want to do this when the speed of the ball is above some threshold value):

1. Compute the axis of rotation as the normalized cross product of the world 'up' axis and the ball's velocity vector.

2. Compute the angle of rotation from the speed of the ball and the ball's circumference.

3. Apply this axis-angle rotation to the orientation quaternion or 3x3 matrix.

4. Normalize/orthogonalize the quaternion/matrix to prevent numerical drift.
Thanks guys, I have a feeling I have a lot of reading to do. It would seem I tried to skip past the hard part (understanding the concepts involved) and go straight to implementation in code, as I don't even know what a quaternion is or how one is used.

I'll check out that link you suggested, seems like a good source with lots of examples in code.
codeXtremeif(you->intelligence < radish->intelligence) you->STFU();

This topic is closed to new replies.

Advertisement