Marketplace › From Ordinate 2D
How fast do dominoes fall? A sweep of the spacing
Six rows of dominoes with different spacings fall at once: the speed of the falling front against d/h, and the fastest spacing.
Use in Ordinate 2DOpens in the Script tab: it runs when you press Run. Free, no account needed.
"""How fast does a row of dominoes fall? An experiment over the spacing.
Six rows of 16 dominoes (0.5 m tall, 5 cm thick) stand on five shelves, each row with a different spacing d. The first of each
row is tipped at the same moment; the script times when each domino has turned 45° and works out the speed of the falling front
from the last ten. The rows of the Script sheet give the speed against d/h, and the console names the fastest spacing: the
closer they stand, the less each one has to fall before it hits the next.
Runs in the studio (Script tab → Run) and locally: python3 domino_speed.py
"""
import math
import studio as s
H, T = 0.5, 0.05 # domino height and thickness, m
N = 16
RATIOS = [0.12, 0.2, 0.35, 0.5, 0.65, 0.8] # spacing / height
s.clear()
s.gravity = (0, -9.81)
rows = []
for i, ratio in enumerate(RATIOS):
y0 = 2.0 * i
d = ratio * H
s.ground(y0, x=N * d / 2, width=N * d + 2, name=f"Shelf {i + 1}", friction=0.6)
dominoes = [s.box(j * d, y0 + H / 2, T, H, mass=0.1, name=f"Row {i + 1} domino {j + 1}", friction=0.5, restitution=0,
color="#4f8ff7" if j % 2 else "#e5484d") for j in range(N)]
dominoes[0].omega = -3.0 # the push (clockwise: towards the others)
rows.append({"ratio": ratio, "d": d, "dominoes": dominoes, "fell": [None] * N, "done": False})
@s.on_step
def watch(t, dt):
for r in rows:
if r["done"]:
continue
for j, dm in enumerate(r["dominoes"]):
if r["fell"][j] is None and abs(dm.angle) > math.pi / 4:
r["fell"][j] = t
times = r["fell"]
if times[-1] is not None:
speed = 10 * r["d"] / (times[-1] - times[-11])
s.record(spacing_over_height=r["ratio"], spacing=r["d"], front_speed=speed)
print(f"d/h = {r['ratio']:.2f}: the front runs at {speed:.2f} m/s")
r["speed"] = speed
r["done"] = True
elif t > 20:
print(f"d/h = {r['ratio']:.2f}: the row stopped part way (they lean on each other, or stand too far apart)")
r["done"] = True
if all(r["done"] for r in rows):
timed = [r for r in rows if r.get("speed")]
if timed:
best = max(timed, key=lambda r: r["speed"])
print(f"fastest: d/h = {best['ratio']:.2f}, {best['speed']:.2f} m/s")
s.stop()
s.run(25)