|
1 #!/usr/bin/python |
|
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.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.fill(True) |
|
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.fill(False) |
|
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.tracer(1,0) |
|
121 |
|
122 ta=clock() |
|
123 ft.color("black", "blue") |
|
124 ft.fill(True) |
|
125 ft.fractalgon(3, 250, 4, 1) |
|
126 ft.fill(True) |
|
127 ft.color("red") |
|
128 ft.fractalgon(3, 200, 4, -1) |
|
129 ft.fill(False) |
|
130 tb=clock() |
|
131 res += "Koch: %.2fsec." % (tb-ta) |
|
132 return res |
|
133 |
|
134 if __name__ == '__main__': |
|
135 msg = main() |
|
136 print msg |
|
137 mainloop() |