Fraktály sú dobre známe sebe-podobné množiny, ktoré vyzerajú podobne v rôznych úrovniach zväčšenia. Najznámejší fraktál nesie meno po svojom objaviteľovi, polsko-francúzsko-americkom matematikovi - Benoitovi Mandelbrotovi. V roku 1980, keď ako jeden z prvých použil počítačovú grafiku na zobrazovanie fraktálnej geometrie pomocou IBM strojov.
V Go vďaka natívnej podpore komplexných čísel a knižníc na prácu s obrázkami vieme jednoducho vytvoriť web server, ktorý interaktívne generuje fraktálové obrazy do png. Vytvoríme si Go server, HTML a jednoduchý JavaScript, pomocou ktorého budeme hľadať zaujímavé štruktúry:
- klikom myši vycentrovať
- + zväčšiť
- - zmenšiť
- 1-4 zmeniť vzorec (mandelbrot, julia, newton, mix)
- 5-9 zmeniť farebnú paletu
- q resetovať nastavenia
Galéria
Všetky obrázky v galérii boli generované zdrojovým kódom nižšie a neboli použité žiadne ďalšie efekty:
Komplexné funkcie
Fraktály sú najčastejšie dynamické systémy generovné iteratívne komplexnými funkciami. Pri mandelbrotovej alebo julia množine zisťujeme, či a po akom počte iterácií unikne absolútna hodnota za nejakú hranicu. Vytvoríme si štyri funkcie s komplexným číslom ako argumentom (vstupný pixel), vracajúcu výsledné komplexné číslo po iteráciach a počet iterácií. Súbor si uložme ako “fractals.go”:
|
|
Web server s image handlerom
Tento web server má dva handlere:
/image.png
vygeneruje nový obrázok, imgHandler najskôr načíta HTTP request parametre a potom vyrenderuje každý riadok obrázka v osobitnej gorutine/
fileserver pre všetko ostatné
Všimnime si, že komplexné funkcie aj funkcie na generovanie farieb sú vďaka Go podpore funkcií ako hodnôt (first-class-citizens) uložené do slicu. Kvôli volaniu v goroutine je renderLine
funkcia je vytvorená ako lambda funkcia s closure - uzavretým scope, ktorý obsahuje “c” a “f” funkcie, “img” a “wg” WaitGroup.
Funkcia getFloat
nie je veľmi zaujímavá, len extrahuje požadovaný HTTP request parameter a snaží sa skonvertovať ho na float64 hodnotu, ak sa to nepodarí vracia default hodnotu.
Súbor si uložme ako “main.go”:
|
|
Html a JavaScript časť
Samotný index.html
obsahuje pomocné CSS, jquery z CDN-ka, <div>
do ktorého vypíšeme status a <img>
do ktorého budeme zapisovať vygenerovaný obrázok.
Funkcia update()
prepíše src atribút obrázku, čím vyvolá jeho načítanie a aktualizuje status. Zavolaný image.png endpoint s požadovanými parametrami vygeneruje nový obrázok.
Keď sa celý dokument načíta $(document).ready()
, tak sa aktualizuje obrázok a nastavia sa funkcie na klik myškou na obrázku a klávesové skratky.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fractal</title>
<style>
html, body{
font-family: monospace;
height: 100%;
width: 100%;
margin: 0;
text-align: center;
color: white;
background-color: #333;
}
img{
margin: 0px auto;
display: block;
cursor: pointer;
min-height: 400px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
cx = 0 // center x
cy = 0 // center y
zm = 2 // zoom
w = 1024 // image width
h = 1024 // image height
tp = 0 // fractal type
cr = 0 // color palette
function update() {
$("#canvas").attr("src", "image.png?x=" + cx + "&y=" + cy + "&z=" + zm + "&t=" + tp + "&c=" + cr)
$("#output").html("x: " + cx + "<br> y: " + cy + "<br> z: " + zm + "<br> t: " + tp + "<br> c: " + cr)
}
$(document).ready(function() {
update()
$("img").on("click", function(event) {
var x = event.pageX - this.offsetLeft
var y = event.pageY - this.offsetTop
cx += 2.0 * zm * (x / w - 0.5)
cy += 2.0 * zm * (y / w - 0.5)
update()
})
$(document).keypress(function(event) {
dirty = false
switch(event.which) {
case 43: // +
zm /= 1.5
dirty = true
break
case 45: // -
zm *= 1.5
dirty = true
break
case 113: // q
cx = 0
cy = 0
zm = 2
dirty = true
break
case 49: // 1
case 50: // 2
case 51: // 3
case 52: // 4
tp = event.which - 49
dirty = true
break;
case 53: // 5
case 54: // 6
case 55: // 7
case 56: // 8
case 57: // 9
cr = event.which - 53
dirty = true
break
default:
console.log( event.which )
break
}
if(dirty) {
update()
}
})
})
</script>
</head>
<body>
<div id="output" style="float: left; text-align: left;width:200px"></div>
<img id="canvas" title="click = center, +/- zoom, 1-4 = type, 5-8 = color, q = reset"/>
</body>
</html>
Záver
Finálny program skompilujeme a spustíme go run .
a v prehliadači si otvoríme lokálnu stránku http://localhost:4200/.
V tomto dieli sme si ukázali, že Go nie je výborné len na sieťové a systémové CLI aplikácie, ale taktiež na výpočty s komplexnými číslami a interaktívne generovanie obrázkov do webového prehliadača. Na kráse fraktálnej geometrie ma neprestáva fascinovať ako tie najjednoduchšie vzorce dávajú vznik nekonečne komplexným štruktúram.
Referencie
Vaše otázky, návrhy a komentáre
Verím, že vás tento návod inšpiroval a budem vďačný ak dáte spätnú väzbu a pomôže mi zamerať sa na to čo by vás zaujímalo.