A Simple Trick for Moving Objects in a Physics Simulation

It is sometime necessary to move an object in a physics simulation to a specific point. On the one hand, it can be difficult to analyse the exact force you have to apply; on the other hand it might not look so good if you animate the object’s position directly.

A compromise that works well in many situations is to use a spring-damper system to move the object.

The trick is simple: we apply two forces—the one is proportional to the displacement; the other is proportional to the velocity. Tweaked correctly, they combine to give realistic movement to the desired point.

The spring force is proportional to the difference between the current position and the position where we want the object:

$F_s = -k(x - x_0)$

Here, $k$ is a positive value called the spring constant.

As you can see, the force gets smaller as our object approaches the desired position, and becomes zero when it reaches that position. Unfortunately, in the absence of friction or drag, the velocity is not zero at this point, so the object overshoots the desired position, and moves past it. The force becomes bigger, but in the opposite direction. The object keeps on moving, slowing down, and finally starts moving in the opposite direction towards the desired position. This goes on indefinitely.

When there is friction or drag, we might be lucky enough for the system to slow down the object sufficiently so that its velocity becomes zero when the object reaches the desired position. This can be tricky to accomplish, though, and might impact the simulation environment in undesirable ways.

It is better to add a counteracting force explicitly. We add a damper force that is propostional to the velocity of the object, again opposite in direction. Here $c$ is the viscous damping coefficient, also a positive number.

$F_d = -cv$

We then apply the sum of the forces to our object:

$F_t = F_s + F_d$

The trick is to choose $c$ to get the behaviour we want.

Fortunately, this is easy. The following table summarizes how the damping constant affects behaviour. Here, $m$ is the mass of the object.

 $c = 0$ The object oscillates. $0 < c < 2\sqrt{mk}$ The object oscillates, but the oscillations die down. $c = 2\sqrt{mk}$ The object moves to the desired position without oscillating in minimum time. $c > 2\sqrt{mk}$ The object moves to the desired position without oscillating, and takes longer as c increases.

If you want to see an explanation of how this works, see the Wikipedia article on damping.

By choosing $c = 2\sqrt{mk}$, we are left with only one parameter to tweak (the spring constant), with which we can adjust the time it will take for the object to reach the desired spot.

A simple implementation of this idea is given by the following function. The function should be called for every simulation frame, until we are satisfied that the object reached its spot:

private void MoveTo(Rigidbody rigidbody, Vector3 newPosition,
float springConstant)
{
Vector3 desiredDisplacement = rigidbody.position - newPosition;
Vector3 springForce = -springConstant * desiredDisplacement;

float viscousDampingCoefficient
= 2 * sqrt(rigidbody.mass * springConstant);

Vector3 dampingForce
= -viscousDampingCoefficient * rigidbody.velocity;

Vector3 totalForce = springForce + dampingForce;
}