Issue with Offset Center of Mass for Equilateral Triangle Shape

Topics: User Forum
Jul 20, 2012 at 8:31 PM

Could someone please advise me where would be the best offset location for Center of Mass for an equilateral triangle shape.

I have offset the Center Of Mass (COM) to the 'base center' as well as to 'top tip' of the triangle but when I apply force it just spins like a top.


//Code to create/setup Triangle Body
float w = ConvertUnits.ToSimUnits(width);
float h = ConvertUnits.ToSimUnits(height);
//create triangle
Vertices verts = new Vertices();
verts.Add(new Vector2(w / 2, 0f));
verts.Add(new Vector2(w, h));
verts.Add(new Vector2(0f, h));

agent = BodyFactory.CreatePolygon(world, verts, density);
agent.BodyType = BodyType.Dynamic;
agent.Position = new Vector2(w, h);
//OFFSET center of mass.....
//agent.LocalCenter = new Vector2(w / 2, 0f); //top center agent.LocalCenter = new Vector2(w / 2, h); //bottom center //In the Update method, based on UP/DOWN key press tilt = 5f * (float)Math.PI / 180; force = 5f;
//update direction to point same direction as rotation

dir = new Vector2((float)Math.Cos(agent.Rotation), (float)Math.Sin(agent.Rotation)); force = 2f; //on key down
//force = -2f; //on key up
agent.ApplyForce(dir * force); //should just move the direction the shape is facing, but instead just spins


Jul 20, 2012 at 9:17 PM
Edited Jul 20, 2012 at 9:18 PM

Try passing the new center of mass as a point at which to apply the force:

Vector2 forceVector=dir*force;

ApplyForce(ref forceVector, ref agent.WorldCenter)

Jul 21, 2012 at 6:04 AM

Thanks jerrysb, that overloaded method helped. Earlier, I set the agent.LocalCenter = agent.Position. That should have worked too, in theory the rotation was being applied at the center position of the shape.

Something else I had to do was apply linear & angular damping to slow movement and rotation, so player character was more easily controllable using the WASD keys.

Jul 21, 2012 at 8:50 AM

I think this might be a bug or at least the description of ApplyForce is wrong. In Box2D there is ApplyForce at a point which calculates the torque too and ApplyForceToCenter which doesn't. In Body.cs ApplyForce(Vector2 force) applies it to the Position which is the world transform of the local orgin which in turn is not necessarily the center of mass. Agent.LocalCenter=agent.Position should work too, doesn't it?

Jul 21, 2012 at 6:50 PM

Agent.LocalCenter=agent.Position, puts the center way off the screen. I had a 800 x 600 screen size. Could be a bug, but setting the LocalCenter to <0f, textureheight/2> put it in the bottom center of the triangle. The overloaded ApplyForce(dir * force * gameTime, Agent.WorldCenter) worked.

Jul 21, 2012 at 7:15 PM
Edited Jul 21, 2012 at 7:26 PM

Actually LocalCenter should be in the local frame of reference so setting it to Position (which is in the world frame) is no good. The thing is Position is always at (0,0) in the local frame (it's the origin) so no use for changing the center of mass.

I'll write up a request for clarification in the issue tracker on the ApplyForce issue  so perhaps someone will look at it for the next version.