This project has moved. For the latest updates, please go here.

Apply force at a specific position on the body

Topics: Developer Forum, User Forum
Feb 3, 2012 at 10:00 AM
Edited Feb 3, 2012 at 10:00 AM


Look at this screenshot here.
It's a spaceship that's made of lots of different parts.
Every time a part gets created i create a rectangle for the part and add it to the list of vertices on the ship to finally use BodyFactory.CreateCompoundPolygon to recreate the body of the ship.

To add thrusters to the ship i loop through every part of the ship every time a parts gets added and create a body without fixture per thruster part and create a Weld Joint to add it the the ship.

The problem is when i want to fire lets say fire the left thruster, the ship just goes up as if the force is added to the center of the ships body, it doesn't rotate the ship.

I'd like to be able to basically 'push' the ship from the position (and rotation) of the thruster into a direction.

I'm using the following code in the thruster class to apply the force:

this.powerVector.X = -0f;
this.powerVector.Y = -this.Power;
Feb 3, 2012 at 3:43 PM

There is an overload for ApplyForce that takes a point at which to apply the force.

 public void ApplyForce(ref Vector2 force, ref Vector2 point)

If the thruster rotates as well, though, you should take that into account when you calculate your power vector.

Feb 3, 2012 at 6:05 PM

Thanks, can't believe i didn't see that overload.
Got it to work, somewhat.
I can't get the rotation to work with this.

How do i get the TextureRotation to work for the power vector?

Here is the code that fires the engine:

this.powerVector.Y = -this.Power;
Vector2 direction = this.Ship.Body.Position + this.RelativePosition;
direction = direction.Rotate(this.Ship.Body.Position, this.Ship.Body.Rotation + this.TextureRotation);
this.Ship.Body.ApplyForce(this.Ship.Body.GetWorldVector(this.powerVector), direction);

And here the Rotate method I'm using:

public static Vector2 Rotate(this Vector2 v, Vector2 origin, float angle)
    Vector2 rotated = new Vector2();
    rotated.X = origin.X + (float)Math.Cos(angle) * (v.X - origin.X) - (float)Math.Sin(angle) * (v.Y - origin.Y);
    rotated.Y = origin.Y + (float)Math.Sin(angle) * (v.X - origin.X) + (float)Math.Cos(angle) * (v.Y - origin.Y);
    return rotated;
Feb 5, 2012 at 12:19 PM

Well, i just made a little tool to understand math better because I'm a complete disaster with it. :p

Got it all to work now, and it works great!

Vector2 position = this.Position;
position = position.Rotate(this.Ship.Body.Position, this.Ship.Body.Rotation);
Vector2 powerVector = this.Position + (Vector2.UnitY * -this.Power);
powerVector = powerVector.Rotate(this.Position, this.Ship.Body.Rotation + this.TextureRotation);
this.Ship.Body.ApplyForce(this.Position - powerVector, position);