Tekenen met <canvas>: De Juliaset fractal
Met de komst van HTML5 is ook de tag <canvas> beschikbaar gekomen. Daarmee kun je tekeningen maken in je webdocument. Dat kan met behulp van voorgedefinieerde vormen, zoals lijnen, cirkels, rechthoeken, veelhoeken, enz. Het kan ook pixel-voor-pixel. Dat maakt het mogelijk om zeer complexe figuren te tekenen zoals fractals. Op deze pagina wordt getoond hoe je een figuur pixel voor pixel opbouwt, aan de hand van de Juliaset fractal.
We beginnen met een uitgewerkte applicatie:
- Er worden twee items besproken:
- De implementatie van het algoritme voor het tekenen van de figuur.
- De werking van de applicatie.
- Inspiratie voor dit item is ontstaan door een vergelijkbaar item over de Fractal van Mandelbrot.
- Het rekengedeelte van de applicatie is afkomstig van de site rosettacode.org.
Die site heeft tot doel om oplossingen voor (programmeer-)problemen te presenteren in zoveel mogelijk programmeertalen, om zo de overeenkomsten en verschillend tussen die talen te laten zien.
Op het moment dat dit geschreven wordt zijn er op rosettacode.org voor het schrijven van 'Hello World' oplossingen beschikbaar in 480(!) programmertalen, van diverse assemblers tot 3e generatietalen zoals Pascal, C, enz. - Voor deze site is de code van rosettacode.org geschikt gemaakt voor toepassing in een website (het origineel is gemaakt om te draaien vanuit een browser console) en is er een applicatie omheen gebouwd.
- De naam "rosettacode" is ontleend aan de Steen
van Rosetta, een tegel waarop een tekst staat in drie schriften, te weten Koinè-Grieks, in demotisch schrift (Egypte)
en in hiërogliefen (ook Egypte). Dit heeft geleid tot het ontcijferen van de Egyptische hiërogliefen.
- De implementatie van het algoritme
- Er zijn vier JavaScript-functions: setupEnInit(), drawFractal(), remap() en getColor().
setupEnInit() maakt het <canvas>-element.
- De function drawFractal() voert voor elk beeldpunt van het <canvas> het iteratieproces uit en berekent vervolgens de RGB-waarde voor dat beeldpunt. Dat laatste gebeurt door getColor().
- De variabelen die door deze functions worden gebruikt hebben allemaal globale scope. De functions hebben waar nodig hun eigen lokale variabelen.
- De globale variabelen zijn.
• Het paar minX en minY zijn de coördinaten van de linker onderhoek. Default: (-.5,-.5).
• Het paar maxX en maxY zijn de coördinaten van de rechter bovenhoek. Default: (.5,.5).
• maxIterations is het maximale aantal iteratie-stappen dat de function drawFractal() mag uitvoeren. Default: 450. - Het verschuiven en verschalen van de plot naar het <canvas> wordt door drawFractal() uitbesteed aan de function remap().
- Als eerste worden er gegevens opgehaald over het <canvas>-element. Dit is een wijziging ten opzichte van de oorspronkelijke code.
- Er wordt een canvas-element gemaakt (createElement()), dat in eerste instantie zwart wordt opgevuld. Dat
element wordt vervolgens met insertBefore() in de regel
<p id="fractal"><span> </span><span> </span></p>
tussen de beide <span>-tags gezet. - Vervolgens wordt de invoer opgehaald en gecheckt. Als daar fouten in zitten wordt de invoer teruggezet op de defaultwaarden.
- Daarna wordt drawFractal() aangeroepen. Deze berekent en tekent de fractal. Voor elk elke beeldpunt wordt de kleur bepaald en in het canvas gezet, mits het rekenproces voor dat beeldpunt convergeert. Anders houdt het de oorspronkelijke kleur, zwart.
- De werking van de applicatie
- De applicatie is gemaakt met HTML, JavaScript en een beetje CSS.
- HTML
- De HTML waar de applicatie is gemaakt bestaat uit drie delen:
• Het formulier voor het veranderen van de rekenparameters.
• Het deel waar de fractal figuur wordt geplaatst.
• De toelichting.
- Het formulier is gemaakt met default tekstinvoer-velden. Je kunt er dus alles intypen. Er is een aparte validatie
nodig om te verzekeren dat er geen verkeerde informatie wordt aangeleverd. Dat wordt gedaan met JavaScript.
Er is geen gebruik gemaakt van type="number", omdat dit type invoerveld (nog) niet goed omgaat met gebroken getallen. - De submit-knop start de function parseAndProcessInput().
- De fractal figuur staat in een canvas-tag die wordt gemaakt door het JavaScript. Om het ding op het scherm te positioneren is het in een <p>-tag geplaatst met id="fractal" , waarmee het in het midden van de regel wordt gezet. Om het goed in de <p>-tag te kunnen 'mikken' zijn er twee <span>-tags ingevoegd die alleen een non-breaking space bevatten.
- Bij de fractal figuur horen de meldingen over het maximale aantal iteratie-stappen en de coördinaten van de linker onderhoek en de rechter bovenhoek. Die staan in een <div>-tag met klasse toelichting.
- De toelichting is een blok tekst die ook zit in een <div>-tag met klasse toelichting.
- CSS
- Het id #fractal, dat ook wordt gebruikt om de plot in het <canvas>-element te zetten, wordt gebruikt om de plot te centreren in de regel. Dat gaat via een <p>-tag. Dat is een lijn-element, dus er wordt text-align:center gebruikt.
- De klasse toelichting wordt alleen gebruikt in <div>-tags. Dat zijn blok-elementen, dus wordt de content
gecentreerd met margin:0 auto. toelichting is 600px breed, even breed als de <canvas>-tag.
- JavaScript
- Het JavaScript staat, samen met de functions drawFractal(), getColor() en remap() voor het genereren van de figuur, in de file juliaset1.js.
- Voor de applicatie zijn er twee functions:
setupEnInit() en parseAndProcessInput().
º setupEnInit() maakt het <canvas>-element. Deze function wordt gestart zodra de pagina is geladen.
º parseAndProcessInput() wordt aangeroepen door setupEnInit() en als er op de submit-knop wordt geklikt. - parseAndProcessInput() haalt de gegevens op uit het formulier en controleert of de informatie zinnig zou kunnen zijn. Als een fout wordt gevonden wordt er een melding gegeven en wordt de invoer teruggezet op de default-waarden. Als de verhouding van de opgegeven breedte en hoogte niet gelijk is aan 1:1, wordt er een melding gegeven dat de plot vertekend is.
- Als er geen fouten worden gevonden wordt drawFractal() aangeroepen voor het maken van een nieuwe figuur.
Gebruik:
- De code staat gedeeltelijk in de <HEAD> en gedeeltelijk in de <BODY>.
- De code van het voorbeeld vind je in de downloadfile. Behalve de achtergrond en de opmaak van de tekst is die gelijk aan wat er op deze site staat.
Downloaden:
Druk op de knop:
File: voorb721.zip, 3618 bytes.
Opmerking:
De Juliaset is nauw verbonden met de Fractal van Mandelbrot. Zie het item
Tekenen met <canvas>: De fractal van Mandelbrot