Momentary impulse through some sort of force

Started by
6 comments, last by johnstanp 13 years, 9 months ago
In the simulation I am creating I have a very basic "Update Position, Calculate Acceleration, Update Velocity" update going. However, this only ideal if the object never takes some sort of momentary impulse force. By "momentary impulse" I mean like when you press forward and a character moves one unit for that time slice and the force is not permanently added to the velocity, like in a driving simulation.

My question is, how can I have a momentary impulse added to my current physics update? I want to be able to add a force like (2.0f, 0.0f, 0.0f) to my object and have it be their for ONLY the one time the update gets called.

Here is how my code is right now:

position += velocity * deltaTime;D3DXVECTOR3 acceleration = gravity / mass;velocity += acceleration * deltaTime;
Advertisement
It's not exactly clear how you want to apply the "impulse."

Perhaps you default the impulse to (0,0,0) and set it to some temporary value when it's to be applied.
// ... set the impulse if desired, else leave as (0,0,0)D3DXVECTOR3 imp_accel = impulse/mass;D3DXVECTOR3 tmp_vel = imp_accel * deltaTime;position += ( velocity +tmp_vel ) * deltaTime; // leaves velocity independent of impulseimpulse = D3DXVECTOR3(0,0,0);// followed by your acceleration & velocity calcs

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

By "impulse" I mean a temporary value that gets added for one time slices.

I do not want to add it directly to my position and nothing else because then that would rude my collision detection.
Quote:when you press forward and a character moves one unit for that time slice
Quote:I do not want to add it directly to my position and nothing else

That's a bit confusing, I'm afraid. Do you want the position to change as a result of the impulse? Your first post says "yes," the second post "no."

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?
Quote:Original post by Hurp
Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?

A force applied to the center of mass of a rigid body modifies the accelerarion. The acceleration modifies the velocity and the velocity modifies the position, if of course, the acceleration and the velocity are not equal to zero. The effect is direct if in your ODE solver the position at time t+dt is computed with the velocity at time t+dt.

This is the case in the following two examples
acceleration = force / mass;velocity += acceleration * dt;position += velocity * dt;


acceleration = force / mass;old_velocity = velocity;velocity = old_velocity + acceleration * dt;position += ( velocity + old_velocity ) * dt / 2;


The last example is more accurate.

Now, you should understand that when dealing with collision detection you have to make a choice:
- you can try to detect collisions before they happen. If a collision is predicted, the state of the simulation is updated to the time of collision and the collision response is computed.
- you could let them happen and resolve them later.

The first option is the most difficult to implement. Because, generally you don't have a closed form solution of the system of equations you want to solve. You can use iterative methods for determining the "exact" time of collision, for non-obvious cases, but it is computationally expensive, when dealing with non simple geometries.

The second option is the easiest one: you make the assumption that at the beginning of the update routine, you have no collision. You update the simulation. Then, you test if a (many) collision(s) occurred: if a (many) collision(s) occurred, you correct the position and velocity of the colliding bodies.

For the second option, there's no need to know the velocity of a rigid body at the start of a frame for collision detection. The velocity at the end of the frame is definitely needed, to adequately correct the position and velocity of colliding bodies.

You can't try detecting collisions before their occurrence, and at the same time, move the bodies arbitrarily.

P.S: a force can't be added to a position or a velocity. As I already told you, you need to read a book or a course on basic physics. You can't try implementing a collision detection routine, if you don't grasp what a force and an impulse are. Some papers would be very hard to even read, if I didn't have a background in Mathematics and Physics. So take the time to read about linear momentum and impulse: you won't lose your time.

[Edited by - johnstanp on July 6, 2010 8:51:03 AM]
What I've just written is still valid but after reading you again, and reminiscing our previous discussions, I better understand your problem. So I hope that now, it will perfectly be addressed.

Quote:Original post by Hurp
Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?


Well, if my assumption is right, you're still using the "algorithm" and the initial updayte function I provided in a previous topic...
What you want to do is not adding a "force" to a player's position, but incrementing the player's position with a certain quantity (of course a vector).
This is what you want:
position += delta_position;


between t and t+dt.

Now, the equations I provided earlier don't take into account the velocity at time t+dt to compute the position at time t+dt, but the velocity at time t.
So as you've well guessed, affecting the velocity doesn't directly affect the position. It will at t+2*dt. But you want to directly affect position by affecting the velocity. It's simple: use another integration scheme.

This one offers a better accuracy than the one I proposed earlier (in another topic):
acceleration = force / mass;position += velocity * dt + 0.5 * acceleration * dt * dt;velocity += acceleration * dt;


This is equivalent to:
acceleration = force / mass;Vector3 old_velocity = velocity;velocity += acceleration * dt;position += 0.5 * ( velocity + old_velocity ) * dt;

You should be able to demonstrate it.

If you chose that integration scheme, then if you want the player's position to be incremented by dx after the next update, apply the following force(*):
Vector3 force = mass * ( 2 * dx / dt - 2 * velocity ) / dt;


Then call the function that update the player's state, with that value:
void update( Rigid_body & body, Vector3 const & force, float dt ){   Vector3 old_velocity = body.velocity;   body.velocity += force / body.mass * dt;   body.position += 0.5 * ( old_velocity + body.velocity ) * dt;}int main( int argc, char ** argv ){   ...   //dx is what you incorrectly call "impulse"   Vector3 force = body.mass * ( 2 * dx / dt - 2 * body.velocity ) / dt;   update( body, force, dt );}


This way you can continue using what you're using right now.

P.S:
(*) is derived this way:
x - xo = dx = ( vo + v )dt/2
<=>v = 2dx/dt - vo (1)

dv = v - vo
=>dv = 2dx/dt - 2vo (2)

v = vo + adt
<=>a = ( v - vo )/dt
<=>a = dv/dt (3)

(2) in (3)=>
a = ( 2dx/dt - 2vo )/dt (4)

F = Ma (5)
(4) in (5)=>
F = M( 2dx/dt - 2vo )/dt (6)

v = velocity at time t+dt
vo = velocity at time t
x = position at time t+dt
xo = position at time t
a = acceleration in time interval[t,t+dt]
dt = timestep of the simulation

[Edited by - johnstanp on July 6, 2010 8:56:51 AM]
And at last:
your collision detection routine (the one I provided earlier) doesn't know exactly the position of the bodies at the end of the frame. It just knows current positions and velocities and "predict" with this data, eventual collisions. The collision routine assumes that the velocity of the bodies are constant between t and t+dt, which is obviously not the case. This is why I told you that you can't prevent inter-penetrations: you just know that impulses will be computed if a collision appears. That doesn't mean bodies won't inter-penetrate.

This topic is closed to new replies.

Advertisement