Quadratic drag wrong?

Jul 22, 2009 at 9:39 PM

Hi,

I noticed that I was having a problem with quadratic drag at high velocities. If I give my objects a quadratic drag of 0.1 and speeds in the 1000's, then instead of coming to a halt, they fly away instantly.

I checked what was happening to the velocities over several updates:

{X:-1600 Y:-1600}
{X:4436.657 Y:4436.657}
{X:-41966.29 Y:-41966.29}
{X:4109227 Y:4109227}
{X:-3.979607E+10 Y:-3.979607E+10}
{X:3.732888E+18 Y:3.732888E+18}
{X:-3.284388E+34 Y:-3.284388E+34}
{X:Infinity Y:Infinity}

So, it is oscillating from positive to negative, and growing. Since it was happening at high speeds only, I guessed it was related to quadratic drag. Looking at the code for quadratic drag, I think I found an error that is causing the drag to be hugely greater than it should be.

From line 867 of Body.cs:

#region INLINE: Vector2.Multiply(ref linearVelocity, -_quadraticDragCoefficient * _speed, out _quadraticDrag);

_quadraticDrag.X = -QuadraticDragCoefficient * _speed * LinearVelocity.X;
_quadraticDrag.Y = -QuadraticDragCoefficient * _speed * LinearVelocity.Y;

#endregion

As you can see, this section is meant to multiply the Coefficient by the speed, but it also multiplies by this extra factor of LinearVelocity.

I know that this factor was meant to cause the quadraticDrag to operate in opposition to the current velocity, so I tried changing both instances of LinearDrag.X/Y to Math.Sign(LinearVelocity.X/Y). This eliminated the problem.

Can someone verify that this is correct?

Coordinator
Jul 23, 2009 at 1:26 AM

Did you apply 1000 force or 1000 impulse?

1000 impulse is really really high and a QuadraticDragCoefficient of 0.1 will give you a weird behavior. Try 0.01 instead for impulses of 1000 and over. QuadraticDragCoefficient is meant for high velocities that should me lowered fast. It depends on the speed and linear velocity of the body, so the higher speed, the more drag. Not like linear drag that is the same constant damping applied over time. So QuadraticDragCoefficient needs to be very low.

Jul 23, 2009 at 2:11 AM

No, that was the initial velocity. I determined that there's a critical point -- if you set the initial velocity to 1200 or greater, it goes to NaN in about 10 updates. Under 1200 it works fine.

Sorry, I misready the #region label, not noticing the ref linearVelocity at the beginning. But still, if you look at the calculation for angular drag, this extra factor of the velocity is replaced by the sign of the velocity.

If you look at the wikipedia page on drag (http://en.wikipedia.org/wiki/Drag_(physics)), in the section on drag at high velocities, the quadratic drag force depends on -v^2 * v_hat. In other words, the magnitude of the velocity squared, in the opposite direction of the velocity. Not, as Farseer has it, on v^2 * v.

Coordinator
Jul 23, 2009 at 2:32 AM

You might be right, I will take a look at it. Thanks

Coordinator
Jul 23, 2009 at 7:07 PM
Edited Jul 23, 2009 at 7:12 PM

I've changed it to -v^2*sign(v)

I've also optimized that part of the code a little be excluding two vector operations. Could you check it to see if it is correct? You can find the file here or download the latest changeset from the source control.

Edit: More like -s*C*sign(v) where s is the speed that is composed of sqrt(lx^2 +ly^2) and C is the coefficient.

Jul 23, 2009 at 7:12 PM

Looks good to me!

Coordinator
Jul 23, 2009 at 7:15 PM

I've just updated my previous post when you wrote. But good that it works out for you. I'm not sure how much quadratic drag is used in the engine since it mostly handles low velocity objects (<1000). I still remember back when FPE had the problem of linear drag being calculated as quadratic drag. I guess this problem dates back to that.

Thanks for reporting the problem and for providing a solution.