Simple Physics for Motion: Mass, Force, Springs, and Gravity

April 21, 2026 · 5 min read · Design Interactive Physics

This article should have started here.

Not with "animation principles." Not with a gallery of clever demos. Just with basic mechanics.

If motion on screen feels believable, it is usually because a few physical ideas are behaving coherently:

  • position
  • velocity
  • acceleration
  • force
  • mass
  • damping

That is enough to explain a large amount of interface motion, game feel, and simulated movement.

Start with State

In one dimension, the minimum useful system is:

  • position: x
  • velocity: v
  • acceleration: a

The update step is:

v = v + a * dt
x = x + v * dt

dt is the timestep. It means: how much time passed since the last update?

That is the first idea to keep straight:

  • acceleration changes velocity
  • velocity changes position

Force and Mass

Newton gives the core relationship:

F = m * a
a = F / m

The same force affects a light body and a heavy body differently.

  • small mass: responds quickly
  • large mass: responds slowly

That is where "weight" starts to come from. Not from shadows or blur, but from response.

mass m force F acceleration a
A rectangle is enough. A force acts on a mass, which creates acceleration. That is the important relationship.

Python: Constant Force on a Mass

Python Example
x = 0.0
v = 0.0
force = 12.0
mass = 3.0
dt = 1 / 60

for frame in range(120):
    a = force / mass
    v = v + a * dt
    x = x + v * dt
    print(frame, round(x, 3), round(v, 3))

Nothing fancy is happening here. That is the point.

Gravity

Gravity is just acceleration acting downward.

a = g
v = v + g * dt
y = y + v * dt

The useful mental model is:

  • gravity does not directly move the body
  • gravity changes the velocity
  • the velocity accumulates over time

That is why falling motion curves instead of moving in a straight line.

Python: Falling Rectangle

y = 0.0
v = 0.0
g = 9.81
dt = 1 / 60

for frame in range(90):
    v = v + g * dt
    y = y + v * dt
    print(frame, round(y, 3), round(v, 3))

Springs

Springs matter because many useful motions are really "return to equilibrium" motions.

Hooke's law:

F_spring = -k * x

Where:

  • k is stiffness
  • x is displacement from rest

The negative sign is the important part. The spring force always points back toward equilibrium.

Read it plainly: the farther you pull something away from rest, the harder the spring tries to pull it back.
rest position mass
The spring does not "know" about style. It only knows displacement from the rest position.

Python: Spring Force

x = 120.0      # displacement from rest
v = 0.0
k = 40.0
mass = 1.0
dt = 1 / 60

for frame in range(180):
    force = -k * x
    a = force / mass
    v = v + a * dt
    x = x + v * dt
    print(frame, round(x, 3), round(v, 3))

Damping

If you only apply the spring force, the object can overshoot for too long. Real systems usually lose energy.

A simple damping term is:

F_damping = -c * v

Now the total force becomes:

F_total = -k * x - c * v

This is one of the most useful equations in motion work. It explains why something returns, overshoots, and eventually settles.

Python: Spring with Damping

x = 120.0
v = 0.0
k = 40.0
c = 12.0
mass = 1.0
dt = 1 / 60

for frame in range(180):
    force = -k * x - c * v
    a = force / mass
    v = v + a * dt
    x = x + v * dt
    print(frame, round(x, 3), round(v, 3))
Useful distinction: a spring cares about displacement from a target. Damping cares about current velocity.

Collision and Energy Loss

When a body hits a floor or wall, it can reverse direction. But if it keeps all of its energy, the result often feels too perfect.

A common approximation is:

v_after = -e * v_before

Where e is restitution.

  • e = 1.0 means no energy loss
  • e < 1.0 means some energy is lost

That is enough to explain why each bounce becomes smaller.

Python: Falling and Bouncing

y = 20.0
v = 0.0
g = 9.81
e = 0.7
floor = 300.0
dt = 1 / 60

for frame in range(240):
    v = v + g * dt
    y = y + v * dt

    if y >= floor:
        y = floor
        v = -e * v

    print(frame, round(y, 3), round(v, 3))

What This Has To Do with Interface Motion

A lot of UI motion problems are really small physics problems in disguise.

Questions like these are usually better than "Which easing curve should I use?"

  • What is the moving body?
  • Does it have mass?
  • Is there a return force?
  • Is energy being lost?
  • Should the motion settle, glide, or bounce?

If you can answer those, the motion usually becomes easier to build.

The Main Point

The article does not need nine flashy examples.

A rectangle mass, a force arrow, a spring, and a few formulas are enough to teach the important part.

Once the mechanics make sense, the visual style can come later.