News Apr 7: On-screen logging class for Cocos2d-x
Mar 22: Downhill Supreme 2 released for iOS and Android
Jan 2: YouTube video: Making soft-body wheels in RUBE
2013
Oct 6: Check out Supplyfront RTS, my 7dRTS entry continued.
Sep 26: R.U.B.E v1.5 released. Customizable item labels, snap-to-grid, export filtering, full-text help search.
Sep 18: Added RUBE sample loader for Cocos2d-X.
Sep 16: Updated RUBE sample loader for Cocos2d v2.
Aug 12: RUBE loader for Nape by Zeh Fernando
Aug 7: Added RUBE sample loader for SFML.
Jul 30: Try my MiniLD 7dRTS entry.
Jul 24: Added physics-driven particles tutorial.
Jul 20: New blog post: rendering solid ground (as in Downhill Supreme)
Jul 18: R.U.B.E v1.4 released. Command-line interface for batch jobs, hotkeys for scripts, better script management.
May 22: Downhill Supreme is out now! (iOS)
Apr 2: R.U.B.E v1.3 released. Collision bitplane editing, Cocos2d-iphone loader, usability improvements.
Mar 11: R.U.B.E v1.2 released. Now supports weld, friction, motor joints and automatic image reloading.
Mar 10: RUBE loader for libGDX by Tim Scott
Jan 28: New blog post: a functional combustion engine!
Jan 22: New blog post: wind tunnel
Jan 20: Added explosions tutorial.
Jan 16: Added buoyancy tutorial.
Jan 16: AndEngine sample project to load RUBE scene by Bart Hirst
Jan 14: R.U.B.E v1.1 released, now supports custom properties.
Jan 1: All basic tutorials are now available in Chinese at ohcoder.com Huge thankyou to @OhCoder!
2012
Dec 23: Discussion forums have been set up
Dec 4: R.U.B.E v1.0 is ready !
Dec 2: YouTube video: Box2D pendulum clock
Nov 26: New blog post: rocket platform thingy
Nov 25: Video of R.U.B.E scenes in Chipmunk.
Nov 23: A sample project to load R.U.B.E scenes into Chipmunk physics! Details here.
Nov 14: An XCode sample project to load R.U.B.E scenes on iOS is now available. Details here.
Nov 11: A Java version of b2dJson is now available, based on JBox2D.
Nov 6: A Javascript version of b2dJson based on box2dweb is now available. Demo here!
Nov 2: The full specification of the JSON format used by b2dJson can be found here: b2dJson file structure
Oct 28: YouTube video: 2-minute ragdoll in R.U.B.E Box2D editor
Sep 29: YouTube video: R.U.B.E Box2D editor usage example

Box2D C++ tutorials - Forces and impulses

Last edited: July 14 2013

Chinese version -> 中文

Forces and impulses


To move things around, you'll need to apply forces or impulses to a body. Forces act gradually over time to change the velocity of a body while impulses can change a body's velocity immediately. As an example, imagine you have a broken down car and you want to move it. You could use a force by slowly driving another car up next to it until their bumpers touched and then push it, causing it to accelerate over time. Or you could use an impulse by driving the other car into it at full speed. Both methods have their place depending on what you are trying to simulate.

You can also 'warp' a body instantaneously by simply setting its location. This can be handy for games where you need a teleport feature, but bear in mind that this is not realistic physics! The whole point of a physics simulator like Box2D is to make things look real, and to this end I would recommend using forces and impulses to move bodies as much as you can. Sometimes it might seem tricky to think of a way to do this, but in the real world everything happens via forces or impulses, so unless you are creating a feature which is obviously not real-world (teleport etc), keep thinking. It may end up giving you less problems down the line.

Angular movement can also be controlled by forces and impulses, with the same gradual/immediate characteristics as their linear versions. Angular force is called torque. Think of this as a twisting strength, like when you twist the cap off a bottle - the bottle doesn't go anywhere, but you are still applying a force (torque) to it.

In this topic, we'll make three bodies and try using each one of the above-mentioned methods to move and twist them. Let's set up a scene similar to the one in the fixtures topic, but with all the shapes the same.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  //class member variable to keep track of three bodies
  b2Body* bodies[3];
  
  FooTest() {
    //body definition
    b2BodyDef myBodyDef;
    myBodyDef.type = b2_dynamicBody;
    
    //shape definition
    b2PolygonShape polygonShape;
    polygonShape.SetAsBox(1, 1); //a 2x2 rectangle
  
    //fixture definition
    b2FixtureDef myFixtureDef;
    myFixtureDef.shape = &polygonShape;
    myFixtureDef.density = 1;
    
    //create identical bodies in different positions
    for (int i = 0; i < 3; i++) {
      myBodyDef.position.Set(-10+i*10, 20);
      bodies[i] = m_world->CreateBody(&myBodyDef);
      bodies[i]->CreateFixture(&myFixtureDef);
    }
    
    //a static floor to drop things on
    myBodyDef.type = b2_staticBody;
    myBodyDef.position.Set(0, 0);
    polygonShape.SetAsEdge( b2Vec2(-15,0), b2Vec2(15,0) );
    m_world->CreateBody(&myBodyDef)->CreateFixture(&myFixtureDef);
  }
Forces

Linear movement


We need some way of affecting these bodies without using the mouse. Now would be a good time to check out the keyboard input feature of the testbed. Override the Keyboard function of the Test class to use a different method for each body:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  void Keyboard(unsigned char key)
  {
    switch (key)
    {
      case 'q':
        //apply gradual force upwards
        bodies[0]->ApplyForce( b2Vec2(0,50), bodies[0]->GetWorldCenter() );
        break;
      case 'w':
        //apply immediate force upwards
        bodies[1]->ApplyLinearImpulse( b2Vec2(0,50), bodies[1]->GetWorldCenter() );
        break;
      case 'e':
        //teleport or 'warp' to new location
        bodies[2]->SetTransform( b2Vec2(10,20), 0 );
        break;
      default:
        //run default behaviour
        Test::Keyboard(key);
    }
  }
The SetTransform function we covered in the bodies topic. The ApplyForce and ApplyLinearImpulse functions take two parameters, the first is what direction the force should be, in this case straight up. The second parameter is what point on the body should be pushed on - we'll get to this soon.

Run the test and try pressing the q/w/e keys. The impulsed body should react as if it was suddenly hit by something. The teleported body moves instantly to the new location, but notice that it retains its linear and angular velocity. What's happening with the body we applied the force to? Well, this Keyboard function is only called when we press the key down, not every timestep. In the example of car-pushing analogy, this would be like pushing the car for a fraction of a second, and then stopping. Since a force works over time, what we really need is some way to turn the force on and off instead of just blipping it on for a brief moment. We could use a class member variable to keep track of whether the force is on, and use the q key to toggle it. Make the following changes to the class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  //class member variable
  bool forceOn;
  
  //inside constructor
  forceOn = false;
  
  //modified case for q key in Keyboard() function
    case 'q':
      forceOn = !forceOn;//toggle bool value
      break;
  
  //inside Step() function
      if (forceOn)
        bodies[0]->ApplyForce( b2Vec2(0,50), bodies[0]->GetWorldCenter() );
Now the q key should turn the force on and off, and you can see the gradual effect of a force.

Hmm.... we applied the same magnitude (50) for both impulse and force, so why does the force seem to be weaker than the impulse? Well, remember that gravity is a force too. Try turning gravity off and the answer might become clear. The reason is that the force acts a little bit each timestep to move the body up, and then gravity acts to push it back down again, in a continual up down up down struggle. The impulse on the other hand, does all its work before gravity gets a chance to interfere. With gravity off, try turning the force on for about one second, then off. You will notice that after one second, the forced body has the same velocity as the impulsed body.

Now what about the last parameter of the apply force/impulse functions that we have ignored? So far we set this using the GetWorldCenter() of the body which will apply the force at the center of mass. As we can see, a force applied to the center of mass does not affect the rotation of the body. Imagine a CD on a friction-less flat surface, like an air-hockey table. If you put your finger in the hole in the middle of the CD and flick it across the table, it will not spin around as it moves. But if you do this with your finger anywhere else on the CD, it will spin around as it moves, and the further away from the middle your finger was, the more it will spin.

Let's offset the point at which we apply the force/impulse. Change the ApplyForce and ApplyLinearImpulse calls so that instead of using GetWorldCenter() to apply force at the center of mass, we'll apply it at the top right corner of the box:
1
2
3
4
5
  //before
  GetWorldCenter()
  
  //after
  GetWorldPoint( b2Vec2(1,1) )
Forces This time, you should see these boxes rotate when acted upon. The function GetWorldPoint is used to convert a location relative to the body (body coordinates) into world coordinates, so that we keep applying the force at the corner of the box even after it has rotated around. Note that while the picture above shows a scenario which might be interpreted as 'picking the box up by its corner', the force being applied has nothing to do with the visible rectangle fixure - forces and impulses are applied to bodies, not their fixtures. The force could just as easily be applied at any old point, even in empty space where the body has no fixures.

Angular movement


Angular movement is controllable by using angular forces (torque) and angular impulses. These behave similar to their linear counterparts in that force is gradual and impulse is immediate. Let's add a couple of cases to the Keyboard() function to try them out. (Although there is a third case where the rotation can be set instanteously, we have already done that with SetTransform() above, so we'll skip that here.)
1
2
3
4
5
6
7
8
      case 'a':
        //apply gradual torque counter clockwise
        bodies[0]->ApplyTorque( 20 );
        break;
      case 's':
        //apply immediate spin counter clockwise
        bodies[1]->ApplyAngularImpulse( 20 );
        break;
Now use the a/s keys to see what happens. Once again you will see that to make the torque effective, you will need to add a class member variable to toggle the torque on/off so it can be applied constantly every time step:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  //class member variable
  bool torqueOn;
  
  //inside constructor
  torqueOn = false;
  
  //modified case for a key in Keyboard() function
    case 'a':
      torqueOn = !torqueOn;//toggle bool value
      break;
  
  //inside Step() function
      if (torqueOn)
        bodies[0]->ApplyTorque( 20 );
With gravity on, you'll see that even though we are only trying to 'twist' these boxes they still move around a bit, but that's only because they collide with the ground and act like square wheels. For a better illustration of what torque and angular impulse are doing, turn gravity off. In a zero-gravity scene, now we can see why only one parameter is necessary for angular force/impulse functions - since no linear movement is caused, the only thing we need to specify is which way the rotation should be. Unlike linear forces above there is never any offset possible because the rotation is always about the body's center of mass.

As with the linear forces, given the same magnitude parameter, ApplyTorque will take one second to gain as much rotational velocity as ApplyAngularImpulse does immediately.