physics.body missing applyLinearImpulse() and applyAngularImpulse()

@Simeon Is it likely that we could get these in the next release?

Sorry to necro this post, but it’d be great if these could be added.

Is this the reactionary force?

@JakAttak Doesn’t body:applyForce() do the same thing. If I’m not mistaken, LinearImpulse is a force applied to the body for an instant and applyForce seems to do the same thing. Or am I looking at this wrong.

@dave1707 just looked it up, ApplyForce is different to ApplyImpulse. And quite rightly is very needed.

ApplyForce applies a force over a multiple timestep dt, so the force becomes velocity*dt.

ApplyImpulse applies an impulse force over no timestep and this is just velocity because the impulse only accounts for one timestep.

This may fix certain bugs with Codea and Box2D which I pointed out to Simeon recently which makes Box2D apply a lot of force to an object when moving the output box (console) or using multi-gestures to get to the homepage. This is because body:applyForce accounts for dt, as it should. I don’t however believe this will fix the whole problem with Box2D and Codea but thats another discussion.

@Luatee I was using this program to see what applyForce did. I used a count to limit the amount of print statements. When this is run, draw cycles (count) 11 thru 15 shows a linearVelocity of 0 in the x direction. When count reaches 15, I execute appleForce with a value in the +x direction. Draw cycle (count) 16 shows an instantaneous velocity increase and that velocity remains the same thru draw cycle 20, or more if I let it print. From what I see, that appears to be the definition of ApplyImpulse, an instantaneous speed increase that then remains the same afterwards. Or am I all wrong.


function setup()
    count=0
    b1=physics.body(CIRCLE,40)
    b1.position=vec2(WIDTH/2,HEIGHT/2)
    b1.gravityScale=0
end

function draw()
    count=count+1
    background(40, 40, 50)
    fill(255)
    ellipse(b1.x,b1.y,80)
    if count>10 and count<21 then
        print("draw cycle ",count,"\
",b1.linearVelocity)
    end
    if count==15 then
        b1:applyForce(vec2(200,0))
        print("applyForce")
    end    
end

@dave1707 If your fps is 60 then you won’t notice the difference between applyForce and applyImpulse (theoretically if your timestep is 1 this should be the case). If your fps is less than 60 then you will notice the difference. I wrote this simple example to demonstrate:

-- Bug

-- Use this function to perform your initial setup
function setup()
    circ = physics.body(CIRCLE,25)
    circ.position = vec2(WIDTH/2,HEIGHT/2)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)
    circ:applyForce((vec2(WIDTH/2,HEIGHT/2)-circ.position)*5-circ.linearVelocity/10)
    -- Do your drawing here
    fill(255)
    ellipse(circ.x,circ.y,50)
end

To show the effects go in to the output console and just drag the output list up and down. Box2D will freeze, when it unfreezes you’ll see all those timesteps missed bunched in to one applyForce which is overly powerful. When you want a stable character made out of physics bodies you need to avoid this.

@dave1707, applyForce and applyLinearImpulse are different and have different uses as @Luatee pointed out.

@Luatee I couldn’t see any difference dragging the output screen. I added your code to a program I have where I could cut the FPS down to 4 fps. Your code ran a little jerky, but I didn’t notice any freezing or big jumps in the movement of the circle. @JakAttak I guess I dont understand the difference between what appleForce and applyLinearImpulse is supposed to do. I’ll see if I can find a definition of them on Google.

Here’s what I found for the definition of ApplyForce and ApplyImpulse. ApplyForce acts over time to change an objects velocity. ApplyImpulse changes the object velocity instantaneously. Another definition was ApplyForce changes the objects velocity, but ApplyImpulse can also cause an object to rotate if it isn’t applied to the center of the object.

@dave1707 applyForce can also cause an object to rotate using the second parameter.
It’s the single step impulse that’s important for stabilising certain mechanics in my game as any frame skip causes an overloaded force due to ApplyForce acting over a time, hopefully this is added in the next update.

@dave1707, there’s a quick explanation of the difference here: http://www.box2d.org/forum/viewtopic.php?f=3&t=5487

It’s a small distinction, but an important one.

@dave1707 Try running this version of the code and tapping the screen, the effect is very noticeable. (Wait for it to slow down, then tap once)

-- Bug

-- Use this function to perform your initial setup
function setup()
    circ = physics.body(CIRCLE,25)
    circ.position = vec2(WIDTH/2,HEIGHT/2)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)
    circ:applyForce((vec2(WIDTH/2,HEIGHT/2)-circ.position)*5-circ.linearVelocity/10)
    -- Do your drawing here
    fill(255)
    ellipse(circ.x,circ.y,50)
end

function touched(touch)
    if touch.state == BEGAN then
        for i = 1, 500 do
            print(i)
        end
    end
end

@SkyTheCoder That code makes the problem noticeable, especially on the iPad 1.

These will be added in 2.2