Skip to content

Instantly share code, notes, and snippets.

@bbengfort
Last active August 16, 2023 06:03
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bbengfort/11183420 to your computer and use it in GitHub Desktop.
Save bbengfort/11183420 to your computer and use it in GitHub Desktop.
Draw an L-System with Python's turtle graphics library, where the L-System is defined with a turning angle (d) a line length (l) and an axiom in the using the characters 'F', 'f', '+', and '-' to indicate rules. You can also iterate the axiom for fractal like patterns.
#!/usr/bin/env python
import turtle
D = 90
L = 10
def iterate(axiom, num=0, initator='F'):
"""
Compute turtle rule string by iterating on an axiom
"""
def translate(current, axiom):
"""
Translate all the "F" with the axiom for current string
"""
result = ''
consts = {'+', '-', '[', ']'}
for c in current:
if c in consts:
result += c
continue
if c == 'F':
result += axiom
return result
# Set initator
result = initator
for i in xrange(0, num):
# For ever iteration, translate the rule string
result = translate(result, axiom)
return result
def draw(axiom, d=D, l=L):
"""
Use turtle to draw the L-System
"""
stack = [] # For tracking turtle positions
screen = turtle.Screen()
alex = turtle.Turtle()
alex.hideturtle() # Don't show the turtle
alex.speed(0) # Make the turtle faster
alex.left(90) # Point up instead of right
for i in xrange(len(axiom)):
c = axiom[i]
if c == 'F':
alex.forward(l)
if c == 'f':
alex.penup()
alex.forward(l)
alex.pendown()
if c == '+':
alex.left(d)
if c == '-':
alex.right(d)
if c == '[':
stack.append((alex.heading(), alex.pos()))
if c == ']':
heading, position = stack.pop()
alex.penup()
alex.goto(position)
alex.setheading(heading)
alex.pendown()
screen.onkey(screen.bye, 'q')
screen.listen()
turtle.mainloop()
if __name__ == '__main__':
axiom = "F-F+F+FF-F-F+F"
axiom = iterate(axiom, 3, "F-F-F-F")
draw(axiom, 90, 2)
@bbengfort
Copy link
Author

To draw the Koch curve:

axiom = "F+F--F+F"
axiom = iterate(axiom, 3, "F")
draw(axiom, 60, 10)

@bbengfort
Copy link
Author

Another class example:

axiom = "F[-F]F[+F]F"
axiom = iterate(axiom, 3, "F")
draw(axiom, 60, 10)

@njanakiev
Copy link

Thanks for sharing! A good resource on L-Systems are in the chapter (http://algorithmicbotany.org/papers/abop/abop-ch1.pdf) from the book "The Algorithmic Beauty of Plants".

@BrandedAlok xrange from Python 2.x is range in Python 3.x.

@secondstarter
Copy link

I am a novice to L-Systems..... Would appreciate greatly if someone explains me the meaning of the following part
if c == '[':
stack.append((alex.heading(), alex.pos()))

@secondstarter
Copy link

Now I understood it ..... Very nice idea to get back to the the previous position and direction ......

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