rotating object when falling

Topics: Developer Forum
Dec 28, 2012 at 7:31 AM
Edited Dec 28, 2012 at 7:35 AM

Hi all,

 I'm having fun learning about farseer (yeah im a newb at this still), but I am a little stuck.

I have a rectangle body that is being fired from a canon at a 45degree angle. the body is also rotated up at a 45 degree angle and I have set the mass to be at the front of the body. 

the body goes up in the air fine however as the body comes back down to earth it does not rotate. Is there a way so that the mass side comes down first.

my real world example is, throwing a tennis ball with a string attached into the air. currently the string doesn't fall behind the ball when gravity comes into affect.

Here is my 'ball'

           Body = BodyFactory.CreateRectangle(world, ConvertUnits.ToSimUnits(texture.Width), ConvertUnits.ToSimUnits(texture.Height),100f, postition, this);
            Body.Mass = 1;
            Body.LocalCenter = new Vector2(ConvertUnits.ToSimUnits(Texture.Width), ConvertUnits.ToSimUnits(Texture.Height / 2));
            Body.UserData = this;
            Body.BodyType = BodyType.Dynamic;
            Body.CollisionCategories = Category.All;
            Body.CollidesWith = Category.All;
            Body.IgnoreGravity = false;
            float ang = BarrelJoint.JointAngle;
            Body.Rotation = ang;
 
Then I do this to fire it:
Body.ApplyLinearImpulse(new Vector2((float)Math.Cos(ang) * 100, (float)Math.Sin(ang) * 100));

 I am guessing there is some setting or calculation I am forgetting.
Dec 29, 2012 at 12:19 PM

Are you sure you are not forgetting some...physics? :)

Joking aside gravity will not produce torque because by definition it acts at the center of gravity so the moment arm is 0 (T=r x F). Changing the center of gravity is of no help. If you are aiming at a rotation effect (which is unphysical btw) instead of moving the local center you should apply a force at some point away from it yourself using the ApplyForce/ApplyImpulse overload that accepts a point on the body for the application. In that sense gravity is no special force - it's just a downward force equal to mg applied automatically by the engine at every step. You can switch global gravity off and apply your own with no problem.

As for your second real world example the string attached to the ball lags behind not because of gravity or mass (as we know from Galileo) but because of air resistance. This is somewhat more difficult to simulate correctly. For a game perhaps cheating a bit by applying forces where necessary will be easier than actually implementing air drag and lift.

Jan 2, 2013 at 8:05 AM

Cheers for the reply, I ended up adding Angular impulse. I am going to have to spend a bit of time tweaking it to get it right for all power levels.

 

Jan 3, 2013 at 10:33 AM

For anyone who will read this in the future, I did work it out.

I realized that the velocity would be changing in a similar fashion as I wanted the rotation to change. So I based the rotation on the velocity, the more gravity pulls down the more the object will turn to face down.

In my objects update class, I put the following (note: potentially bad maths):

 

public override void Update(GameTime gameTime)
    {
        Vector2 velocity = Body.LinearVelocity;

        float radians = (float)(Math.Atan2(-velocity.X, velocity.Y) + Math.PI/2.0);

        Body.Rotation = radians;

        base.Update(gameTime);
    }

And ta da we have a rotating object.