I noticed that when I write code that is not trivial to understand I tend to extract intermediate values into variables with meaningful names.
applyDrag(): void {
const { quad: quadConfig } = settings
const quad = this.getRigidBody()
const quadVel = vec3ToTwgl(quad.linvel())
const dragMag = aerodynamicDrag(quadConfig.dragCoefficient, v3.length(quadVel), quadConfig.frontalArea)
const dragDir = v3.negate(v3.normalize(quadVel))
const dragForce = v3.mulScalar(dragDir, dragMag)
const dragImpulse = v3.mulScalar(dragForce, dt)
quad.applyImpulse(vec3TwglToRapier(dragImpulse), true)
}
This way code gets more natural language anchors which helps understanding what it does.