1 #!/usr/bin/env python3 2 """ turtle-example-suite: 3 4 tdemo_fractalCurves.py 5 6 This program draws two fractal-curve-designs: 7 (1) A hilbert curve (in a box) 8 (2) A combination of Koch-curves. 9 10 The CurvesTurtle class and the fractal-curve- 11 methods are taken from the PythonCard example 12 scripts for turtle-graphics. 13 """ 14 from turtle import * 15 from time import sleep, clock 16 17 class CurvesTurtle(Pen): 18 # example derived from 19 # Turtle Geometry: The Computer as a Medium for Exploring Mathematics 20 # by Harold Abelson and Andrea diSessa 21 # p. 96-98 22 def hilbert(self, size, level, parity): 23 if level == 0: 24 return 25 # rotate and draw first subcurve with opposite parity to big curve 26 self.left(parity * 90) 27 self.hilbert(size, level - 1, -parity) 28 # interface to and draw second subcurve with same parity as big curve 29 self.forward(size) 30 self.right(parity * 90) 31 self.hilbert(size, level - 1, parity) 32 # third subcurve 33 self.forward(size) 34 self.hilbert(size, level - 1, parity) 35 # fourth subcurve 36 self.right(parity * 90) 37 self.forward(size) 38 self.hilbert(size, level - 1, -parity) 39 # a final turn is needed to make the turtle 40 # end up facing outward from the large square 41 self.left(parity * 90) 42 43 # Visual Modeling with Logo: A Structural Approach to Seeing 44 # by James Clayson 45 # Koch curve, after Helge von Koch who introduced this geometric figure in 1904 46 # p. 146 47 def fractalgon(self, n, rad, lev, dir): 48 import math 49 50 # if dir = 1 turn outward 51 # if dir = -1 turn inward 52 edge = 2 * rad * math.sin(math.pi / n) 53 self.pu() 54 self.fd(rad) 55 self.pd() 56 self.rt(180 - (90 * (n - 2) / n)) 57 for i in range(n): 58 self.fractal(edge, lev, dir) 59 self.rt(360 / n) 60 self.lt(180 - (90 * (n - 2) / n)) 61 self.pu() 62 self.bk(rad) 63 self.pd() 64 65 # p. 146 66 def fractal(self, dist, depth, dir): 67 if depth < 1: 68 self.fd(dist) 69 return 70 self.fractal(dist / 3, depth - 1, dir) 71 self.lt(60 * dir) 72 self.fractal(dist / 3, depth - 1, dir) 73 self.rt(120 * dir) 74 self.fractal(dist / 3, depth - 1, dir) 75 self.lt(60 * dir) 76 self.fractal(dist / 3, depth - 1, dir) 77 78 def main(): 79 ft = CurvesTurtle() 80 81 ft.reset() 82 ft.speed(0) 83 ft.ht() 84 ft.getscreen().tracer(1,0) 85 ft.pu() 86 87 size = 6 88 ft.setpos(-33*size, -32*size) 89 ft.pd() 90 91 ta=clock() 92 ft.fillcolor("red") 93 ft.begin_fill() 94 ft.fd(size) 95 96 ft.hilbert(size, 6, 1) 97 98 # frame 99 ft.fd(size) 100 for i in range(3): 101 ft.lt(90) 102 ft.fd(size*(64+i%2)) 103 ft.pu() 104 for i in range(2): 105 ft.fd(size) 106 ft.rt(90) 107 ft.pd() 108 for i in range(4): 109 ft.fd(size*(66+i%2)) 110 ft.rt(90) 111 ft.end_fill() 112 tb=clock() 113 res = "Hilbert: %.2fsec. " % (tb-ta) 114 115 sleep(3) 116 117 ft.reset() 118 ft.speed(0) 119 ft.ht() 120 ft.getscreen().tracer(1,0) 121 122 ta=clock() 123 ft.color("black", "blue") 124 ft.begin_fill() 125 ft.fractalgon(3, 250, 4, 1) 126 ft.end_fill() 127 ft.begin_fill() 128 ft.color("red") 129 ft.fractalgon(3, 200, 4, -1) 130 ft.end_fill() 131 tb=clock() 132 res += "Koch: %.2fsec." % (tb-ta) 133 return res 134 135 if __name__ == '__main__': 136 msg = main() 137 print(msg) 138 mainloop() 139