Снежинка Коха (JavaScript) — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
(не показана 1 промежуточная версия этого же участника) | |||
Строка 1: | Строка 1: | ||
==Авторы== | ==Авторы== | ||
− | [[ | + | [[Смирнова Ирина|Смирнова Ирина]] |
<br /> | <br /> | ||
[[Нежинская Лилия|Нежинская Лилия]] | [[Нежинская Лилия|Нежинская Лилия]] | ||
Строка 11: | Строка 11: | ||
==Визуализация== | ==Визуализация== | ||
{{ #widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Smirnova/koch2_smooth.html | width=800 | height=800 | border=0 }} | {{ #widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Smirnova/koch2_smooth.html | width=800 | height=800 | border=0 }} | ||
+ | |||
+ | ==Код программы== | ||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | '''Код программы на языке JavaScript:''' <div class="mw-collapsible-content"> | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | |||
+ | <html> | ||
+ | |||
+ | <head> | ||
+ | <style> | ||
+ | canvas {border: 4px black solid} | ||
+ | </style> | ||
+ | <title> Snowflake Koch</title> | ||
+ | </head> | ||
+ | |||
+ | <body> | ||
+ | <h1> Snowflake Koch</h1> | ||
+ | <canvas id='canvas' ></canvas> | ||
+ | |||
+ | |||
+ | <script> | ||
+ | var CanvasBody = document.getElementById("canvas"), | ||
+ | canvas = CanvasBody.getContext("2d"), | ||
+ | width = CanvasBody.width = window.innerWidth - 20, | ||
+ | height = CanvasBody.height = window.innerHeight - 100, | ||
+ | timedist = 100; | ||
+ | canvas.translate(.5 * width, .5 * height); | ||
+ | if (width < height){ | ||
+ | |||
+ | height = width; | ||
+ | } | ||
+ | let crdx = []; | ||
+ | let crdy = []; | ||
+ | var scl = 1; | ||
+ | var r; | ||
+ | |||
+ | function coordtriang() | ||
+ | { | ||
+ | var a = height/2, | ||
+ | h = a*Math.sin(Math.PI/3), | ||
+ | x1 = 0, | ||
+ | y1 = -(2*h/3), | ||
+ | x2 = Math.trunc(a/2), | ||
+ | y2 = (h/3), | ||
+ | dx = Math.abs(x1 - x2), | ||
+ | dy = Math.abs(y1 - y2), | ||
+ | dist = Math.sqrt(dx * dx + dy * dy), | ||
+ | angle = Math.atan2(dy, dx); | ||
+ | x3 = x1 + Math.cos(angle + Math.PI / 3) * dist, | ||
+ | y3 = y1 + Math.sin(angle + Math.PI / 3) * dist; | ||
+ | return [x1,y1,x2,y2,x3,y3]; | ||
+ | } | ||
+ | |||
+ | function crdcalc(x1,y1,x2,y2,r) | ||
+ | { | ||
+ | crdx[r] = x1; | ||
+ | crdy[r] = y1; | ||
+ | crdx[r+1] = (2*x1+x2)/3; | ||
+ | crdy[r+1] = (2*y1+y2)/3; | ||
+ | crdx[r+2] = (x1+x2)/2 - (y1-y2)/(2*Math.sqrt(3)); | ||
+ | crdy[r+2] = (y1+y2)/2 - (x2-x1)/(2*Math.sqrt(3)); | ||
+ | crdx[r+3] = (2*x2+x1)/3; | ||
+ | crdy[r+3] = (2*y2+y1)/3; | ||
+ | crdx[r+4] = x2; | ||
+ | crdy[r+4] = y2; | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | function koch(n) | ||
+ | { | ||
+ | |||
+ | |||
+ | crdcalc(coordtriang()[0],coordtriang()[1],coordtriang()[2],coordtriang()[3],0); | ||
+ | crdcalc(coordtriang()[2],coordtriang()[3],coordtriang()[4],coordtriang()[5],4); | ||
+ | crdcalc(coordtriang()[4],coordtriang()[5],coordtriang()[0],coordtriang()[1],8); | ||
+ | |||
+ | let crdx_t = new Array(); | ||
+ | let crdy_t = new Array(); | ||
+ | |||
+ | |||
+ | for(var j=0; j<n; j++) | ||
+ | { | ||
+ | crdx_t = []; | ||
+ | crdy_t = []; | ||
+ | r = 3*Math.pow(4,j+1); | ||
+ | for(var i=0; i<=r; i++) | ||
+ | { | ||
+ | crdx_t[i] = crdx[i]; | ||
+ | crdy_t[i] = crdy[i]; | ||
+ | } | ||
+ | for(var i=0; i<r; i++) | ||
+ | { | ||
+ | crdcalc(crdx_t[i],crdy_t[i],crdx_t[i+1],crdy_t[i+1],4*i); | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | function sm(x1,y1,x2,y2,k,smooth) | ||
+ | { | ||
+ | var xxs = (x1+x2)/2, | ||
+ | yys = (y1+y2)/2, | ||
+ | dx = x2 - x1, | ||
+ | dy = y2 - y1, | ||
+ | dist = Math.sqrt(dx * dx + dy * dy), | ||
+ | angle = Math.atan2(dy, dx); | ||
+ | x3 = x1 + Math.cos(angle + Math.PI / 3) * dist, | ||
+ | y3 = y1 + Math.sin(angle + Math.PI / 3) * dist; | ||
+ | |||
+ | if (k < smooth) | ||
+ | { | ||
+ | var xm = (xxs-x3)*k/3/smooth+xxs, | ||
+ | ym = (yys-y3)*k/3/smooth+yys; | ||
+ | return [xm,ym]; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | return [Math.abs((4*xxs-x3)/3),Math.abs((4*yys-y3)/3)]; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | function centr(x1,y1,x2,y2) | ||
+ | { | ||
+ | var xxs = (x1+x2)/2, | ||
+ | yys = (y1+y2)/2, | ||
+ | dx = x2 - x1, | ||
+ | dy = y2 - y1, | ||
+ | dist = Math.sqrt(dx * dx + dy * dy), | ||
+ | angle = Math.atan2(dy, dx); | ||
+ | x3 = x1 + Math.cos(angle + Math.PI / 3) * dist, | ||
+ | y3 = y1 + Math.sin(angle + Math.PI / 3) * dist; | ||
+ | return[x3, y3]; | ||
+ | } | ||
+ | |||
+ | |||
+ | function drw2(n, k, smooth) | ||
+ | { | ||
+ | |||
+ | |||
+ | koch(n) | ||
+ | |||
+ | |||
+ | //var i = 10; | ||
+ | |||
+ | for(var i = 2; i<crdx.length-2; i=i+4) | ||
+ | { | ||
+ | crdx[i] =sm(crdx[i-2],crdy[i-2],crdx[i+2],crdy[i+2],k,smooth)[0]; | ||
+ | crdy[i] =sm(crdx[i-2],crdy[i-2],crdx[i+2],crdy[i+2],k,smooth)[1]; | ||
+ | |||
+ | } | ||
+ | |||
+ | canvas.clearRect(-width/2,-height/2,width,height); | ||
+ | canvas.beginPath(); | ||
+ | canvas.strokeStyle = "black"; | ||
+ | canvas.lineWidth = 1; | ||
+ | |||
+ | if(n==-1) | ||
+ | { | ||
+ | canvas.moveTo(crdx[0],crdy[0]); | ||
+ | canvas.lineTo(crdx[4],crdy[4]); | ||
+ | canvas.lineTo(crdx[8],crdy[8]); | ||
+ | canvas.lineTo(crdx[0],crdy[0]); | ||
+ | } | ||
+ | else{ | ||
+ | canvas.moveTo(crdx[0],crdy[0]); | ||
+ | for(var i=0; i<crdx.length;i++) | ||
+ | { | ||
+ | canvas.lineTo(crdx[i+1],crdy[i+1]); | ||
+ | }} | ||
+ | canvas.stroke(); | ||
+ | canvas.closePath(); | ||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | var t = -1, | ||
+ | k_t = 0, | ||
+ | smooth = 10, | ||
+ | order = 3; | ||
+ | //console.log(crdx); | ||
+ | |||
+ | function loop() { | ||
+ | if(t <= order){ | ||
+ | drw2(t, k_t, smooth); | ||
+ | //canvas.clearRect(-width/2,-height/2,width/2,height/2); | ||
+ | k_t++; | ||
+ | console.log(k_t) | ||
+ | if(k_t == smooth) | ||
+ | { | ||
+ | k_t = 0; | ||
+ | t++; | ||
+ | // | ||
+ | } | ||
+ | if (t==order+1) { | ||
+ | setTimeout(()=>{document.location.reload()}, 2000) | ||
+ | } | ||
+ | } | ||
+ | //else{ | ||
+ | //canvas.font = "48px Verdana"; | ||
+ | //var text = "Koch Snowflake" | ||
+ | //canvas.fillStyle = "orange"; | ||
+ | //canvas.fillText(text, -canvas.measureText(text).width/2, Math.trunc(height / 3)); | ||
+ | //} | ||
+ | } | ||
+ | |||
+ | setInterval(loop,timedist); | ||
+ | |||
+ | |||
+ | </script> | ||
+ | </body> | ||
+ | </html> | ||
+ | |||
+ | |||
+ | document.onkeydown=keyControl; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </div> |
Текущая версия на 11:16, 31 октября 2020
Содержание
Авторы[править]
Смирнова Ирина
Нежинская Лилия
Описание[править]
Снежинка Коха - фрактал, который получается из трех копий кривой Коха. Интересно то, что данная кривая имеет бесконечную длину, непрерывна, но нигде не дифференцируема.
Визуализация[править]
Код программы[править]
Код программы на языке 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;