Снежинка Коха (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;