prev up inhalt next


8.6 Mandelbrot-Menge

Sei z eine komplexe Zahl mit Realteil z.re und Imaginärteil z.im :
    public class Komplex
    {
            double re;
            double im;

    ...

Das Quadrat einer komplexen Zahl z hat den Realteil z.re 2 - z.im 2 und den Imaginärteil 2 · z.re · z.im . Der Betrag einer komplexen Zahl c sei |c| = .
Betrachte die Funktion f : ,f (z) = z 2 + c für festes c .

    Komplex f(Komplex z)
    {
            double tmp;

            tmp   = z.re;
            z.re  = z.re * z.re - z.im * z.im + c.re;
            z.im  = 2 * tmp * z.im + c.im;

            return z
    }
Betrachte die Folge z,f (z),f 2(z),f 3(z),... beginnend bei z = 0 für festes c .
Für manche c wächst der Betrag beliebig, für manche c konvergiert er zu einem Fixpunkt. Die Mandelbrotmenge besteht aus solchen komplexen Zahlen c , die beim Startwert z = 0 zur Konvergenz führen.
Um die Mandelbrotmenge grafisch darzustellen, definiert man

Ordne jedem Pixel (p.x,p.y) des Bildschirms eine komplexe Zahl zu wie folgt. Die linke obere Ecke bezeichne die komplexe Zahl start (z.B. - 2.15,2.15 ). Die rechte obere Ecke bezeichne die komplexe Zahl ende (z.B. 0.85,2.15 )
Dann ergibt sich bei 300 Pixeln pro Zeile eine Schrittweite von (0.85 + 2.15)/300 = 0.01 .
Somit läßt sich ein Koordinatenpaar (p.x,p.y) umrechnen durch den folgenden Konstruktor.

        public Komplex(Point p, Komplex start, double schritt)
        // bildet die komplexe Zahl zum Pixel p mit linker/oberer Ecke start
        // und Schrittweite schritt
        {
                this.re = start.re + schritt * (double)p.x;
                this.im = start.im - schritt * (double)p.y;
        }

Sei (p.x,p.y) das zur komplexen Zahl c gehörende Pixel. Dann färbe es mit farbe( c ).


Mandelbrotmenge: - 2.2 z.re 0.6 , - 1.2 z.im 1.2 , 100 Iterationen

Implementation der Mandelbrot-Menge

Sobald während des Iterierens der Betrag von z > 2 Folge konvergiert definitiv nicht.
Falls Betrag von z nach z.B. 100 Iterationen noch < 2 Folge konvergiert vermutlich.
D.h., bei Erreichen einer vorgegebenen Iterationenzahl wird das Pixel, welches der komplexen Zahl c entspricht, schwarz gefärbt, da c vermutlich zur Konvergenz führt.

void mandel ()
{
     Point p;
     int zaehler;
     Komplex c, z;

     for (p.x = 0; p.x < WIDTH;  p.x++)
     for (p.y = 0; p.y < HEIGHT; p.y++)
     {
          zaehler = 0; 
          c       = new Komplex(p, start, schritt);
          z       = new Komplex(c);

          while ((betrag (z) < 2.0) && (zaehler++ < max_iter))

             z = f(z);

          if (betrag(z) < 2.0) set_pixel(p);
      }
}

Bemerkung:
Bei Erhöhung der Iterationszahl können einige Pixel weiß werden, da sich herausgestellt hat, daß durch weitere Iterationen die Betragsgrenze 2 überschritten wird.
Um die Zahlen c , die nicht zur Konvergenz geführt haben, weiter zu klassifizieren, setzt man

Also ergibt sich:

   if (betrag < 2.0)        set_pixel (p); else
   if ((zaehler %  2) != 0) set_pixel (p);

Bei Farbbildschirmen gibt es folgende Möglichkeit, die Divergenzgeschwindigkeit der Folge für ein c zu veranschaulichen:

Es seien die Farben farbe[0], ..., farbe[NUM_COL-1] vorhanden

    set_col_pixel (p, farbe [zaehler % NUM_COL])


Mandelbrotmenge: - 1.2548 Re - 1.2544 , 0.3816 Im 0.3822 , 100 Iterationen

/************************************************************************************/
/*                           Mandelbrotmenge                                        */
/************************************************************************************/
void  mandel(                   // berechnet und zeichnet Mandelbrotmenge ab 
        Komplex start,          // linker oberer Ecke start der komplexen Flaeche
        double  schritt,        // mit Schrittweite schritt und 
        int     max_iter,       // Iterationsanzahl max_iter (muss gerade sein)
        int     fall)           // gemaess Fall fall
                                // Abbruch, wenn Quadrat des Betrags >= 4 
                                // oder wenn Iterationszahl erreicht ist 
{
    Komplex c = new Komplex(0.0, 0.0);
    Komplex z = new Komplex(0.0, 0.0);
    Point   p = new Point();
    double  q_betrag, tmp;
    int     zaehler ;

    for (p.x = 0, c.re = start.re; p.x < WIDTH;  p.x++, c.re += schritt) 
    for (p.y = 0, c.im = start.im; p.y < HEIGHT; p.y++, c.im += schritt) 
    {
        z.re = 0.0;
        z.im = 0.0;
        zaehler = 0;
        q_betrag  = 0.0;

        while( (q_betrag < 4.0)  && (zaehler++ < max_iter) ) {
                tmp    = z.re;
                z.re   = z.re * z.re - z.im * z.im + c.re;
                z.im   = 2 * tmp * z.im + c.im;
                q_betrag = z.re*z.re + z.im*z.im;
        }
                
        switch (fall) {

        case 1: if (q_betrag(z) < 4.0) set_pixel(p); break;       // schwarz

        case 2: if (q_betrag(z) < 4.0) set_pixel(p); else         // schwarz
                if ((zaehler %2) != 0) set_pixel(p); break;       // mit modulo

        case 3: if(zaehler == max_iter+1)
                set_col_pixel(p,farbe[0]); else                   // Mandelbrotmenge
                set_col_pixel(p,farbe[zaehler%NUM_COL]); break;   // farbe modulo
        }
    }
}
	


prev up inhalt next