DEV Community

Cover image for The Tusi couple in Python: 8 beads in straight lines that roll as a circle
Black
Black

Posted on

The Tusi couple in Python: 8 beads in straight lines that roll as a circle

Eight beads sit in eight straight slots. Each bead only ever slides back and forth along its own line. Watch all eight at once, though, and you see a circle rolling around the dial.

Tusi couple animation

The trick: a circle rolling inside a circle twice its size

In 1247 the Persian astronomer Nasir al-Din al-Tusi showed that if a circle of radius r rolls inside a circle of radius 2r, every point on the small circle's rim moves in a straight line through the centre. Copernicus later used the same construction to build straight-line motion out of circles.

The maths is one line. Put the small circle's centre at angle t. It rolls the opposite way, so a rim point that started at angle b sits at

P(t) = r*(cos t, sin t) + r*(cos(b - t), sin(b - t))
     = 2r * cos(t - b/2) * (cos(b/2), sin(b/2))
Enter fullscreen mode Exit fullscreen mode

The direction (cos b/2, sin b/2) never changes. Only the length 2r*cos(t - b/2) changes, so the point just slides along a fixed diameter. Space eight points 45 degrees apart on the small circle and you get eight lines 22.5 degrees apart.

Building it for a 3D printer

I wrote it in Python with manifold3d:

  • Body: a dial with 16 half-slots cut from the centre out, so all 8 diameters meet in an open centre window. The body prints face-down, so the slots are just holes in the first layers.
  • Disc: radius 17 mm, with 8 pegs on a 15 mm circle. Pegs ride in the slots with 0.4 mm clearance per side. No gears needed: the pegs in the slots fully constrain the disc (it is a trammel).
  • Floor and beads: the floor presses in under the disc, and beads glue onto the peg tips above the dial.

The motion is checked in code before printing: step the angle through a full turn and intersect every part with every other part.

for t in range(0, 360, 6):
    body, floor, disc, beads = assembled(t)
    hit = (body ^ disc).volume() + (body ^ beads).volume() + (disc ^ floor).volume()
    assert hit < 1e-6
Enter fullscreen mode Exit fullscreen mode

That came back zero at every step. The animation above is just that same function rendered frame by frame.

Tusi Couple Astrolabe

Styling

The dial borrows from astrolabes: 64 degree ticks, an eight-point star in every segment, a throne (kursi) with a hanging ring, and a sunburst on the disc that shows through the centre window.

The STL files are here if you want to print one: Tusi Couple Astrolabe on Cults3D.

Top comments (0)