2.8 Beispiel: Bildliche Darstellung der Mandelbrot-Menge

Werbung
Aufgabe: Programmieren Sie ein „Apfelmännchen“
Quelle: Xiang, Plastock: Computergrafik
2.8
Beispiel: Bildliche Darstellung der
Mandelbrot-Menge
Ein elegantes und anschauliches Beispiel, das den Aufbau schöner Bilder durch das Setzen
von Farbattributen für einzelne Pixel direkt aus der Anwendung heraus verdeutlicht, ist die
bildliche Darstellung der Mandelbrot-Menge. Diese bemerkenswerte Menge beruht auf der
folgenden Transformation:
Xn+1 = Xn2 + Z
wobei sowohl x als auch z komplexe Zahlen sind. Für Leser, die mit komplexen Zahlen nicht vertraut sind, reicht es zu wissen, dass eine komplexe Zahl in der Form a + bi festgelegt wird. Hier
handelt es sich bei a und b um reelle Zahlen; a wird als Realteil der komplexen Zahl und b als
Imaginärteil (der durch das spezielle Symbol i gekennzeichnet ist) bezeichnet. Der Betrag von
a + bi, angegeben in der Form \a + bi\, entspricht der Quadratwurzel von a2 + b2. Die Summe
der beiden komplexen Zahlen a + bi und c + di wird als (a + c) + (b + d) i definiert, das Produkt als
(ac - bd) + (ad + bc)i definiert. Das Quadrat von a + bi entspricht daher (a2 - b2) + 2abi. Die Summe
von 0,5 + 2,0i und 1,0 - 1,0i beträgt beispielsweise 1,5 + 1,0i. Als Produkt ergibt sich 2,5 + 1,5i. Das
Quadrat von 0,5 + 2,0i ergibt -3,75 + 2,0i und das Quadrat von 1,0 - 1,0i beträgt 0,0 - 2,0i.
Bei der Mandelbrot-Menge handelt es sich um eine Menge komplexer Zahlen z, die unter der
oben genannten Transformation mit X0 = 0 nicht divergieren. (Sowohl der Real- als auch der
Imaginärteil von x0 sind 0). Mit anderen Worten: Um festzustellen, ob eine bestimmte komplexe
Zahl z ein Element der Menge ist, beginnen wir mit x0 = 0, gefolgt von x1 = x02 + z,x2 = x12 + z,..., xn+l =
xn2 + z,... Wenn |x| bei der Erhöhung von n gegen unendlich geht, dann ist z kein Element.
Andernfalls gehört z zur Mandelbrot-Menge.
Abbildung 2.11 zeigt, wie man eine diskrete Momentaufnahme der Mandelbrot-Menge erstellt.
Auf der linken Seite befindet sich die komplexe Ebene, wo die horizontale Achse Re den Realund die vertikale Achse Im den Imaginärteil komplexer Zahlen angibt. Daher entspricht eine
beliebige komplexe Zahl z einem Punkt auf der komplexen Ebene. Unser Ziel ist es, ein Bild in
Breite mal Höhe (in Anzahl der Pixel) zu erzeugen, das die z-Werte in einem rechteckigen
Bereich abbildet, der durch (Re_min, Im_min) und (Re_max, Im_max) definiert wird. Dieser
rechteckige Bereich weist dasselbe Seitenverhältnis wie das Bild auf, um geometrische
Verzerrungen auszuschließen. Zur Anpassung an das Pixelraster des Bilds unterteilen wir den
Raum. Die Farbe eines Pixels, das als kleines Quadrat im Pixelraster dargestellt wird, wird durch
die komplexe Zahl z bestimmt, die der unteren linken Ecke des kleinen Quadrats entspricht.
Obwohl in der komplexen Ebene nur Punkte in der Anzahl (Breite x Höhe) für die
Bildberechnung verwendet werden, erzeugt dieser relativ direkte Ansatz der diskreten
Abtastung halbwegs gute Näherungen für die bildliche Darstellung der Menge.
Abb. 2.11: Bildliche Darstellung der Mandelbrot-Menge
Es gibt viele Wege, die Farbe eines Pixels auf der Grundlage der entsprechenden komplexen
Zahl z zu bestimmen. Hier erzeugen wir ein Graustufenbild, bei dem die Helligkeit eines nicht
schwarzen Pixels proportional die Anzahl der Iterationen darstellt, die nötig sind, damit |x|
größer als 2 wird. Wir verwenden 2 als Schwellenwert für die Divergenz, da x unter der
vorgegebenen Transformation schnell divergiert, wenn |x| den Wert 2 erst einmal
überschritten hat. Bleibt |x| nach einer vorgegebenen maximalen Anzahl von Iterationen
kleiner oder gleich 2, setzen wir den Pixelwert einfach auf 0 (Schwarz).
Der folgende Pseudocode führt das aus, was wir in den vorherigen Absätzen erläutert haben.
Wir verwenden N zur Darstellung der maximalen Anzahl von Iterationen, z.real als Real- und
z.imag als Imaginärteil von z. Außerdem gehen wir von einer Graustufentabelle mit 256
Einträgen aus, in der (i, i, i) der Farbwert in Eintrag i ist. Mit der Formel im zweiten Aufruf von
setCol or wollen wir eine proportionale Abbildung von [0; N] auf [1; 255] erzielen:
int i, j, count;
float delta = (Re_max-Re_min)/breite;
for (i = 0, z.real = Re_min; i < breite; i ++ , z.real+ = delta)
for (j = 0, z.imag = Im_min; j < höhe; j++, z.imag+ = delta)
{
count = 0;
komplexe Zahl x = 0;
while ( |x| <= 2 , 0 && count < N)
{
compute x = x 2 + z;
count++;
}
if ( | x | <= 2,0) setColor(0);
else setColor(1+254*count/N);
setPixel (i, j ) ;
}
Das Bild in Abb. 2.12 zeigt ein Phänomen, das den Spitznamen Apfelmännchen trägt. Es stellt
einen Bereich dar, in dem -2,0 <= z.real <= 0,5 und -1,25 <= z.imag <= 1,25 bei N = 64 ist. Die
meisten der außerhalb dieses Bereichs liegenden z-Werte führen zu einer schnellen Divergenz
von x,während die z-Werte in dem schwarzen Bereich zur Mandelbrot-Menge gehören. Entlang
der Kontur des Apfelmännchens sehen wir die meisten dynamischen Änderungen zwischen
Divergenz und Nichtdivergenz zusammen mit den signifikantesten Schwankungen der im
Divergenztest verwendeten Anzahl von Iterationen. Je heller ein Pixel ist, desto länger dauert es,
Schlussfolgerungen über die Divergenz des entsprechenden z-Werts zu ziehen. Im Prinzip kann
der rechteckige Bereich unendlich verkleinert werden, um aktive Regionen zu vergrößern und
damit kompliziertere Details aufzuzeigen.
Abb. 2.12: Die Mandelbrot-Menge
Herunterladen