# Das Apfelmännchen

Dieses Buch steht im Regal Programmierung.
Dieses Wikibook beschäftigt sich mit der softwaretechnischen Erstellung von fraktalen Mengen mit der Hilfe von strukturierten Java-Programmen, insbesondere mit der Berechnung von Julia-Mengen und der Mandelbrot-Menge. Letztere wird wegen der Ähnlichkeit ihrer geometrischen Form zu einer Figur aus verschieden großen Äpfeln auch Apfelmännchen genannt.

## Julia-Mengen

Julia-Mengen sind nach dem französischen Mathematiker Gaston Maurice Julia (* 1893; † 1978) benannt, der diese 1917 fast gleichzeitig mit dem ebenfalls französischen Mathematiker Pierre Fatou (* 28. 1878; † 1929) beschrieben hatte.

## Die Mandelbrot-Menge

1979 begann der französisch-US-amerikanische Mathematiker Benoît Mandelbrot (* 1924; † 2010) damit, an fraktalen Julia-Mengen weiterzuforschen. Mit Hilfe von Computern und Software konnte er bestimmte Eigenschaften von Julia-Mengen graphisch darstellen und entdeckte dabei die nach ihm benannte Mandelbrot-Menge.
Siehe auch Wikibook Komplexe Zahlen / Anwendung in der Mathematik / Mandelbrot-Menge

## Komplexe Zahlen

Komplexe Zahlen bestehen aus einem reellen Anteil und einem imaginären Anteil, die beide durch eine reelle Zahl repräsentiert werden können, die orthogonal in einer Zahlenebene dargestellt werden können. Hierbei wird in der Regel der reelle Anteil auf der horizontalen Achse und der imaginäre Anteil auf der vertikalen Achse aufgetragen. Jede komplexe Zahl hat auf diese Weise einen bestimmten Ort in der komplexen Zahlenebene, die nach dem deutschen Mathematiker Carl Friedrich Gauß (* 1777; † 1857) auch Gaußsche Ebene genannt wird.
Die komplexe Zahl mit dem Zahlendupel (1|0) entspricht der reellen Einheitszahl $1$, und die komplexe Zahl mit dem Zahlendupel (0|1) entspricht der imaginären Einheitszahl $i$. Das Quadrat von $1$ hat den Wert $1$, und das Quadrat von $i$ hat den Wert $-1$:
    $1^{2}=1$
    $i^{2}=-1$
Eine beliebige komplexe Zahl $z$ kann zum Beispiel als Summe eines reellen Anteils $a=z_{re}$ und eines imaginären Anteils $b=z_{im}$ dargestellt werden, in dem die Zahl i mit dem imaginären Anteil multipliziert wird:
    $z=z_{re}+i\cdot z_{im}=a+i\cdot b$
In einer Java-Klasse KomplexeZahl können diese beiden Attribute folgendermaßen programmiert werden:
Die Summe $z_{s}$ zweier komplexen Zahlen $z_{1}$ und $z_{2}$ kann berechnet werden, indem die beiden reellen und die beiden imaginären Anteile jeweils addiert werden:
In Bezug auf die komplexen Zahlen
    $z_{s}=z_{1}+z_{2}=a+i\cdot b+c+i\cdot d=(a+c)+i\cdot (b+d)$
In Bezug auf die reellen Anteile der komplexen Zahlen:
    $z_{s,re}=z_{1,re}+z_{2,re}=a+c$
In Bezug auf die imaginären Anteile der komplexen Zahlen:
    $z_{s,im}=z_{1,im}+z_{2,im}=b+d$
In der Java-Methode addiereZu ist diese Rechenvorschrift implementiert:
Das Quadrat $q$ einer komplexen Zahl $z$ kann mit der folgenden Vorschrift berechnet werden:
In Bezug auf die komplexen Zahlen:
    $q=z^{2}$
In Bezug auf den reellen Anteil von $q$:
    $q_{re}=z_{re}^{2}-z_{im}^{2}$
In Bezug auf den imaginären Anteil von $q$:
    $q_{im}=2\cdot z_{re}\cdot z_{im}$
Die Java-Methode quadriere multipliziert eine komplexe Zahl mit sich selbst:
Das Betragsquadrat $b^{2}$ und der Betrag $b$ einer komplexen Zahl $z$ sind reellwertig (der Imaginäranteil ist also null), und diese können mit Hilfe des Satzes von Pythagoras berechnet werden:
    $b^{2}=|z|^{2}=z_{re}^{2}+z_{im}^{2}$
    $b=|z|={\sqrt {z_{re}^{2}+z_{im}^{2}}}$
Die folgende Methode betragsquadrat ermittelt das Betragsquadrat einer komplexen Zahl:
Mit dem folgenden Java-Programm in der Java-Klasse KomplexeZahl können die oben aufgeführten Rechenoperationen durchgeführt werden:
→ Java-Programm "KomplexeZahl"
Siehe auch:
* → Wikibook Imaginäre und komplexe Zahlen
* → Wikibook Komplexe Zahlen

## Quadratische Polynome

Ein quadratisches Polynom $p_{c}$ kann wie folgt als Funktion $p_{c}(z)$ des Arguments $z$ dargestellt werden:
    $p_{c}(z)=z^{2}+c$
Hierbei können das Argument $z$ und der Koeffizient $c$ auch komplexe Zahlen sein.
Bei einer Polynomfolge wird das nächste Glied mit dem Index $n+1$ nach der folgenden Vorschrift aus dem aktuellen Glied mit dem Index $n$ berechnet:
    $z_{n+1}=p_{c}(z_{n})$ mit $0\leq n;n\in \mathbb {N} _{0}$
Ein quadratische Polynomfolge $p_{c}$ kann demnach wie folgt dargestellt werden:
    $z_{n+1}=p_{c}(z_{n})=z_{n}^{2}+c$
Dieser Algorithmus ist in der folgenden Java-Methode berechneNaechstesPolynomglied umgesetzt:
Bei den Julia-Mengen wird das Verhalten dieser Polynomfolge für alle Startwerte $z_{0}$ in der komplexen Zahlenebene dahingehend untersucht, ob der Betrag dieser Folge beschränkt bleibt oder gegen unendlich divergiert. Für jeden Koeffizienten $c$ ergibt sich eine andere Julia-Menge.
Bei der Mandelbrot-Menge wird das Verhalten dieser Polynomfolge für alle Koeffizienten $c$ in der komplexen Zahlenebene dahingehend untersucht, ob der Betrag dieser Folge mit dem Startwert $z_{0}=0$ beschränkt bleibt oder gegen unendlich divergiert.
In einem Computerprogramm kann diese Beschränktheit mit einer kopfgesteuerten Schleife abgeschätzt werden, die prüft, ob der Betrag der Polynomfolge nach einer vorgegebenen Anzahl von Schleifendurchläufen einen ebenfalls vorgegebenen reellen Betrag nicht überschritten hat. Hier ein Beispiel mit der Methode iterationszahlBisSchranke in der Programmiersprache Java, das für beliebige komplexwertige Zahlen $z$ und $c$ aufgerufen werden kann:
Es hat sich als praktisch erwiesen, für die Schranke der Beträge von z den Wert 2 beziehungsweise für die Betragsquadrate von z den Wert 4 zu wählen. Dicht an der Grenze der zusammenhängenden Gebiete kann es zu Polynomfolgen kommen, die langsam divergieren, so dass durch eine Erhöhung der maximalen Anzahl der Iterationen unter Umständen eine höhere Genauigkeit bei der Berechnung und Darstellung erreicht werden kann. Dies verlängert dann allerdings die Laufzeit der Berechnungen entsprechend.
Mit dem folgenden Java-Programm mit der Klasse FraktaleMenge können die oben erwähnten Rechenoperationen durchgeführt werden:
→ Java-Programm "FraktaleMenge"

## Ausgabe

Es wäre schade, wenn die Ergebnisse der oben aufgeführten Algorithmen nicht sichtbar gemacht werden können. Hierzu dient die unten in diesem Abschnitt abrufbare Java-Klasse FraktaleMengeAusgabe, die die Eigenschaften der Java-Klasse JFrame aus dem Java-Paket swing des Java-Moduls javax erbt. Dadurch wird aus der Oberklasse Window aus dem Java-Paket awt (Abkürzung für "abstract window toolkit") auch die öffentliche, typengebundene Methode paint geerbt, mit der die graphische Ausgabe erfolgt:
* java.awt.Component
** java.awt.Container
*** java.awt.Window
**** java.awt.Frame
***** javax.swing.JFrame
****** FraktaleMengeAusgabe
Mit Hilfe der Java-Klasse BufferedImage aus dem Java-Paket awt kann die Graphik auch gespeichert werden. Hierzu wird mit der Java-Klasse Iterator aus dem Java-Paket util wird die Bilddateiart PNG ausgewählt. Mit einigen Klassen aus dem Java-Paket javax.imageio wird dann das Speichern der unkomprimierten Bilddatei bewerkstelligt.
Mit dem Konstruktor FraktaleMengeAusgabe muss eine neu erzeugte Instanz der Klasse initialisiert werden:
Die folgenden öffentlichen, klassengebundenen Methoden stehen zur Laufzeit zur Verfügung:
| Modifikator | Methode | Beschreibung |
| void | center | Zentriert die Menge auf den Ursprung (0, 0) |
| KomplexeZahl | getComplexParameter ​ | Gibt den komplexwertigen Parameter der fraktalen Menge zurück |
| int | getKeyCode | Gibt den Code der gedrückten Taste zurück (siehe java.awt.event.KeyEvent @Field Summary / Fields) |
| double | getMaxX | Gibt den maximalen reellen Wert der Menge zurück |
| double | getMaxY | Gibt den maximalen imaginären Wert der Menge zurück |
| double | getMinX | Gibt den minimalen reellen Wert der Menge zurück |
| double | getMinY | Gibt den minimalen imaginären Wert der Menge zurück |
| double | getShiftFactor | Gibt den aktuellen Verschiebungs- und Zoomfaktor in Anteilen des Bildausschnitts zurück |
| void | init | Initialisiert die Menge |
| void | repaint ​ | Erneuert die Darstellung der Menge |
| void | saveFile | Speichert die Menge in einer PNG-Datei |
| void | setBorders ​(double minX, double maxX, double minY, double maxY) | Setzt die minimalen und maximalen reelen (X) und imaginären (Y) Koordinaten |
| void | setComplexParameter ​(KomplexeZahl c) | Setzt den komplexwertigen Parameter der fraktalen Menge |
| void | setShiftFactor ​(double shiftFactor) | Setzt den Verschiebungs- und Zoomfaktor in Anteilen des Bildausschnitts festlegen; der Faktor muss größer als 0 und kleiner als 1 sein |
| void | shiftDown | Ausschnitt wird nach unten verschoben |
| void | shiftLeft | Ausschnitt wird nach links verschoben |
| void | shiftRight( ) | Ausschnitt wird nach rechts verschoben |
| void | shiftUp | Ausschnitt wird nach oben verschoben |
| void | zoomIn | In den Ausschnitt hineinzoomen |
| void | zoomOut | Aus dem Ausschnitt herauszoomen |
Mit dem folgenden Java-Programm mit der Klasse FraktaleMengeAusgabe können die fraktalen Mengen angezeigt oder als graphische PNG-Datei gespeichert werden:
→ Java-Programm "FraktaleMengeAusgabe"

## Aufruf des Programms

Die parameterlose, öffentliche Methode init muss aufgerufen werden, um die entsprechende fraktale Menge zu berechnen und gegebenenfalls darzustellen oder zu speichern.
Mit dem folgenden Java-Code kann beispielsweise eine Julia-Menge mit dem Koeffizienten c = (-0.5142|0.5142) berechnet und graphisch ausgegeben werden:
Mit dem folgenden Java-Code kann die Mandelbrot-Menge berechnet und graphisch ausgegeben werden:
Mit dem Aufruf der klassengebundenen Methode safeFile kann beispielsweise der aktuelle Ausschnitt der im Objekt fraktaleMengeAusgabe der Klasse FraktaleMengeAusgabe gespeicherten Menge als PNG-Datei gespeichert werden:
Mit der beispielhaften Methode centerAt0Key (FraktaleMengeAusgabe fraktaleMengeAusgabe) kann die Darstellung der Instanz fraktaleMengeAusgabe der Klasse FraktaleMengeAusgabe modifiziert werden. Das folgende Code-Beispiel bringt den Ursprungspunkt (0, 0) der Menge in die Mitte der graphischen Darstellung, wenn die Taste "0" (entweder auf der Haupttastatur (java.awt.event.KeyEvent.VK_0) oder auf dem Nummernblock (java.awt.event.KeyEvent.VK_NUMPAD0)) niedergedrückt ist:

## Nachwort

Die hier angegebenen strukturierten Programmbeispiele können ohne große Umstände in jede andere strukturierte Programmiersprache übertragen werden. Durch die Modifikation und Ergänzung der angegebenen Algorithmen können sicherlich auch leicht ähnlich geartete Programmieraufgaben gelöst werden. Es wäre erfreulich, wenn dieses Wikibook zu einem besseren und tieferen Verständnis der strukturierten Programmierung und als Einstieg in die Mathematik fraktaler Mengen beitragen kann.

## Widmung

Diese Zusammenstellung ist dem deutschen Mathematiker und Physiker Reinhart Behr (* 1928; † 2003) gewidmet. Der Hauptautor dankt ihm für seine Offenheit und Ansprechbarkeit als Gymnasiallehrer der Beethoven-Oberschule in Berlin-Lankwitz und für seine immerwährende Bereitschaft zur Förderung und Bildung seiner Schüler. Er konnte mit seinem beeindruckenden und breitgefächerten Wissen sowie mit der ihm eigenen und hervorragenden Didaktik auch anspruchsvolle Fragen meist aus dem Stand und umfassend beantworten.

## Literatur

* Heinz-Otto Peitgen und Dietmar Saupe: The Science of Fractal Images, Springer, Heidelberg, 1988, ISBN 0-387-96608-0.
* Reinhart Behr: Der Weg zur fraktalen Geometrie, Ernst Klett Schulbuchverlag, Stuttgart, 1989, ISBN 3-12-722410-9

## Siehe auch

* Strukturierte Programmierung
* Rekursive Labyrinthe
* Waldbrandsimulation

## Zusammenfassung des Projekts

„Das Apfelmännchen“ ist nach Einschätzung seiner Autoren zu 100 % fertig
* Zielgruppe: Informatiker, Mathematiker
* Lernziele: Erstellung fraktaler Julia-Mengen und der Mandelbrot-Menge mit einem Java-Programm.
* Buchpatenschaft/Ansprechperson: Benutzer:Bautsch
* Sind Co-Autoren gegenwärtig erwünscht? Ja, sehr gerne. Korrekturen von offensichtlichen Fehlern direkt im Text; Inhaltliches bitte per Diskussion.
* Richtlinien für Co-Autoren: Wikimedia-like.