Ordinate 2D Marketplace Community Open the studio

Marketplace › From Ordinate 2D

How fast do dominoes fall? A sweep of the spacing

Script by Ordinate 2D ✓ · Puzzles and challenges

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)

table collisions experiment