Ordinate 2D Marketplace Community Open the studio

Marketplace › From Ordinate 2D

Moment of inertia from rolling times

Script by Ordinate 2D ✓ · Rotation and rolling

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)

table rolling ring experiment