""" koch_zelle.py Problem 8, pg 64 in Zelle's Python Programming text : Use a Turtle class to draw a recursive Koch curve fractal. Jim M | GPL | Nov 2010 """ from graphics import GraphWin, Point, Line from math import pi, sin, cos class Turtle: """ A Turtle is a graphics abstraction; see wikipedia's "Turtle Graphics" article for a description. This one is based on Zelle's graphics.py module. For example, this is how you could draw a square : t = Turtle() # create a window and turtle for side in range(4): # four sides of square : t.move(10) # draw a line that's 10 units long t.turn(90) # turn 90 degrees """ degrees2radians = pi / 180.0 # conversion factor def __init__(self, windowSize = (400, 400), position = (200, 200), direction = 0.0): """ Turtle initialization optional parameters : windowSize = window size in pixels position = (x,y) initial turtle position; (0,0) is bottom left direction = initial orientation of turtle; 0.0 is eastwards """ self.window = GraphWin('Turtle', windowSize[0], windowSize[1]) self.window.setCoords(0, 0, windowSize[0], windowSize[1]) self._penDown = True self.position = position self.direction = direction def penUp(self): """ Set turtle's pen up; i.e. move doesn't draw """ self._penDown = False def penDown(self): """ Set turtle's pen down; i.e. move does draw """ self._penDown = True def turn(self, degrees): """ Rotate the direction that the turtle is facing. """ self.direction += degrees def move(self, distance): """ Move the given distance in the direction the turtle is facing, drawing a line if the pen is down. """ x0 = self.position[0] y0 = self.position[1] x1 = x0 + distance * cos(Turtle.degrees2radians * self.direction) y1 = y0 + distance * sin(Turtle.degrees2radians * self.direction) if self._penDown: Line(Point(x0,y0), Point(x1,y1)).draw(self.window) self.position = (x1, y1) def square(self, length): """ Draw a square with a turtle. """ for i in range(4): self.move(length) self.turn(90) def koch(self, length, recursionDepth): """ Recursively draw a Koch curve. """ if recursionDepth == 0: self.move(length) else: for angle in (0.0, 60.0, -120.0, 60.0): self.turn(angle) self.koch(length/3.0, recursionDepth - 1) def main(): turtle = Turtle(position=(10,10)) turtle.koch(380, 4) wait = input('quit? ') main()