This project has moved and is read-only. For the latest updates, please go here.

Constant Rotation

Nov 21, 2007 at 11:35 PM

I apologise for what is probably a total dumb question...

I have a rectangular body which has a local force applied on each side (simulating tank movement) so slight rotation is achieved by applying a force to only one side and more by applying a negative force to the other side at the same time (i never explicitly apply torque)... this works well and initial movement is as expected, however, once all user input has ceased, the body comes to a stop pretty quickly but continues to rotate for a while afterwards...

i have tried setting the RotationalDragCoefficient to a number of values ranging from 10000 down to 0 but each one results in pretty much the same effect.

Below is the section of code which provides forward movement with a small rotation

if (Keyboard.GetState().IsKeyDown(Keys.Up))

Matrix bodyMat = body.GetBodyRotationMatrix();

Vector2 thrust1 = new Vector2(0, -200) * thrustMag;
Vector2 thrust2 = new Vector2(0, -180) * thrustMag;

thrust1 = Vector2.Transform(thrust1, bodyMat);
thrust2 = Vector2.Transform(thrust2, bodyMat);

body.ApplyForceAtLocalPoint(thrust1, new Vector2(-40, 0));
body.ApplyForceAtLocalPoint(thrust2, new Vector2(40, 0));


I hope this makes sense, i am probably doing something totally wrong, but i've been working with this for a while now and its starting to bug me


Nov 22, 2007 at 12:23 AM
I've managed to resolve my issue by setting the AngularVelocity to 0f on each update...

Am i using the engine correctly?... i kinda got the feeling that the AngularVelocity was really only meant to be read only and set by the engine itself

Anyway, i would appreciate if someone could still let me know the best way of acheiving my goal

Nov 22, 2007 at 2:00 AM
Edited Nov 22, 2007 at 4:21 AM
I tried your code, and yes, it looks odd. The RotationalDragCoefficient seems to be virtually negligible until it's >100. Even then, the rotational velocity doesn't really diminish to 0, as you'd like, but slowly drops.

As to your setting AngularVelocity to 0 every update, I'd recommend you instead multiply it by .95f or something like that (only when the Up key isn't pressed). Then it will gradually slow to a stop, but not too gradually. It would be nice not to have to manually control the behavior of the object, though.

To crashlander:
This is code from Body.IntegrateVelocity(dt):
dw = torque * inverseMomentOfInertia * dt;
previousAngularVelocity = angularVelocity;
angularVelocity = previousAngularVelocity += dw;
What does the last line do?

Also, the inverseMomentOfInertia for a default Mass=1 Rectangular Body is 0.0004166667. When multiplied by the torque (which has been scaled by the RotationalDragCoefficient, this alters the new AngularVelocity hardly at all. Is this intended?
Nov 22, 2007 at 5:29 AM
I should be able to answer these questions.

That last line is applying a velocity delta (the product of torque, 'MOI, and time delta) to the previous angular velocity, and then he's... copying... oh. Hmm. Yeah... Is that '+=' intended to be there, crashlander?

Anyway, about that MOI. Do a test and look at the values. I did my test, but it was in a game with a number of other outside forces.

My body's inverse MOI is 0.0000534521132. Torque being -1466.35889. The body I tested is jointed to a few other considerably massy bodies, which probably bumps up the torque quite a bit above normal. The game is set to run at 200 updates per second, and the simulation is given the number of milliseconds * 0.0075. The time delta in my test is 0.0374999978.

The product of these three values (dw) is -0.00293924916, which is -0.168406561 in degrees.

Result? My body's rotation decreased by about 1.7 degrees in 1/200th of a second. Now these were extreme circumstances, and that torque was much higher due to outside force, but this demonstrates how the numbers can add up.

I don't have time to make more controlled tests at the moment unfortunately. About how much torque do you get on a free-spinning body with X rotational drag coeffecient?
Nov 22, 2007 at 10:43 AM
Something seems amiss! :-) I don't think that should be +=

There was another post on this forum that was seeing strange behavior when applying turning torques. Most likely that is related to this. I'll see what I can find out.
Nov 22, 2007 at 1:23 PM
Thanks for the reply michael, i had already tried manually decreasing the AngularVelocity in each update, but to be honest, setting it to zero actually give quite a nice "tank" feel...

I seem to be having another problem now though, i am using each thumbstick to control the thrust for each track of the tank, which again works well, however, when thrust is only applied to one side the tank does drive in a circle, but it seems to be a "rounded square" (if that makes sense) i had found another post on the forum with someone having the same problem, but their solution didn't seem to fix the issue.

This is the code i am using for applying thrust... and it works, but im not sure that im transforming the force vectors correctly as the direction the body travells in is not exactly the direction its facing, it is more noticable when the rotation is at about 22 deg, 67deg, 112 deg, etc

float thrustMagnitude1 = 0f;
float thrustMagnitude2 = 0f;

if (Math.Abs(GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y) > 0)
thrustMagnitude1 += Math.Abs(GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y) * 2000;

if (Math.Abs(GamePad.GetState(PlayerIndex.One).ThumbSticks.Right.Y) > 0)
thrustMagnitude2 += Math.Abs(GamePad.GetState(PlayerIndex.One).ThumbSticks.Right.Y) * 2000;

Matrix bodyMat = body.GetBodyRotationMatrix();

Vector2 thrust1 = new Vector2(0, -GamePad.GetState(PlayerIndex.One).ThumbSticks.Left.Y * thrustMagnitude1);
Vector2 thrust2 = new Vector2(0, -GamePad.GetState(PlayerIndex.One).ThumbSticks.Right.Y * thrustMagnitude2);

thrust1 = Vector2.Transform(thrust1, bodyMat);
thrust2 = Vector2.Transform(thrust2, bodyMat);

body.ApplyForceAtLocalPoint(thrust1, new Vector2(-20, 0));
body.ApplyForceAtLocalPoint(thrust2, new Vector2(20, 0));

I really appreciate the time you guys have dedicated to this, thanks

btw... i haven't mentioned, i think this engine is absolutly incredible, i've been watching its progress for a while and had a little dabble a few times, but now i've decided to give it a real stab!

Thanks again guys,