Снежинка Коха (JavaScript)
Материал из Department of Theoretical and Applied Mechanics
Содержание
Авторы
Смирнова Ирина
Нежинская Лилия
Описание
Снежинка Коха - фрактал, который получается из трех копий кривой Коха. Интересно то, что данная кривая имеет бесконечную длину, непрерывна, но нигде не дифференцируема.
Визуализация
Код программы
Код программы на языке JavaScript:
1 <html>
2
3 <head>
4 <style>
5 canvas {border: 4px black solid}
6 </style>
7 <title> Snowflake Koch</title>
8 </head>
9
10 <body>
11 <h1> Snowflake Koch</h1>
12 <canvas id='canvas' ></canvas>
13
14
15 <script>
16 var CanvasBody = document.getElementById("canvas"),
17 canvas = CanvasBody.getContext("2d"),
18 width = CanvasBody.width = window.innerWidth - 20,
19 height = CanvasBody.height = window.innerHeight - 100,
20 timedist = 100;
21 canvas.translate(.5 * width, .5 * height);
22 if (width < height){
23
24 height = width;
25 }
26 let crdx = [];
27 let crdy = [];
28 var scl = 1;
29 var r;
30
31 function coordtriang()
32 {
33 var a = height/2,
34 h = a*Math.sin(Math.PI/3),
35 x1 = 0,
36 y1 = -(2*h/3),
37 x2 = Math.trunc(a/2),
38 y2 = (h/3),
39 dx = Math.abs(x1 - x2),
40 dy = Math.abs(y1 - y2),
41 dist = Math.sqrt(dx * dx + dy * dy),
42 angle = Math.atan2(dy, dx);
43 x3 = x1 + Math.cos(angle + Math.PI / 3) * dist,
44 y3 = y1 + Math.sin(angle + Math.PI / 3) * dist;
45 return [x1,y1,x2,y2,x3,y3];
46 }
47
48 function crdcalc(x1,y1,x2,y2,r)
49 {
50 crdx[r] = x1;
51 crdy[r] = y1;
52 crdx[r+1] = (2*x1+x2)/3;
53 crdy[r+1] = (2*y1+y2)/3;
54 crdx[r+2] = (x1+x2)/2 - (y1-y2)/(2*Math.sqrt(3));
55 crdy[r+2] = (y1+y2)/2 - (x2-x1)/(2*Math.sqrt(3));
56 crdx[r+3] = (2*x2+x1)/3;
57 crdy[r+3] = (2*y2+y1)/3;
58 crdx[r+4] = x2;
59 crdy[r+4] = y2;
60
61
62 }
63
64
65 function koch(n)
66 {
67
68
69 crdcalc(coordtriang()[0],coordtriang()[1],coordtriang()[2],coordtriang()[3],0);
70 crdcalc(coordtriang()[2],coordtriang()[3],coordtriang()[4],coordtriang()[5],4);
71 crdcalc(coordtriang()[4],coordtriang()[5],coordtriang()[0],coordtriang()[1],8);
72
73 let crdx_t = new Array();
74 let crdy_t = new Array();
75
76
77 for(var j=0; j<n; j++)
78 {
79 crdx_t = [];
80 crdy_t = [];
81 r = 3*Math.pow(4,j+1);
82 for(var i=0; i<=r; i++)
83 {
84 crdx_t[i] = crdx[i];
85 crdy_t[i] = crdy[i];
86 }
87 for(var i=0; i<r; i++)
88 {
89 crdcalc(crdx_t[i],crdy_t[i],crdx_t[i+1],crdy_t[i+1],4*i);
90 }
91
92
93 }
94
95
96
97 }
98
99
100 function sm(x1,y1,x2,y2,k,smooth)
101 {
102 var xxs = (x1+x2)/2,
103 yys = (y1+y2)/2,
104 dx = x2 - x1,
105 dy = y2 - y1,
106 dist = Math.sqrt(dx * dx + dy * dy),
107 angle = Math.atan2(dy, dx);
108 x3 = x1 + Math.cos(angle + Math.PI / 3) * dist,
109 y3 = y1 + Math.sin(angle + Math.PI / 3) * dist;
110
111 if (k < smooth)
112 {
113 var xm = (xxs-x3)*k/3/smooth+xxs,
114 ym = (yys-y3)*k/3/smooth+yys;
115 return [xm,ym];
116 }
117 else
118 {
119 return [Math.abs((4*xxs-x3)/3),Math.abs((4*yys-y3)/3)];
120 }
121
122 }
123
124 function centr(x1,y1,x2,y2)
125 {
126 var xxs = (x1+x2)/2,
127 yys = (y1+y2)/2,
128 dx = x2 - x1,
129 dy = y2 - y1,
130 dist = Math.sqrt(dx * dx + dy * dy),
131 angle = Math.atan2(dy, dx);
132 x3 = x1 + Math.cos(angle + Math.PI / 3) * dist,
133 y3 = y1 + Math.sin(angle + Math.PI / 3) * dist;
134 return[x3, y3];
135 }
136
137
138 function drw2(n, k, smooth)
139 {
140
141
142 koch(n)
143
144
145 //var i = 10;
146
147 for(var i = 2; i<crdx.length-2; i=i+4)
148 {
149 crdx[i] =sm(crdx[i-2],crdy[i-2],crdx[i+2],crdy[i+2],k,smooth)[0];
150 crdy[i] =sm(crdx[i-2],crdy[i-2],crdx[i+2],crdy[i+2],k,smooth)[1];
151
152 }
153
154 canvas.clearRect(-width/2,-height/2,width,height);
155 canvas.beginPath();
156 canvas.strokeStyle = "black";
157 canvas.lineWidth = 1;
158
159 if(n==-1)
160 {
161 canvas.moveTo(crdx[0],crdy[0]);
162 canvas.lineTo(crdx[4],crdy[4]);
163 canvas.lineTo(crdx[8],crdy[8]);
164 canvas.lineTo(crdx[0],crdy[0]);
165 }
166 else{
167 canvas.moveTo(crdx[0],crdy[0]);
168 for(var i=0; i<crdx.length;i++)
169 {
170 canvas.lineTo(crdx[i+1],crdy[i+1]);
171 }}
172 canvas.stroke();
173 canvas.closePath();
174
175
176
177 }
178
179
180 var t = -1,
181 k_t = 0,
182 smooth = 10,
183 order = 3;
184 //console.log(crdx);
185
186 function loop() {
187 if(t <= order){
188 drw2(t, k_t, smooth);
189 //canvas.clearRect(-width/2,-height/2,width/2,height/2);
190 k_t++;
191 console.log(k_t)
192 if(k_t == smooth)
193 {
194 k_t = 0;
195 t++;
196 //
197 }
198 if (t==order+1) {
199 setTimeout(()=>{document.location.reload()}, 2000)
200 }
201 }
202 //else{
203 //canvas.font = "48px Verdana";
204 //var text = "Koch Snowflake"
205 //canvas.fillStyle = "orange";
206 //canvas.fillText(text, -canvas.measureText(text).width/2, Math.trunc(height / 3));
207 //}
208 }
209
210 setInterval(loop,timedist);
211
212
213 </script>
214 </body>
215 </html>
216
217
218 document.onkeydown=keyControl;