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

Rotation and applied force in refrence frame...

Topics: Developer Forum, User Forum
Aug 26, 2009 at 1:14 PM

Last evening I downloaded and installed the Farseer Physics Engine for the first time.  I watched the demos and worked through a few tutorials.  This engine looks powerful and I'm very excited to start working with it.  I'm an experienced programmer and I've played with 2D and 3D physics from time to time, writen my own DIY 2D routines and working with the Ageia (now NVIDA) PhysX engine.  So last night when I wrote my first simple test application that yielded unexpected results, I went to bed a bit confused.  So I'm hoping to find some clarification.  My scenario is simple and straight forward.

Let's say I have a 50x50 square body and I do the following: 

body.Position = new Vector2(100.0f, 100.0f);
body.Rotation = 0.0f;
body.ApplyForceAtLocalPoint(new Vector2(100.0f, 0.0f), Vector2.Zero);

This code resulted in the behavior I expected, the body accelerated towards the right side of the screen.  Then I rotated the body 90 degrees CCW and applied the same force.

body.Position = new Vector2(100.0f, 100.0f);
body.Rotation = MathHelper.ToRadians(-90.0f);
body.ApplyForceAtLocalPoint(new Vector2(100.0f, 0.0f), Vector2.Zero);

To my surprise, rather than the object moving towards the top of the screen, the body moved to the right side exactly as the code above.  I was surprised by this because I assumed that AtLocalPoint meant "in local body reference frame/coordinate system", so a force applied a positive X-Axis force applied to a body turned on its left side, would result in a force pushing upwards -- forces applied within the reference frame of the Body.

Obviously, the function was not intended to apply a force within the local points coordinate system, but rather in the world coordinate system.  I'm not sure I'm describing this very well.

The short story is... I want to put a body on the screen that I can rotate.  When I apply a force (like thrust), I want that body to be thrusted in the direction the body is "pointed".  Finally... I tried this...

xmag = mag * cos(body.Rotation);

ymag = mag * sin(body.Rotation);
body.ApplyForceAtLocalPoint(new Vector2(xmag, ymag), Vector2.Zero);

Which worked, but I'm concerned that the math with get more complicated when I start applying multiple forces at multiple points at multiple angles to the body.  It seems like the physics engine should have a function for applying forces within the reference frame of the body (like the PhysX engine).  Perhaps I need to right my own function to accomplish this task, but I'd hate to do that if the engine already can do it somehow.

Any thoughts or feedback on this topic would be much appreciated.

- todd

Aug 26, 2009 at 4:33 PM

Farseer Physics is a very simple 2D physics engine and we only have the very basics plus some tools. It is simply, but powerful.

This is also why the engine does not have any idea of orientation. Gravity is what makes us believe in something called up, down, left and right. Think of this engine as something in space. There is no orientation, only reference (where you are at) and direction (towards where you are going). I can understand why you expected a different result, for platform games it might give more sense to apply force (locally) the way you described, but here local simply means a point relative to the centroid of the geometry.

The engine works in world space only - this means that even if you use local points, it will still use world points. The ApplyForceAtLocalPoint() is simply there for convenience.

Your solution should work fine. You could also use the geometry matix and make a method that respects the rotated matrix. Example: Simply rotate the matrix and apply the force in the direction of the rotation.

Aug 26, 2009 at 5:19 PM

The engine appears to be very powerful and I'm especially looking forward to playing with collision detection.  What's important is that once the body is in motion in interacts with other bodies correctly, which from the demos I tried seems to be spot on.  I'm going to dig up some of my old source could to see how body-based reference frames, rotation and forces.  I think you are right, its done using matrix functions.  Thanks for getting back to me.