Na této stránce se dovíte něco o náhodném fraktálu a jak jej jednoduše vykreslovat na internetové stránce pomocí JS a <canvas>
.
Fraktál o kterém zde bude řeč, vzniká následujícím způsobem.
→ →
A tak pokračujeme s každým čtvercem dál a dál…
Jako náhodný se označuje proto, že čtverec, který v každém kroku vynecháme je určen generátorem pseudonáhodného čísla.
· · ·
hloubka mod 3
.Pro vykreslování je použit prvek canvas, který dnes podporuje již velká část prohlížečů (nejrozšířenější IE bohužel nikoli).
<body>
<canvas id="platno" width="256" height="256" />
</body>
Upozornění pro OOP programátory následující kód je psán v JavaScriptu za pomoci funkcionální filozofie. Takže mě nekamenujte, když se Vám to bude zdát poněkud neobjektové. Mějte strpení, jsem nakažen LISPem :)
Nejdříve si nedefinujeme 2 pomocné funkce pro vykreslování.
function rec( x, y, a, color){
ctx.fillStyle = color ? "white" : "black";
ctx.fillRect(x, y, a, a);
}
Vykreslí čtverec na pozici x, y o délce strany a s bílou nebo černou barvou podle boolean hodnoty color. ctx je 2D kontext plátna, viz dále.
Druhá funkce vykreslí jeden element fraktálu na pozici x, y s délkou strany a, přičemž čtverec daný parametrem w (číslo 0 .. 3) bude bílý.
function element( x, y, a, w){
a = Math.ceil(a/2);
rec( x , y , a , color , w==0);
rec( x + a , y , a , color , w==1);
rec( x , y + a , a , color , w==2);
rec( x + a , y + a , a , color , w==3);
}
A konečně vlastní funkce pro vykreslení fraktálu.
function frac( x, y, a, n ){
var rnd = Math.round(Math.random()*3); // náhodné číslo (0 .. 3)
element(x, y, a, rnd );
if( n-- == 0 ) return; // konec
a = Math.ceil(a/2);
if(rnd != 0) frac( x , y , a , n);
if(rnd != 1) frac( x + a , y , a , n);
if(rnd != 2) frac( x , y + a , a , n);
if(rnd != 3) frac( x + a , y + a , a , n);
}
Vykreslí fraktál na pozici x, y s délkou strany a. Jedná se o rekurentní funkci, která volá sama sebe na vykreslení dílčích čtverců. Parametr n je počet volání (iterací).
Nyní už jen spustit vykreslení po načtení stránky.
var ctx;
onload = function(){
var can = document.getElementById('can');
ctx = can.getContext("2d");
frac(0, 0, 256, 8);
}
Krátké, ne?
Výše uvedený rekurentní algoritmus poměrně časově náročný. Proto je lepší provádět jenotlivé kroky rekurze v časových intervalech, tím dosáhneme efektu animace.
Výhodou použití tohoto relativně neefektivního algoritmu, vyjma toho, že je velmi snadno pochopitelný, je fakt, že rozšíření o časové zpoždění je otázkou přidání jedné fce. a náhradou bloku volání ve fci. frac.
...
if(rnd != 0) sequence( function(){ frac( x, y, a, n) });
...
Funkce sequence je implementace jaké si čekací fronty. Nebudu ji příliš rozebírat, pokud vás zajímá, koukněte se do zrojáku. Zda-li se bude fraktál vykreslovat do šířky čí do hlouby záleží na imlpementaci právě fce. sequence (pujde li o forntu nebo zásobník).