void calculateResponseVelocity( ref Vector2 relativeVelocity, ref Vector2 minimumTranslationVector, out Vector2 responseVelocity )
{
// first, we get the normalized MTV in the opposite direction: the surface normal
var inverseMTV = minimumTranslationVector * -1f;
Vector2 normal;
Vector2.Normalize( ref inverseMTV, out normal );
// the velocity is decomposed along the normal of the collision and the plane of collision.
// The elasticity will affect the response along the normal (normalVelocityComponent) and the friction will affect
// the tangential component of the velocity (tangentialVelocityComponent)
float n;
Vector2.Dot( ref relativeVelocity, ref normal, out n );
var normalVelocityComponent = normal * n;
var tangentialVelocityComponent = relativeVelocity - normalVelocityComponent;
if( n > 0.0f )
normalVelocityComponent = Vector2.Zero;
// if the squared magnitude of the tangential component is less than glue then we bump up the friction to the max
var coefficientOfFriction = _friction;
if( tangentialVelocityComponent.LengthSquared() < _glue )
coefficientOfFriction = 1.01f;
// elasticity affects the normal component of the velocity and friction affects the tangential component
responseVelocity = -( 1.0f + _elasticity ) * normalVelocityComponent - coefficientOfFriction * tangentialVelocityComponent;
}