
# fractals.py

'''
  sierpinski input: 3 or 4
  dragon input: 6 or 7
  levy input: 7 or 8
  koch input: 3 or 4
  minkowski input: 2 or 3
'''

import turtle, random, math
from TurtleUtils import *

START_SIZE = 200


def sierpinski(t, size, level):
  if level < 1:
    t.left(60)
    drawTriangle(t, size, "blue")
    t.right(60)
  else:
    sierpinski(t, size/2.0, level-1)
    t.left(60)
    t.fd(size/2.0)
    t.right(60)
    sierpinski(t, size/2.0, level-1)
    t.left(60)
    t.bk(size/2.0)
    t.right(60)
    t.fd(size/2.0)
    sierpinski(t, size/2.0, level-1)
    t.bk(size/2.0)



def dragon(t, size, level, dir):
  """ The Dragon Curve
  http://en.wikipedia.org/wiki/Dragon_curve
  """
  if level < 1:
    t.down()
    t.right(dir*45)
    t.fd(size)
    t.left(dir*90)
    t.fd(size)
    t.right(dir*45)
  else:
    t.down()
    t.right(dir*45)
    dragon(t, size/math.sqrt(2), level-1, 1)
    t.left(dir*90)
    dragon(t, size/math.sqrt(2), level-1, -1)
    t.right(dir*45)



def levy(t, size, level):
  """ The Levy C-Curve fractal
  http://en.wikipedia.org/wiki/C-curve
  """
  if level < 1:
    t.fd(size)
  else:
    t.left(45)
    levy(t, size/2.0, level-1)
    t.right(90)
    levy(t, size/2.0, level-1)
    t.left(45)



def koch(t, size, level):
  for _ in range(3):
    kochSide(t, size, level)
    t.right(120)

def kochSide(t, size, level):
  if level < 1:
    t.fd(size)
  else:
    for angle in [60, -120, 60, 0]:
      kochSide(t, size/3, level-1)
      t.left(angle)



def minkowskiIsland(t, size, level):
  for _ in range(4):
    minkowski(t, size, level)
    t.left(90)


def minkowski(t, size, level):
  if level < 1:
    t.fd(size)
  else:
    for angle in [90,-90,-90, 0, 90, 90,-90, 0]:
      minkowski(t, size/4, level-1)
      t.left(angle)
  



# ----------------------- main ---------------------------

type = input("s, d, l, k, or m? ").lower().strip()[0]
level = int(input("level? "))

t = turtle.Turtle()
scr = t.screen
scr.title('Fractals')
t.hideturtle()
t.speed(0)

if type == "s":
  sierpinski(t, START_SIZE, level)
elif type == "d":
  dragon(t, START_SIZE, level, 1)
elif type == "l":
  levy(t, START_SIZE*level, level)
elif type == "k":
  koch(t, START_SIZE, level)
elif type == "m":
  minkowskiIsland(t, START_SIZE, level)
else:
  print("Unknown type", type)

scr.exitonclick()
