Flex benötigt zur Ausführung Flash und bekanntlich ist Flash ja früher ein Tool gewesen um Animationen und vergleichbares zu erstellen. Fälschlicherweise denken auch heute noch viele an ein besseres Powerpoint wenn sie das Wort “Flash” hören, aber dies ist ein anderes Thema.
Anstelle der grafischen Art und Weise wie man eine Flash Animation erstellen kann, ist es natürlich auch möglich, Bilder per Code erstellen. Wir wollen deswegen ein simples Fraktal von Flex/Flash zeichnen lassen.
Der Code für die Erstellung des Fraktals, hab ich einem C-Beispiel entnommen, dessen Herkunft ich leider nicht mehr kenne. Ich hab es aber in der Kategorie “ohne Copyright” bei mir eingeordnet, sollte dies nicht stimmen, bitte melden!
Damit unser Fraktal gezeichnet wird, ohne dass wir 10 Tassen Kaffee trinken müssen bis etwas sichtbar ist, verwenden wir die BitmapData Klasse. Diese Klasse ist für unsere Zwecke ideal, da wir nicht direkt auf den Monitor zeichen, sondern in eine Art 2D-Array. Würden wir jeden Pixel direkt auf den Monitor zeichnen, gäbe es sehr viele “Refreshs” der Anzeige.
Wie kann ich mit BitmapData etwas ausgeben?
... bmd = new BitmapData(300, 200); bmd.setPixel(10,10,0xFF0000); img.source = new Bitmap(bmd); ]]> </mx:Script> <mx:Image id="img" /> |
Dieser Code zeichnet lediglich einen roten “Pixel” an der Position 10, 10 und gibt in anschliessend im Image Objekt “img” aus. Für die Ausgabe müssen wir unser BitmapData Object in ein Bitmap Objekt umwandeln, dazu gibt es sogar einen Konstruktor, so dass wir dafür lediglich eine Zeile benötigen (new Bitmap(bmd)).
Mit diesem Prinzip können wir mit einer akzeptablen Performance Bilder erstellen. Selbstverständlich können wir nicht nur einzelne Pixel mit BitmapData manipulieren, es gibt zahlreiche Funktionen wie zum Beispiel fillRect, wir wollen aber nicht weiter auf die Funktonen von BitmapData eingehen.
Damit wir die Parameter unseres Fraktals ohne Code-Änderung einstellen können, erstellen wir mit MXML ein simples Interface. Mit “mx:HSlider” stellt uns Flex ein passendes Control zur Verfügung um einen numerischen Wert grafisch zu verändern.
<mx:HSlider id="slider_p" minimum="-5" maximum="-0.7" value="-1.29" tickColor="black" snapInterval="0.1" tickInterval="0.3" allowTrackClick="true" liveDragging="true" change="generateFractal()"/> |
Bei jeder Änderung (change=…) führen wir die Funktion “generateFractal” aus, welche sofort das Fraktal neu zeichnet.
Mein Wissen bezüglich Fraktalen ist definitiv zu klein, deswegen kann ich den Code nicht weiter kommentieren. Es gibt aber zahlreiche Ressourcen im Internet wenn jemand mehr über dieses Thema wissen will.
<mx:Script> <![CDATA[ private var bmd:BitmapData; public function generateFractal():void { bmd = new BitmapData(300, 200); bmd.lock(); var xmin:Number, xmax:Number, ymin:Number, ymax:Number; var fact:Number = 1.0; var ypy:Number, x:Number, y:Number, x0:Number, y0:Number, xp:Number, yp:Number; var const_scr:Number = 1.0; var deltax:Number, deltay:Number, p:Number, q:Number, ya:Number, r:Number, xkp1:Number, ykp1:Number; var npix:int = 640, npiy:int = 480; var kcolor:int; var k:int, np:int, nq:int, ipen:int; p = slider_p.value; q = slider_q.value; xmin = slider_xmin.value; xmax = slider_xmax.value; ymin = slider_ymin.value; ymax = slider_ymax.value; kcolor = slider_kcolor.value; deltax = (xmax-xmin)/npix-1; deltay = (ymax-ymin)/npiy-1; for (np = 0; np <= npix - 1; np++) { x0 = xmin + np*deltax; for (nq = 0; nq <= npiy - 1; nq++) { y0 = ymin + nq*deltay; x = x0; y = y0; k = 0; do { xkp1 = (x+y)*(x-y) + p; ya = x*y; ykp1 = ya + ya + q; r = xkp1*xkp1 + ykp1*ykp1; k++; if (r >= kcolor) { ipen = 30 + k; xp = const_scr*np; yp = nq; bmd.setPixel(xp,yp,ipen*100); } if (k == kcolor) { ipen = 1; xp = const_scr*np; yp = nq; bmd.setPixel(xp,yp,ipen*100); } x = xkp1; y = ykp1; } while (r <= kcolor && k<=kcolor); } } bmd.unlock(); img.source = new Bitmap(bmd); } ]]> </mx:Script> |
Die Input Parameter hab ich “empirisch” auf ein Minimum bzw. Maximum beschränkt. Einige sind aber trotzdem nicht ganz optimal, so lässt sich zum Beispiel die Farbe nicht wirklich ändern.. Werde bei Gelegenheit noch ein paar Dinge optimieren, bekomme aber auch immer gerne Feedback!
Keine Kommentare
You can leave the first : )