Skip to content

Instantly share code, notes, and snippets.

@cormullion
Last active December 13, 2023 12:14
Show Gist options
  • Save cormullion/cf126eb3d247b9fa81f21295366733ea to your computer and use it in GitHub Desktop.
Save cormullion/cf126eb3d247b9fa81f21295366733ea to your computer and use it in GitHub Desktop.
rotating tape spools
using Luxor, Colors
function drawtape(spoolradius, separation, e)
@layer begin
# draw the 'tape' threading between the spools
# (e is normalized 0 to 1 for animation)
sr = spoolradius + 10 # outside spool, not realistic
spoolcenters = ngon(O, separation, 3, vertices = true)
top_point = Point(spoolcenters[2].x, spoolcenters[2].y - spoolradius - 10)
# top left spool
path1() = begin
move(top_point + (400, 0)) # come in from right
carc(spoolcenters[2], sr, 3π / 2, π / 3)
end
# middle right spool
path2() = begin
arc(spoolcenters[3], sr, 3π / 2 - π / 6, π - π / 3)
end
# bottom left spool
bottom_point = Point(spoolcenters[1].x, spoolcenters[1].y + spoolradius + 10)
path3() = begin
carc(spoolcenters[1], sr, 3π / 2 + π / 6, π / 2)
line(bottom_point + (400, 0)) # shoot off right
end
# paths will connect automatically
path1()
path2()
path3()
strokepath()
end
end
# e is eased_n, normalized duration bettween 0 and 1
function main(e;
clockwise = true,
darkmode = true,
backgroundcolor = "black")
translate(-25, 0)
scale(0.95)
spoolradius = 95
separation = 140 # distance between spool centers
pts = ngon(O, separation, 3, vertices = true) # spool centers
# draw spools
setline(3) # edging
# edging mostly useful for non-darkmode
for (n, pt) in enumerate(pts)
sethue([Luxor.julia_red, Luxor.julia_green, Luxor.julia_purple][mod1(n, end)])
circle(pt, spoolradius, :fillpreserve)
sethue("grey20")
strokepath()
@layer begin
translate(pt)
# [red green purple]
wheelrotation = (clockwise ? 1 : -1) * [1, 1, -1]
rotate(e * 2π * wheelrotation[n])
for i in 1:3
sethue(backgroundcolor)
sector(O, 30, spoolradius * 0.9, i * 2π / 3, (i * 2π / 3) + 2π / 6, 10.0, action = :fillpreserve)
# edging
sethue("grey20")
strokepath()
end
end
end
setline(darkmode ? 7 : 10) # "tape" thickness
sethue(darkmode ? "orange" : "grey20") # "tape" colour
drawtape(spoolradius, separation, e)
end
function frame(scene, framenumber)
darkmode = true
squircle(O, 245, 245, :clip, rt = 0.3)
backgroundcolor = darkmode ? "black" : HSB(120, 0.1, 0.9)
background(backgroundcolor)
eased_n = scene.easingfunction(framenumber - scene.framerange.start,
0, 1, (scene.framerange.stop + 1) - scene.framerange.start)
main(eased_n, clockwise = false, darkmode = darkmode, backgroundcolor = "black")
end
function animation()
mpitape = Movie(500, 500, "mpitape")
animate(mpitape, [
Scene(mpitape, frame, 1:40),
],
framerate = 24,
pathname = "/tmp/mpitape.gif",
creategif = true)
end
animation()
@cormullion
Copy link
Author

mpitape

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment