apply impulse applies floating point force instead of constant

Why does the applylinearimpulse apply a non integer force where box2d applies an integer force.

using the below code to create a box and apply force:

playerObj1 = display.newRect( 200,500, 50,50 )

physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0})

playerObj1:applyLinearImpulse( 0, 1, playerObj1.x, playerObj1.y )

yields a linear velocity in corona as 10.789998283386

whereas a similar applyimpulse in box2d will yield a force of 10

are there any solutions / work arounds for this??

You’re mixing terms so the question is a little hard to answer, and you haven’t given us a hint as to what you’re trying to achieve.

  • Floating Point - 1.2345, 3.567, …
  • Whole Number - 0, 1, 2, 3 (is this what you meant by constant?)
  • Constant - A variable or value that doesn’t change.

As far as applyLinearImpulse(), unless I’m mistaken, it is merely a wrapper for Box2D so whatever you’re seeing is Box2D.  Can you tell us what other SDK/Engine you were using where you saw non-floating point values?

I think there may be some confusion of expectation re: what the Physics (Box2D) functions should do:

  • applyForce() - Applies a force to an object for a single frame.  Used to accelerate objects and must be applied again every frame to continue accelerating.
  • setLinearVelocity() - Used to instantly give an object a specific velocity.
  • applyLinearImpulse() - Apply a force to a body once in a specific direction.  This is used to simulate an impact (or as they say in the docs a jolt.)  

So, what about the results you should expect with the above functions and what will affect them?

  • applyForce() and applyLinearImpulse() - The accelerations and resultant velocity of the object will be a combination of: Force _Magnitude x  1/Object_Mass x Duration.  i.e. If an force is weak, you get low resultant acceleration and then velocity.  If an object has a lot of ‘mass’ you get the same result.  Increase force or apply a force to a low mass (small or low density) object and you get high acceleration and high end speed.
  • setLinearVelocity() - This doesn’t care about an object’s mass.  It instantly sets the velocity of the object.

Finally, don’t forget about linearDamping (the physics attribute).  If an object has damping, it will start to lose velocity immediately after a force is applied and/or a velocity is set.

Hope this helps.

One more thing, I may be guessing wrongly here, but are you expecting the same result for these two scenarios?

-- 50 x 50 rectangle w/ impulse of \< 0, 1 \> playerObj1 = display.newRect( 200,500, 50,50 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0, 1, playerObj1.x, playerObj1.y )

 and

-- 25 x 25 rectangle w/ impulse of \< 0, 1 \> playerObj1 = display.newRect( 200,500, 25,25 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0, 1, playerObj1.x, playerObj1.y )

The second case will generate a block moving at twice the velocity of the first case.  Impulses and forces are not ‘mass’ aware.  You have to calculate that yourself.

-Ed

PS - Some time ago I put together examples for the Corona Geek Hangout (81).  

https://www.youtube.com/watch?v=Ssno3LRoBKw

You can get them here and experiment with Physics forces and impulses:

https://github.com/roaminggamer/RG_FreeStuff/tree/master/Corona%20Geek/Hangout%2081 

hey, thanks for your response!

im using box2d web port  for node.js ‘npm box2dweb-commenjs’

what i meant by integer was non floating point number. so for example an applyimpulse on the y-axis of 5 would yield 10 with a mass of 1.0 in box2d web, whereas the same applylinearimpulse wrapper for coronasdk would yield a 11.15556788868

Hi again.  My guess is that the Box2D implementation you were using was ‘mass-aware’, thus giving you nice whole number responses to whole number inputs (1.0 as floating-point is for all purposes the same as the whole number 1).

So, you’re probably comparing apples and oranges here since Corona functions are not mass-aware.  i.e. They don’t adjust the implied force based on the target mass.  Instead, the force is exactly what you put in and the mass is calculated based on density and pixel area of the rectangular display object (or circular area for circles).

-Ed

I should have mentioned it, but you can easily make your code mass-aware:

playerObj1 = display.newRect( 200,500, 25,25 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0 \* playerObj1.mass, 1 \* playerObj1.mass, playerObj1.x, playerObj1.y )

now acts the same as this:

playerObj1 = display.newRect( 200,500, 50,50 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0 \* playerObj1.mass, 1 \* playerObj1.mass, playerObj1.x, playerObj1.y )

roaminggamer, that did the trick!! very much appreciated!

You’re mixing terms so the question is a little hard to answer, and you haven’t given us a hint as to what you’re trying to achieve.

  • Floating Point - 1.2345, 3.567, …
  • Whole Number - 0, 1, 2, 3 (is this what you meant by constant?)
  • Constant - A variable or value that doesn’t change.

As far as applyLinearImpulse(), unless I’m mistaken, it is merely a wrapper for Box2D so whatever you’re seeing is Box2D.  Can you tell us what other SDK/Engine you were using where you saw non-floating point values?

I think there may be some confusion of expectation re: what the Physics (Box2D) functions should do:

  • applyForce() - Applies a force to an object for a single frame.  Used to accelerate objects and must be applied again every frame to continue accelerating.
  • setLinearVelocity() - Used to instantly give an object a specific velocity.
  • applyLinearImpulse() - Apply a force to a body once in a specific direction.  This is used to simulate an impact (or as they say in the docs a jolt.)  

So, what about the results you should expect with the above functions and what will affect them?

  • applyForce() and applyLinearImpulse() - The accelerations and resultant velocity of the object will be a combination of: Force _Magnitude x  1/Object_Mass x Duration.  i.e. If an force is weak, you get low resultant acceleration and then velocity.  If an object has a lot of ‘mass’ you get the same result.  Increase force or apply a force to a low mass (small or low density) object and you get high acceleration and high end speed.
  • setLinearVelocity() - This doesn’t care about an object’s mass.  It instantly sets the velocity of the object.

Finally, don’t forget about linearDamping (the physics attribute).  If an object has damping, it will start to lose velocity immediately after a force is applied and/or a velocity is set.

Hope this helps.

One more thing, I may be guessing wrongly here, but are you expecting the same result for these two scenarios?

-- 50 x 50 rectangle w/ impulse of \< 0, 1 \> playerObj1 = display.newRect( 200,500, 50,50 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0, 1, playerObj1.x, playerObj1.y )

 and

-- 25 x 25 rectangle w/ impulse of \< 0, 1 \> playerObj1 = display.newRect( 200,500, 25,25 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0, 1, playerObj1.x, playerObj1.y )

The second case will generate a block moving at twice the velocity of the first case.  Impulses and forces are not ‘mass’ aware.  You have to calculate that yourself.

-Ed

PS - Some time ago I put together examples for the Corona Geek Hangout (81).  

https://www.youtube.com/watch?v=Ssno3LRoBKw

You can get them here and experiment with Physics forces and impulses:

https://github.com/roaminggamer/RG_FreeStuff/tree/master/Corona%20Geek/Hangout%2081 

hey, thanks for your response!

im using box2d web port  for node.js ‘npm box2dweb-commenjs’

what i meant by integer was non floating point number. so for example an applyimpulse on the y-axis of 5 would yield 10 with a mass of 1.0 in box2d web, whereas the same applylinearimpulse wrapper for coronasdk would yield a 11.15556788868

Hi again.  My guess is that the Box2D implementation you were using was ‘mass-aware’, thus giving you nice whole number responses to whole number inputs (1.0 as floating-point is for all purposes the same as the whole number 1).

So, you’re probably comparing apples and oranges here since Corona functions are not mass-aware.  i.e. They don’t adjust the implied force based on the target mass.  Instead, the force is exactly what you put in and the mass is calculated based on density and pixel area of the rectangular display object (or circular area for circles).

-Ed

I should have mentioned it, but you can easily make your code mass-aware:

playerObj1 = display.newRect( 200,500, 25,25 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0 \* playerObj1.mass, 1 \* playerObj1.mass, playerObj1.x, playerObj1.y )

now acts the same as this:

playerObj1 = display.newRect( 200,500, 50,50 ) physics.addBody(playerObj1, {density=1.00, bounce = 0.6, friction = 0}) playerObj1:applyLinearImpulse( 0 \* playerObj1.mass, 1 \* playerObj1.mass, playerObj1.x, playerObj1.y )

roaminggamer, that did the trick!! very much appreciated!