This topic is now archived and is closed to further replies.

Drag in a predictive physics model. I am crying!

This topic is 5019 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I know it''s a bit naughty to ask for help on my first post, but I''m in a spot of trouble and I don''t know where else to go! I''m currently working on a little game that requires simple particle fissics (i.e. it''s pseudo fakey arcadey physics). For some stupid reason, I decided to try to get the physics working in a sort of "predictive" manner. For example, the player would press "thrust", then the time at which "thrust" was pressed would be logged, then a delta time would be available every rendered frame to predict the position of the little air craft thingy from the position it was at when "thrust" was pressed. Basically, everything''s forward predicted from the last change in control states. So far, it works pretty well. You can chuck different forces (gravity, thrust, lift, drag) onto a stack of physics agents quite arbitrarily, and they''ll add the displacement (and change in velocity) due to themselves to an accumulator. This accumulator then adds its value to the base values (those recorded at the time when controls were changed). You have the initial velocity ("u") and position of the craft. Then you have several forces on this craft. So there''s heavy use of "v=u + at" and "s=ut + 1/2at^2". You grab the "u" and "ut" components easily from the initial values of the craft. Then you get the "at" and "1/2 at^2" components from each of the forces, add them all together, and get your final position for that rendered frame. I''m sure you''ve probably heard of this kind of approach before. It makes recording demos nice and easy, since only control changes need to be recorded, and the results of those changes are deterministic. My problem is this: so far, I''ve been dealing with constant forces. Gravity, and acceleration due to thrust are fixed. Drag and incedentally, lift, are proportional to velocity, and velocity, ofcourse, is NOT constant. (it''s roughly something like drag = 1/2v^2 for a given moment in time). Thus, I can''t take these factors as constants during the calculation of displacement and velocity change due to drag (or lift). I can''t for the life of me figure out how to integrate the drag equation so that it takes into account the delta time component. i.e. what''s the displacement due to the CHANGE in drag force (in turn, a result of the change in velocity, which you can take as a linear increase for the sake of simplicity). I''m thinking, for displacement, I have to add "s=ut + 1/2at^2" with another part, "1/3dt^3". ("a", in this case, represents the initial acceleration due to drag, and "d" represents the rate of change of "a"). Is this correct, or am I crap? I''m not even sure how to figure out the change in velocity due to changing drag! I don''t suppose anyone could give me a clue? I''ve been wracking my brains, and feel a bit stupid not being able to figure it out.

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
you''re running into a differential equation.

Share this post

Link to post
Share on other sites
I am about to runinto this problem myself. All the equations of motion I have done so far have dealt with constant acceleration.
There is a bit of calculus here that may be simple, but just I have never seen it.

Hopefully someone here will know something about "projectile motion with non constant acceleration". Google has failed me so far (I need to look harder), when I get around to it I will get an advanced physics book to see how these problems are solved. Mabe someone will give us a head start in the mean time.


[edited by - try_catch_this on March 19, 2004 2:25:09 PM]

Share this post

Link to post
Share on other sites
well... that depends on wheather the drag is velocity depndant, but the equation for the for of drag over time is:

that should get you on your way.

you can divid by mass and integrate twice and that would give you postion.

[edited by - duekiller on March 19, 2004 4:47:09 PM]

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
I tried to resolve it...

finally I came up with

v = F0/k - m(v0 + F0/k)exp(-k/m*t)

(for more than one dimension, you should apply the formula for each component) where k is the friction coefficient (drag = -kv) F0 is the constant force applied to th body and v0 is the initial velocity

for position i got

pos = 1/k * (F0*t + m * (v0 + F0/k)*exp(-k/m*t))

I don''t guarantee it''s correct but it doesn''t seem unlogical: when time -> infinity, v -> F0/k, the speed where no forces act on the body.

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
typo error, velocity formula should be:

v = F0/k -(v0 + F0/k) * exp(-k/m * t)

Share this post

Link to post
Share on other sites
Not yet implemented the kind anon's solution, but I found this, which try_catch_this might also find interesting. It solves displacement due to drag, but not velocity delta due to drag. The great part is, it explains it as if to a child! Woo!

[edited by - Bezzy on March 22, 2004 4:53:07 AM]

Share this post

Link to post
Share on other sites
Important note from that pdf - there's several different drag models, which I didn't realize.

For smallish, spherical objects, you can take drag as roughly proportional to velocity. More complex shapes are, naturally, more complicated to model, but the drag becomes proportional to the SQUARE of velocity.

The pdf only solves displacement and velocity change due to drag for linear ("Viscous") drag rather than squared ("Newtonian") drag. That's fine for me, personally - my craft are modelled as marbles (thank god for the arbitrary nature of modelling arcade physics ).

It looks like the anonymous poster's equation is right, also. There's a few little tweaks you can make to it to make it look just like the PDF's version, so you get a slap on the back for that, kind mister! Well done!

edit: I've also found a nice slide with typical drag coefficient values for regular shapes that you might use for modelling airflow in your game:
Thanks for all the help. I've learnt a lot.

[edited by - Bezzy on March 22, 2004 7:08:58 AM]

Share this post

Link to post
Share on other sites
Guest Anonymous Poster

i hope i''m not wrong:

F = F0 - kv^2
v(dot) = a0 - k/m*v^2
solving the equation
1/v^2*v(dot) = -k/m

-1/v = -k/m*t + C
thus v = m / (k*t + C) + sqr(a0*m/k)

t = 0 then v = v0

v0 = m / C + sqr(a0*m/k)

(vf = sqr(a0*m/k))

v0 = m/C + vf
C = m / (v0-vf)

so for v we got

v = m / (k*t + m/(v0-vf)) + vf

pos = m/k * ln( k*t + m/(v0-vf)) + vf*t + C

where C should be set to have pos(0) = pos0

just mind that the sign of the drag may be false....

Share this post

Link to post
Share on other sites
So far, I've had some fairly promising results. One of the displacement equations slowed down the craft to a stop, laterally, which is what it's meant to do. Unfortunately, it doesn't really work consistantly, depending on whether thrust was last pressed or released. Also, I couldn't get the velocity-after-time equation to work so successfully.

The problem is, I have a certain physics framework working at the moment. I'll give a little bit of pseudo code:

Times: Now, KeyChangeTime, DeltaTime; //DeltaTime = Now - KeyChange Time.
Vector: Direction; //Normalized vector representing ship's heading
Vectors: StartPos, StartVel; //Orientation at key state change
Vectors: DeltaPos, DeltaVel; //*Change* in position and velocity
// during DeltaTime due *ONLY* to forces during this peroid -
// NOT due to initial velocity or position.
Vectors: NewPos, NewVel; //The orientation at time = Now.
//NewPos = StartPos + DeltaTime*StartVel DeltaPos.
//Note that this takes into account the initial velocity.
//NewVel = StartVel + DeltaVel

void ControlsChanged() //Update position and time at which new keyframe changed at
KeyChangeTime = Now;
StartPos = NewPos;//NewPos has been worked out by the physics functions
StartVel = NewVel;//As above, this has been computed by the physics call.

void ResetPhysics()
//DeltaPos and DeltaVel are cleared at the beginning of
// physics. They act as accumulators for displacement due *only*
// to forces. Inherent velocity is ignored until the last stage.
DeltaPos.Clear()//Set all components to zero

void Physics() //Called every rendered frame to find out the NewPos and NewVel of rendered objects
//To apply s=ut+1/2at^2, the force must be constant for the extent of DeltaTime. Example: gravity.
Vector Gravity(0, -9.8, 0);//Acceleration due to gravity. Assume mass of object = 1.0;
//Displacement due to force *alone* ds = 1/2at^2. ie s= /*ut*/ + 1/2at^2
DeltaPos += 0.5*(Gravity*(DeltaTime*DeltaTime));
//Change in velocity due to force *only* is dv = at, ie v= /*u*/ + at
DeltaVel += Gravity*DeltaTime;

//Here's another acceleration component. The nice part of
// this is you can add to the accumulator at any point between
// it being cleared, and it being finalized.
//Thrust in craft's direction
if(CONTROLS & Thrusting)
DeltaPos += 0.5*(Direction*(DeltaTime*DeltaTime));
DeltaVel += Direction*DeltaTime;


void FinalizePhysics{
NewPos = StartPos + (DeltaPos) + (StartVel*DeltaTime);
NewVel = StartVel + DeltaVel;//Must be after the above for obvious reasons.
void LoopMe(){
//Functions must come in order:
if(Controls Have Changed)
ControlsChanged(); //Can be at beginning or end, but not between others

So, the jist of it is this: The starting position and speed of the craft is recorded, as is a required time to extrapolate its position. Forces affecting the craft during this period are added kinda willy nilly. It's easy enough to work out the displacement and change in speed due ONLY to each force. These shifts in position/speed are added to accumulators. The accumulated change in position/velocity are finally added to the object's INHERENT momentum - ie, where the object would have gone when not under any forces.

But drag is not a constant force. I guess what I'm looking for is the displacement due to the drag alone, so that it can be added to the position and velocity displacement accumulators, and then finally get added in a regular way along with the accumulator.

So what you've got to play with is the initial velocity (StartVel), the velocity that WOULD HAVE BEEN (StartVel+DeltaVel). You don't need to worry about the actual position - just the change in position due to the drag force. I can't get my head around exponentials, although I'm sure they're the right thing to use - as time approaches infinity, the delta velocity needs to plateux to constant: terminal velocity.

Ahh. Sorry to be so expectant, but by brain is truely fried. I knew I should have taken M2 in Maths A-Level :/

[edited by - Bezzy on March 23, 2004 8:47:55 AM]

[edited by - Bezzy on March 23, 2004 8:49:27 AM]

[edited by - Bezzy on March 23, 2004 8:50:27 AM]

Share this post

Link to post
Share on other sites