|
1 #!/usr/bin/python |
|
2 """ xturtle-example-suite: |
|
3 |
|
4 xtx_kites_and_darts.py |
|
5 |
|
6 Constructs two aperiodic penrose-tilings, |
|
7 consisting of kites and darts, by the method |
|
8 of inflation in six steps. |
|
9 |
|
10 Starting points are the patterns "sun" |
|
11 consisting of five kites and "star" |
|
12 consisting of five darts. |
|
13 |
|
14 For more information see: |
|
15 http://en.wikipedia.org/wiki/Penrose_tiling |
|
16 ------------------------------------------- |
|
17 """ |
|
18 from turtle import * |
|
19 from math import cos, pi |
|
20 from time import clock, sleep |
|
21 |
|
22 f = (5**0.5-1)/2.0 # (sqrt(5)-1)/2 -- golden ratio |
|
23 d = 2 * cos(3*pi/10) |
|
24 |
|
25 def kite(l): |
|
26 fl = f * l |
|
27 lt(36) |
|
28 fd(l) |
|
29 rt(108) |
|
30 fd(fl) |
|
31 rt(36) |
|
32 fd(fl) |
|
33 rt(108) |
|
34 fd(l) |
|
35 rt(144) |
|
36 |
|
37 def dart(l): |
|
38 fl = f * l |
|
39 lt(36) |
|
40 fd(l) |
|
41 rt(144) |
|
42 fd(fl) |
|
43 lt(36) |
|
44 fd(fl) |
|
45 rt(144) |
|
46 fd(l) |
|
47 rt(144) |
|
48 |
|
49 def inflatekite(l, n): |
|
50 if n == 0: |
|
51 px, py = pos() |
|
52 h, x, y = int(heading()), round(px,3), round(py,3) |
|
53 tiledict[(h,x,y)] = True |
|
54 return |
|
55 fl = f * l |
|
56 lt(36) |
|
57 inflatedart(fl, n-1) |
|
58 fd(l) |
|
59 rt(144) |
|
60 inflatekite(fl, n-1) |
|
61 lt(18) |
|
62 fd(l*d) |
|
63 rt(162) |
|
64 inflatekite(fl, n-1) |
|
65 lt(36) |
|
66 fd(l) |
|
67 rt(180) |
|
68 inflatedart(fl, n-1) |
|
69 lt(36) |
|
70 |
|
71 def inflatedart(l, n): |
|
72 if n == 0: |
|
73 px, py = pos() |
|
74 h, x, y = int(heading()), round(px,3), round(py,3) |
|
75 tiledict[(h,x,y)] = False |
|
76 return |
|
77 fl = f * l |
|
78 inflatekite(fl, n-1) |
|
79 lt(36) |
|
80 fd(l) |
|
81 rt(180) |
|
82 inflatedart(fl, n-1) |
|
83 lt(54) |
|
84 fd(l*d) |
|
85 rt(126) |
|
86 inflatedart(fl, n-1) |
|
87 fd(l) |
|
88 rt(144) |
|
89 |
|
90 def draw(l, n, th=2): |
|
91 clear() |
|
92 l = l * f**n |
|
93 shapesize(l/100.0, l/100.0, th) |
|
94 for k in tiledict: |
|
95 h, x, y = k |
|
96 setpos(x, y) |
|
97 setheading(h) |
|
98 if tiledict[k]: |
|
99 shape("kite") |
|
100 color("black", (0, 0.75, 0)) |
|
101 else: |
|
102 shape("dart") |
|
103 color("black", (0.75, 0, 0)) |
|
104 stamp() |
|
105 |
|
106 def sun(l, n): |
|
107 for i in range(5): |
|
108 inflatekite(l, n) |
|
109 lt(72) |
|
110 |
|
111 def star(l,n): |
|
112 for i in range(5): |
|
113 inflatedart(l, n) |
|
114 lt(72) |
|
115 |
|
116 def makeshapes(): |
|
117 tracer(0) |
|
118 begin_poly() |
|
119 kite(100) |
|
120 end_poly() |
|
121 register_shape("kite", get_poly()) |
|
122 begin_poly() |
|
123 dart(100) |
|
124 end_poly() |
|
125 register_shape("dart", get_poly()) |
|
126 tracer(1) |
|
127 |
|
128 def start(): |
|
129 reset() |
|
130 ht() |
|
131 pu() |
|
132 makeshapes() |
|
133 resizemode("user") |
|
134 |
|
135 def test(l=200, n=4, fun=sun, startpos=(0,0), th=2): |
|
136 global tiledict |
|
137 goto(startpos) |
|
138 setheading(0) |
|
139 tiledict = {} |
|
140 a = clock() |
|
141 tracer(0) |
|
142 fun(l, n) |
|
143 b = clock() |
|
144 draw(l, n, th) |
|
145 tracer(1) |
|
146 c = clock() |
|
147 print "Calculation: %7.4f s" % (b - a) |
|
148 print "Drawing: %7.4f s" % (c - b) |
|
149 print "Together: %7.4f s" % (c - a) |
|
150 nk = len([x for x in tiledict if tiledict[x]]) |
|
151 nd = len([x for x in tiledict if not tiledict[x]]) |
|
152 print "%d kites and %d darts = %d pieces." % (nk, nd, nk+nd) |
|
153 |
|
154 def demo(fun=sun): |
|
155 start() |
|
156 for i in range(8): |
|
157 a = clock() |
|
158 test(300, i, fun) |
|
159 b = clock() |
|
160 t = b - a |
|
161 if t < 2: |
|
162 sleep(2 - t) |
|
163 |
|
164 def main(): |
|
165 #title("Penrose-tiling with kites and darts.") |
|
166 mode("logo") |
|
167 bgcolor(0.3, 0.3, 0) |
|
168 demo(sun) |
|
169 sleep(2) |
|
170 demo(star) |
|
171 pencolor("black") |
|
172 goto(0,-200) |
|
173 pencolor(0.7,0.7,1) |
|
174 write("Please wait...", |
|
175 align="center", font=('Arial Black', 36, 'bold')) |
|
176 test(600, 8, startpos=(70, 117)) |
|
177 return "Done" |
|
178 |
|
179 if __name__ == "__main__": |
|
180 msg = main() |
|
181 mainloop() |