Marketplace › From Ordinate 2D
Chaos: two nearly identical double pendulums
A difference of 10⁻⁴ rad grows until the two motions are unrelated.
Use in Ordinate 2DOpens in the Script tab: it runs when you press Run. Free, no account needed.
"""Sensitive dependence: two double pendulums that differ by a ten-thousandth of a radian.
Both start from the same pose except that the second one's upper rod is 0.0001 rad further round. For a while they swing as
one; then the difference grows by a large factor every second and the two motions have nothing in common. The table
has the separation of the lower bobs against time (chart it on a log axis: a straight line is exponential growth).
Runs in the studio (Script tab → Run) and locally: python3 chaos_double_pendulum.py
"""
import math
import studio as s
L1, L2 = 0.9, 0.8
A1, A2 = math.radians(120), math.radians(-10)
EPS = 1e-4
s.clear()
s.gravity = (0, -9.81)
def pendulum(cx, a1, hex_):
anchor = s.box(cx, 2.4, 0.2, 0.1, static=True, name=f"Anchor {hex_}", color="#8b939b", collide=False)
p1 = (cx + L1 * math.sin(a1), 2.4 - L1 * math.cos(a1))
b1 = s.circle(*p1, 0.08, mass=1, name=f"Bob 1 {hex_}", color=hex_, collide=False, restitution=0)
p2 = (p1[0] + L2 * math.sin(A2), p1[1] - L2 * math.cos(A2))
b2 = s.circle(*p2, 0.07, mass=1, name=f"Bob 2 {hex_}", color=hex_, collide=False, restitution=0)
s.rod(anchor, b1, at_a=(cx, 2.4), at_b=p1)
s.rod(b1, b2, at_a=p1, at_b=p2)
return b2
first = pendulum(-1.2, A1, "#4f8ff7")
second = pendulum(1.2, A1 + EPS, "#e5484d")
@s.on_step
def compare(t, dt):
if round(t / dt) % 12 == 0:
sep = math.hypot((first.x + 1.2) - (second.x - 1.2), first.y - second.y)
s.record(t=t, separation=sep)
@s.on_end
def report():
print(f"after {s.time:.0f} s the lower bobs are {math.hypot((first.x + 1.2) - (second.x - 1.2), first.y - second.y):.3f} m apart (they started {L1 * EPS:.1e} m)")
s.run(20)