Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Anguler Kinetics

Started by evenfurtherdownunder Jan 8, 2005 at 6:48 PM 3 replies 700+ views
Original Post
evenfurtherdownunder
evenfurtherdownunder
Hi, I am trying to do some angular kinetics but am having some problems. I am setting a value for angular velocity as 1.0f, there is no forces on the object so theretically it should continully spin around and around. Here is the step that i am using //global CTorque M; //moment acting on the mass CInertia I; //inertia acting on the mass CQuaternion qOrientation; //rotation of the object represented as a quaternion CVector3 angularVelocity; //velocity in rotation //local float mag; //step angularVelocity += I.inverseInertiaTensor * ( M.torque - math->Cross( angularVelocity,(I.inertiaTensor * angularVelocity))) * dt; // calculate the new rotation quaternion: qOrientation += ( qOrientation * angularVelocity ) * (0.5f * dt); // now normalize the orientation quaternion: mag = qOrientation.Magnitude(); if (mag != 0) qOrientation /= mag; If this was working right the angularVelocity should change but instead they are all over the place and quickly become infinity??? I dont know if this will help but i think the inertia tensor might be wrong... I use this method void CInertia::calculateInertiaTensor( int amountElements, CVector3 localInertia[], CVector3 pts[], CVector3* cg, float mass[] ) { int i = 0; float Ixx, Iyy, Izz, Ixy, Ixz, Iyz; Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0f; CVector3 *cgPosition; cgPosition = (CVector3*)malloc(amountElements*sizeof(CVector3)); //redefine each point as if the cg was the origin for( i = 0; i < amountElements; i++ ) { cgPosition.x = pts.x - cg->x; cgPosition.y = pts.y - cg->y; cgPosition.z = pts.z - cg->z; } //add up each elemnets inertia for( i = 0; i < amountElements; i++ ) { Ixx += localInertia.x + mass * ( cgPosition.y * cgPosition.y + cgPosition.z * cgPosition.z ); Iyy += localInertia.y + mass * ( cgPosition.z * cgPosition.z + cgPosition.x * cgPosition.x ); Izz += localInertia.z + mass * ( cgPosition.x * cgPosition.x + cgPosition.y * cgPosition.y ); Ixy += mass * ( cgPosition.x * cgPosition.y ); Ixz += mass * ( cgPosition.x * cgPosition.z ); Iyz += mass * ( cgPosition.y * cgPosition.z ); } //now define the inertiatensor and inverse inertia tensor inertiaTensor.setMatrix(Ixx, -Ixy, -Ixz, -Ixy, Iyy, -Iyz, -Ixz, -Iyz, Izz ); inverseInertiaTensor = inertiaTensor.Inverse(inertiaTensor); //free up the space free(cgPosition); } I am using this formula on a simple Cube (2.0f LxDxH and 100.0f mass) and it gives me (66.66f, 66.66f, 66.66f). I calulate the local inertia of the object using CVector3 momentInertia; momentInertia.x = ( mass * ( ( depth * depth ) + ( lenght * lenght ) ) ) / 12.0f; momentInertia.y = ( mass * ( ( height * height ) + ( lenght * lenght ) ) ) / 12.0f; momentInertia.z = ( mass * ( ( depth * depth ) + ( height * height ) ) ) / 12.0f; return momentInertia; then pass that along with all the points into the method above and it creates strange numbers all over 500.0f. So does any one see any thing wrong or can they point me in the right direction to online tutorial.
grhodes_at_work
grhodes_at_work
I haven't had time to look at your post in detail, but the following appears to be quite wrong:

Quote:
Original post by evenfurtherdownunder
//step
angularVelocity += I.inverseInertiaTensor * ( M.torque - math->Cross( angularVelocity,(I.inertiaTensor * angularVelocity))) * dt;


I'd recommend keeping track of angular momentum (I.inertiaTensor * angularVelocity) explicitly. In place of the above, update angular momentum using:

L += M.torque * dt;

and at the same time update orientation as you do below:

Quote:
Original post by evenfurtherdownunder// calculate the new rotation quaternion:
qOrientation += ( qOrientation * angularVelocity ) * (0.5f * dt);


And, then, compute the new angular velocity using:

angularVelocity = I.inverseInertiaTensor * L;

Now....you also must ensure that the inertia tensor is represented in world space for all these steps. I would also guess that you're not treating your inertia tensor correctly (even if you're initially calculating it correctly). What you can do is calculate I in the object coordinates (which is what you're describing in your post, e.g., you calculate it about a set of axes that are aligned with the cube and not necessarily aligned with the world since the cube might be oriented arbitrarily with respect to the world), then when you need it convert into world space in the following way:

I.worldspaceInertiaTensor = R*I.objectspaceInertiaTensor*R_transpose;

and,

I.inverseWorldspaceInertiaTensor = R*I.inverseObjectspaceInertiaTensor*R_transpose;

where R is a 3x3 rotation matrix corresponding to qOrientation.

Then, all the equations above use the I.worldspace* and I.inverseWorldSpace* tensors instead of the object space ones...

Hope this helps, :).
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
evenfurtherdownunder
evenfurtherdownunder
Dont mind the last question i figured it out. And now i get a constant velocity. But as my quaternion starts at x-0, y-0, z-0, n-0 then the following part just keeps producing zero's

Original post by evenfurtherdownunder// calculate the new rotation quaternion:
qOrientation += ( qOrientation * angularVelocity ) * (0.5f * dt);

Is that part right or is the initilization of the quaternion being 0,0,0,0 wrong?

grhodes_at_work
grhodes_at_work
Your quaternion initialization is wrong. It must be a unit length quaternion representing the object orientation. A zero quaternion cannot do this.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.