Skip to content

Instantly share code, notes, and snippets.

@justvanrossum
Last active February 14, 2018 00:09
Show Gist options
  • Save justvanrossum/f3cd70f2f378553c9351 to your computer and use it in GitHub Desktop.
Save justvanrossum/f3cd70f2f378553c9351 to your computer and use it in GitHub Desktop.
DrawBot: Emulate some of Marcel Duchamp's Rotoreliefs.
# An interpretation of Marcel Duchamp's Rotoreliefs, as seen in his 1926 movie Anemic Cinema:
# https://www.youtube.com/watch?v=dXINTf8kXCc
def circle(pt, radius):
diameter = 2 * radius
x, y = pt
oval(x - radius, y - radius, diameter, diameter)
canvasSize = 500
nFrames = 64 # 64
# main parameters
nCircles = 17 # should be odd
turns = 2 # should be an int > 0
skipOdd = False # if True, don't move the "odd" circles
# nCircles = 17; turns = 2; evenOdd = False
# http://dailydrawbot.tumblr.com/post/136530684599/rotorelief-1-after-marcel-duchamps-anémic
# nCircles = 15; turns = 1; evenOdd = True
# http://dailydrawbot.tumblr.com/ # coming soon!
# secondary parameters
baseAngle = 360 / (nCircles - 1)
angleIncrement = -radians(baseAngle * turns)
if skipOdd:
angleIncrement *= 2
startRadius = 0.95 * canvasSize/2
stepSize = startRadius / nCircles
smaller = 0.8
for frame in range(nFrames):
framePhase = frame / nFrames
newPage(canvasSize, canvasSize)
frameDuration(1/20)
rect(0, 0, canvasSize, canvasSize) # background
save()
translate(canvasSize/2, canvasSize/2) # put origin at center
rotate(-360 * framePhase) # just rotate the entire drawing
radius = startRadius
angle = 0
x = y = 0
for i in range(nCircles):
fill(1 - i % 2)
circle((x, y), radius)
if not skipOdd or i % 2:
x += smaller * stepSize * cos(angle)
y += smaller * stepSize * sin(angle)
angle += angleIncrement
radius -= stepSize
restore()
if nFrames > 10:
fn = "RotoRelief-%s-%s-%s" % (nCircles, turns, skipOdd)
saveImage(fn + ".gif")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment