Marketplace › From Ordinate 2D
Moment of inertia from rolling times
A disc, a thick ring, a thin hoop and a sliding block race down equal slopes; k = g sin θ t²/2L − 1 gives each one's I/mr².
Use in Ordinate 2DOpens in the Script tab: it runs when you press Run. Free, no account needed.
"""Moment of inertia from rolling: time four bodies down a slope and work out I/mr² from the times.
A body that rolls without slipping down a slope of angle θ accelerates at a = g sin θ / (1 + k), with I = k m r². So from
the time t to roll a length L (from rest, L = ½ a t²): k = g sin θ t² / (2L) − 1. The script rolls a solid disc, a thick
ring, a thin hoop and a smooth sliding block (k = 0) down four equal slopes and compares each k with ½(1 + (hole/r)²).
(The studio's default rolling resistance, 0.02, slows the rolling bodies a little: their k comes out 0.05 to 0.07 high, while the
sliding block, which does not roll, gives 0. That excess is itself a measurement of rolling resistance: about (1 + k)·μr / sin θ.)
Runs in the studio (Script tab → Run) and locally: python3 rolling_inertia.py
"""
import math
import studio as s
THETA = math.radians(30)
L = 3.0 # m along each slope
R = 0.2 # m
BODIES = [("Solid disc", 0.0), ("Thick ring", 0.5 * R), ("Thin hoop", 0.9 * R), ("Sliding block", None)]
s.clear()
s.gravity = (0, -9.81)
s.air_density = 0
racers = []
for i, (name, hole) in enumerate(BODIES):
y0 = 9 - 3 * i # each slope 3 m lower than the one before
s.ground(y0, x=0, width=L + 1.5, angle=-THETA, name=f"Slope {i + 1}", friction=0.9 if hole is not None else 0.0)
# start at the top of the slope, resting on it
sx, sy = -(L + 1.5) / 2 * math.cos(THETA) + 0.3, y0 + ((L + 1.5) / 2 - 0.3 / math.cos(THETA)) * math.sin(THETA)
nx, ny = math.sin(THETA), math.cos(THETA) # the slope's outward normal
if hole is None:
b = s.box(sx + nx * 0.1, sy + ny * 0.1, 0.3, 0.2, mass=1, name=name, angle=-THETA, friction=0.0, color="#8b939b")
k_theory = 0.0
else:
b = s.circle(sx + nx * R, sy + ny * R, R, mass=1, name=name, friction=0.9, hole=hole, color="#4f8ff7")
k_theory = 0.5 * (1 + (hole / R) ** 2)
racers.append({"n": i + 1, "name": name, "body": b, "x0": b.x, "y0": b.y, "k": k_theory, "done": False})
@s.on_step
def timing(t, dt):
for r in racers:
if r["done"]:
continue
d = math.hypot(r["body"].x - r["x0"], r["body"].y - r["y0"])
if d >= L:
g = -s.gravity[1]
k = g * math.sin(THETA) * t * t / (2 * L) - 1
s.record(racer=r["n"], time=t, k_measured=k, k_theory=r["k"]) # racer 1 to 4: disc, thick ring, hoop, block
print(f"{r['name']:<13} t = {t:.3f} s → I/mr² = {k:.3f} (theory {r['k']:.3f})")
r["done"] = True
if all(r["done"] for r in racers):
s.stop()
s.run(10)