I'm trying to simulate a sphere rolling on a floor. For the simulation I'm using the good-old Papervision3D library of Flash AS3, but it actually doesn't matter, this is a pure geometry question.
Assuming that I have a Sphere3D object to which I can set the rotationX, rotationY and rotationZ properties, How can I calculate the rotation in every axis where this sphere is rolling on the floor?
For instance, Let's assume the sphere is in rest. Now it rolls 1 meter to the right. If I'm looking at this sphere from the top - I'll want to rotate it around the Z axis, 90 degrees. Then the sphere should roll "downwards" along the floor, so I'll want to rotate it around the X axis, but this problem is that in the meantime the X axis rotated itself when I rotated the sphere along the Z axis.
How can I solve this issue?
Thanks
If there is no sliding then:
rotation axis
will be parallel to your floor and perpendicular to your movement. So you can exploit cross product to get it. Let:
n
- floor normal vectort
- movement direction parallel with floor (tangent)b
- our rotation axis (binormal)so we can compute it as:
rotation speed
this can be derived from arclength and speed
vel [unit/s]
. So if our sphere is of radiusr
then:so we need to rotate our sphere by
omg
each second.rotation math
Euler angles (your sequenced rotations X,Y,Z) are the worst thing for this I can think of as they will lead to singularities and weird stuff making this simple example horrible nightmare to implement. have you seen in a game or any 3D engine that suddenly you can not look as you expect, or randomly spin until you move/rotate differently or suddenly rotate by 180deg ... ? That are Euler angles singularities at work without proper handling...
Quaternions are somewhat alien to most people (me included) as they do not work like we think. IIRC You can look at them as efficient way of computing 3x3 3D rotation matrix with less goniometric functions needed. As we now have much different computational power than 20 years ago theres not much point choosing them if you do not know them at all. Anyway they have also another advantages which are still relevant like you can interpolate between rotations etc.
4x4 homogenuous transform matrices are your best choice. As their geometric representation is compatible with human abstract thinking (you can imagine what and how it is done hence you can construct your own matrices instead of having them as bunch of meaningless numbers).
I strongly recommend to start with 3D 4x4 homogenuous transform matrices. So all the rest of this answer will be aimed to them.
rotating
Now There are 2 ways I know of how to achieve your rotation. Either use Rodrigues_rotation_formula and encode it as transform matrix or simply construct your own rotation matrix that will represent your sphere aligned to floor. direction of movement and rotation axis.
The latter is much much simpler and we can do it directly as we already know the 3 basis vectors needed (
t,b,n
). What is left is only the sphere position which should be also known.So at start create a transform matrix (assuming OpenGL notation):
Where
x0,y0,z0
is start position of your sphere aligned with your mesh. So if center point of your mesh is(0,0,0)
then place your spherer
above the floor...Now just each elapsed time
dt [sec]
(like timer) multiply this matrix by incremental rotation matrix aroundy
axis (asb
is our rotation axis) and angleomg*dt [rad]
.We also need to translate our sphere by
t*vel*dt
so simply add this vector to matrix position or multiply our matrix with:And also render the scene again using our resulting matrix... This approach is nice as you can anytime change the direction of movement (you just remember the position and change the inner 3x3 rotation part of the matrix with new
t,b,n
vectors.However there is one disadvantage that such cumulative matrix will degrade the accuracy over time (as we are performing multiplication by floating numbers over and over on it without reset) so the matrix can deform over time. To avoid this is enough to recompute and set the
t,b,n
part of the matrix from time to time. I am used to do it each 128 rotations on 64bitdouble
variables precision. It can be done also automatically (when you have no prior info about the axises) I am doing like this:Also using matrices have different notations (row/column major order, multiplication order) which can affect the equations a bit (either reverse order of multiplication and/or using inverse matrices instead).
Now in case your 3D engine does not support matrices (which is highly unlikely) you would need to convert our resulting matrix back into Euler angles. That is doable by goniometrics but for that you would need to know the order of the angles.
In case of Sliding you need to go in reverse order. So first compute the rotations and then compute the direction of translation from the grip forces with floor and inertia. Which is a bit more complex and pure physics ...
[Edit1] rotundus style simple OpenGL/C++/VCL example
Here simple control example using cumulative matrix (without the accuracy preservation):
Its an empty single form VCL app with single 20ms timer on it. In order to port to your environment just ignore the VCL stuff, mimic the relevant events of the app and port rendering to your components/style/api. The only important stuff is just the
sphere
class marked as// movement
and the timer eventTimer1Timer(TObject *Sender)
. All the rest is just rendering and keyboard handling ... Which I susspect you already got handled on your own ...The preview shows movement while I control the ball with arrows:
Here texture I used (drawed in mspaint by hand so it might not be pixel perfect symmetrical...)
The
gl_simple.h
of mine can be found in here: