Saturday, May 4, 2013

Air Resistance in Box2D

I've seen many questions asking how to implement air resistance (drag) in box2d, and the most common solution is to use body.setLinearDamping.  After just a little bit of research, I discovered that calculating air resistance is not that difficult.  Here is an example in Java using box2d.
Note: this is not a full simulation of aerodynamics, it only affects linear velocity.
After reading the source, check out the algorithm in action in this video.
float dragForce;
Vector2 appliedDrag = new Vector2();
float dragAngle;
float p, A, Cd, v; // elements of the formula see wikipedia entry for Drag (physics)
/*
ρ is the density of the fluid,
v is the speed of the object relative to the fluid,
A is the cross-sectional area
Cd is the drag coefficient – a dimensionless number.
sample drag co-efficients (http://en.wikipedia.org/wiki/Drag_coefficient)
cube = 1.05
sphere = 0.47
streamlined-body (smooth wing shape) = 0.04
*/
// it's not necessary to calculate fluid density as I have, try 1.0 and change it until it looks nice
p = FLUID_DENSITY_OF_AIR * getAtmosphericDensity(ent.getAltitude()); // density of the fluid
// we can just leave this, cross-sections are beyond the scope of what we want to simulate
A = 1.0f;
// a very sleek object
Cd = 0.05f;
v = (float) Math.pow(ent.getSpeed(), 2); // speed squared
dragForce = 0.5f * p * v * Cd * A;
// we need the angle of the body's current velocity to know which angle we should set the drag force
dragAngle = ent.body.getLinearVelocity().angle();
// create a vector based on our dragForce
appliedDrag.set(dragForce, 0);
// align the drag to the same angle as our velocity
appliedDrag.setAngle(dragAngle);
// drag should slow down velocity when added to current velocity, so we make it negative
appliedDrag.scl(-1);
ent.body.applyForceToCenter(appliedDrag, true);

No comments:

Post a Comment