Skip to content

Instantly share code, notes, and snippets.

@AnthonyBriggs
Created January 30, 2018 02:49
Show Gist options
  • Save AnthonyBriggs/0072252ba7a6252a41deba3bbb4e9e19 to your computer and use it in GitHub Desktop.
Save AnthonyBriggs/0072252ba7a6252a41deba3bbb4e9e19 to your computer and use it in GitHub Desktop.
A fractal turtle L-system thing
"""Fancy turtle L-system thing
Messing around at lunchtime :)
Inspired by https://bitaesthetics.com/posts/fractal-generation-with-l-systems.html"""
# Maybe this runs under Python 2? Who knows? Not sure what the turtle
# changes between 2 and 3 are
from __future__ import print_function
dawg = "Yo dawg, I heard you like fractals, so I put a fractal on your fractal so you can fractal while you fractal"
dawg_bit = "put a fractal on your fractal so you can fractal while you fractal"
new_dawg = dawg.replace("fractal", dawg_bit)
for i in range(2):
new_dawg = new_dawg.replace("fractal", dawg_bit)
print(new_dawg)
import turtle
def set_up():
# Length constant
LENGTH = 250
turtle.clear()
turtle.screensize(LENGTH*4, LENGTH*4)
# center square on the middle of the screen
turtle.penup()
turtle.goto(LENGTH, -LENGTH)
turtle.pendown()
turtle.setheading(180) # face west/left
#turtle.delay(1) # go fast
#turtle.delay(0.1) # go really fast
turtle.delay(0) # go really really fast
return LENGTH
LENGTH = setup()
def interpret(command):
"""Given a string command like "F100" or "R90", make the turtle do its thing.
Handles lists of commands (and lists-of-lists, etc.)"""
if type(command) == list:
return [interpret(c) for c in command]
if command[0].lower() not in "fblrz":
# "comment/debug"
return
number = float(command[1:])
do = command[0].lower()
#print(command, "==>", do, number, type(number))
if do == 'f':
turtle.forward(number)
if do == 'z': # immutable forward command
turtle.pencolor("red")
turtle.forward(number)
turtle.pencolor("black")
if do == 'b':
turtle.back(number)
if do == 'l':
turtle.left(number)
if do == 'r':
turtle.right(number)
def complexify_square(command):
"""Make a command more fractalish (squares)"""
# handle lists of commands (and lists-of-lists, etc.)
if type(command) == list:
return [complexify_square(c) for c in command]
if command[0].lower() not in "fblrz":
# "comment/debug", but don't eat it
return [command]
number = float(command[1:])
do = command[0].lower()
if do == 'f':
# turn forward into a square zig-zag
# ==> _
# __ | |_
half = number / 2.0
do_bit = "f" + str(half)
return ["l90", do_bit, "r90", do_bit, "r90", do_bit, "l90", "z"+str(half), "-"]
else:
return [do+str(number)]
### dodecagon
#turtle_commands = ["F250", "R30.0"] * 12
#print(turtle_commands)
#
#for each_command in turtle_commands:
# interpret(each_command)
### square
#turtle_commands = ["F500", "R90.0"] * 4
#print(turtle_commands)
#
#for each_command in turtle_commands:
# interpret(each_command)
### old style, manually pulling/flattening commands from result
### (That's the `new_commands += ....` bit)
"""
commands = ["F"+str(LENGTH), "R90"]
for i in range(10):
new_commands = []
for command in commands:
new_commands += complexify_square(command)
commands = new_commands
print(' '.join(commands))
for i in range(4):
for each_command in commands:
interpret(each_command)
"""
### New, can-handle-nested-lists style
commands = ["F"+str(LENGTH), "R90"]
# only go until length < 1.0 (it's too small to see after this)
length = LENGTH
while 1:
new_commands = []
for command in commands:
new_commands += complexify_square(command)
commands = new_commands
length = length / 2.0
if length < 1.0:
# now print, and exit the loop
# print(commands)
print(len(commands),"commands created, length is", length)
interpret(commands)
### Wheee, dodecagon fractal square
"""
commands = ["F"+str(LENGTH/3), "R30"]
for i in range(12):
new_commands = []
for command in commands:
new_commands += complexify_square(command)
commands = new_commands
interpret(commands)
"""
ignored = input("Hit enter to exit")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment