Explosion, random distribution, linear drag

Topics: Developer Forum, User Forum
Jan 27, 2008 at 12:41 AM
Edited Jan 27, 2008 at 12:42 AM
Hey, I've been experimenting with a simple explosion effect: I create a bunch of non-colliding particles in the same spot, and then apply a random force to each particle.
I can get a good random distribution if I don't change the linear drag coefficient of the particles, but if I do, the particles tend to bunch toward the corners.

Here are pictures of the particles: The first is what happens if I don't change the linear drag coefficient (the scale of the applied force is not randomized to show circular distribution).
Here's what happens if I change the linear drag to 0.05.

Here's the random force generation code (called with 4000 to 80000 as the max):
Random rand = new Random();
Vector2 getRandomVector2(float max)
     Vector2 v = new Vector2();
     float theta = (float)(rand.NextDouble() * MathHelper.TwoPi);
     v.Y = (float)Math.Sin(theta);
     v.X = (float)Math.Cos(theta);
     float scale = (float)(rand.NextDouble()) * max;
     v *= scale;
     return v;
Jan 28, 2008 at 4:24 PM
This is strange.

There have been other posts about wierd things happening with linear drag. I haven't been able to track it down yet. I'll try to get some time to look at this again.
Jan 28, 2008 at 6:48 PM
Edited Jan 28, 2008 at 7:14 PM
I looked at the linear drag code, and it looks like you are generating a drag force Fx = -cvx^2 (and also for y), where 'c' is the drag coefficient. According to wikipedia and various physics websites, linear drag depends linearly on velocity, not quadratically: F = -cv. It seems that there is also a quadratic drag which is closer to the form you give, but which is operative at high velocities. The linear drag is apparently an effective approximation for a body moving through a viscous medium, such as air, at reasonable speeds.

I tried changing the Body.ApplyDrag() method to use an actual linear drag formula, which solved the distribution problem. The quadratic drag formula you were using seems to work to a greater degree on objects moving in the X or Y directions only. To include the effects of the quadratic drag, the formula would have to be F = -bvv^2, where 'v' is the speed, and 'v' is the normalized velocity. This causes F to have length proportional to the length squared of velocity, whereas with your original formulation it had components proportional to the components squared, which is not the same thing. The formula can be reduced (I believe) to F = -bvv, so that no normalization is necessary.

Here's the relevant portion of my ApplyDrag method:
#region INLINE: Vector2.Multiply(ref linearVelocity, -linearDragCoefficient, out linearDrag);
linearDrag.X = -linearVelocity.X * linearDragCoefficient;
linearDrag.Y = -linearVelocity.Y * linearDragCoefficient;
#region INLINE: Vector2.Multiply(ref linearVelocity, -quadraticDragCoefficient * speed, out quadraticDrag);
quadraticDrag.X = -quadraticDragCoefficient * speed * linearVelocity.X;
quadraticDrag.Y = -quadraticDragCoefficient * speed * linearVelocity.Y;
#region INLINE: Vector2.Add(ref linearDrag, ref quadraticDrag, out totalDrag);
totalDrag.X = linearDrag.X + quadraticDrag.X;
totalDrag.Y = linearDrag.Y + quadraticDrag.Y;
ApplyForce(ref totalDrag);

I also added a float quadraticDragCoefficient and property, and directly above the ApplyDrag method, I added a Vector2 totalDrag, although this could probably be removed for optimization.

In testing, for a mass of 1, a linearDragCoefficient of 0.1 and a quadraticCoefficient of 0.01 seemed to work well. For the default value, 0.001 caused both types of drag to have little effect, as desired.
Jan 28, 2008 at 7:39 PM
Great find! I looked at that code quite a few times and never caught that.

I'll definetly get this in the next version. It will be interesting to see if this fixes the issue (from another post) that was causing a turning object to map out a rounded square rather than a circle.

Thanks for taking the time to find this.

Jan 28, 2008 at 7:59 PM
No problem. Glad to be able to help.

Feb 1, 2008 at 2:14 PM
This is great news!

I had been one of the people who had seen this, in both my projects I just ended up applying my own deceleration force. (I felt like I was cheating a bit)

Go Farseer people!

Hopefully I will shortly be releasing a version of my game that uses Farseer.

Have a nice weekend all.