#!/usr/bin/env python3 """program to draw using a turtle and an L-system. See commands in loops below. multiple lines of input are allowed. Clicking on the display window or running out of input without a pause will terminate the program. """ from turtle import (Screen, Turtle) screen = Screen() def stopit(x, y) : """A call-back routine for button click on draw screen""" print("bye bye") quit() def openDraw() : """open a canvas to draw upon and return a turtle to draw with""" screen.setup(width, height) screen.bgcolor("black") screen.setworldcoordinates(-width//2, -height//2, width//2, height//2) screen.onclick(stopit) # click on window to end program screen.tracer(0, 0) # do this for speedier drawing! t = Turtle() t.pensize(3) t.pencolor("red") t.hideturtle() # hide the turtle return t # return the turtle # the colors colorlist = ["maroon", "red", "orange", "yellow", "greenyellow", "lime", "green", "turquoise", "royalblue", "blue", "blueviolet", "purple"] colorlen = len(colorlist) # globals defs = {} angle = 90 depthLimit = 3 scale = 1.0 shrinkRatio = .6108 size = 20 width = 1400; height = 1200 # stacks scales = [] positions = [] headings = [] pens = [] def runDraw(t, instructions) : """do the drawing using character based instructions""" global defs global colorlist, colorlen global angle, depthLimit, scale, shrinkRatio, size, width, height global positions, headings, scales, pens # default size of steps, headings, and changes in size addr = 0 depth = 0 while addr < len(instructions) : instr = instructions[addr] # process any MACRO CHARACTER that is defined as a replacement string # if the depth has reached the depthLimit then ignore the character if instr in defs : if depth < depthLimit : instructions = defs[instr] + '\\' + instructions[addr+1:] depth += 1 print(instructions) addr = -1 # internal use instruction to mark end of replacement text from a MACRO CHARACTER elif instr == '\\' : depth -= 1 # define a MACRO CHARACTER elif instr == '=' : name = instructions[addr+1] code = instructions[addr+2:] defs[name] = code print(defs) instructions = "" # consume all of the remaining instrutions on the line # go forward a step size elif instr == 'F' : t.forward(size*scale) # shrink the size of step size (shrinkRatio < 1) elif instr == '>' : scale *= shrinkRatio # increase the size of step size (shrinkRatio < 1) elif instr == '<' : scale /= shrinkRatio # turn left a turn increment elif instr == '+' : t.left(angle) # turn right a turn increment elif instr == '-' : t.right(angle) # remember step size, position, and heading of turtle on a stack elif instr == '[' : scales.append(scale) positions.append(t.pos()) headings.append(t.heading()) # pop the step size, position, and heading of turtle elif instr == ']' : scale = scales.pop() t.penup() t.goto(positions.pop()) t.setheading(headings.pop()) t.pendown() # set the angle elif instr == 'a' : angle = int(instructions[addr+1:]) instructions = "" # clear the turtle drawing cavas elif instr == 'c' : t.clear() # set the depthLimit elif instr == 'd' : depthLimit = int(instructions[addr+1:]) instructions = "" # reset the origin elif instr == 'o' : origin = instructions[addr+1:] instructions = "" print("O:", origin) # setworldcoordinates before ever drawing anything!! # lc=left side center, c=center, bc=bottom center, otherwise lower left if origin=="lc" : screen.setworldcoordinates(0, -height//2, width, height//2) elif origin=="lr" : screen.setworldcoordinates(-width, 0, 0, height) elif origin=="c" : screen.setworldcoordinates(-width//2, -height//2, width//2, height//2) elif origin=="bc" : screen.setworldcoordinates(-width//2, 0, width//2, height) elif origin=="tl" : screen.setworldcoordinates(0, -height, width, 0) else : screen.setworldcoordinates(0, 0, width, height) # pause to enjoy the drawing elif instr == 'p' : screen.mainloop() # quit the program elif instr == 'q' : quit() # set the proportion to set change the ratio of elif instr == 'r' : shrinkRatio = float(instructions[addr+1:]) instructions = "" # set the step size elif instr == 's' : size = int(instructions[addr+1:]) instructions = "" # ignore any character that is not known else : # if the instruction is not recognized then do nothing!!! pass addr += 1 def main() : t = openDraw() while True : runDraw(t, input("Command me:")) screen.update() # update the scree drawing here main()