"""
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()