Wie findet man eine Fraktalformel?

Ich veröffentliche hier ja immer wieder meine eigenen Formeln, die ich beim Experimentieren entdeckt habe. Einige von ihnen sehen interessant oder doch wenigstens „anders“ aus. Das erweckt vielleicht im einen oder anderen meiner Leser den Wunsch, selbst nach interessanten Formeln zu suchen und ein paar Experimente damit anzustellen.

In diesem Text setze ich die Möglichkeit zur Programmierung einer eigenen Formel voraus. Meine Beispiele sind im passenden Format für FRACTINT 20, sämtliche Bezeichner in den kurzen Programmen sind komplexe Zahlen.

Diese kurze Anleitung ist praktisch orientiert und richtet sich nicht primär an Menschen mit mathematischem Interesse, sondern an Menschen, die ebenfalls ein paar neue Fraktale entdecken und durch den unmittelbaren Augenschein erforschen wollen. Wer so viel mathematische Intuition hat, dass er seine Ideen durch abstrakte Betrachtungen findet, bedarf einer solchen Anleitung nicht.

Machen Sie sich mit der Programmiersprache vertraut!

Wenn Sie selbst Formeln programmieren wollen, egal ob in FRACTINT oder mit Hilfe völlig selbst geschriebener Programme, denn müssen Sie die dabei verwendete Programmiersprache beherrschen. Sie brauchen zunächst nicht jede Einzelheit zu kennen, aber einen groben Überblick sollten Sie sich auf alle Fälle verschaffen.

Wer schon einmal etwas programmiert hat, tut sich relativ leicht damit. Wer jetzt aber das erste Mal in seinem Leben mit dem Programmieren konfrontiert ist, steht gleichzeitig vor der Aufgabe, auch ein paar Grundlagen der Programmierung lernen zu müssen. Die Programmiersprache, in der sich Formeln für typische Fraktalprogramme formulieren lassen, ist zum Glück meist recht einfach aufgebaut, so dass man durch schnelle Erfolgserlebnisse ermutigt wird. Der größte Teil des Programmes ist bereits fertig, er muss nur durch die Startbedingungen, eine Iteration und die eventuelle Berücksichtung von Parametern ergänzt werden. Ein Fraktalprogramm aus dem Nichts in einer allgemeinen Programmiersprache zu schreiben, ist ungleich schwieriger.

Lesen Sie die Dokumentation quer! Schauen Sie sich an, wie eine Fraktalformel aufgebaut ist und probieren Sie die Beispiele aus. Wenn die Beispiele „laufen“, versuchen Sie, die Abläufe zu verstehen und schauen Sie in die Dokumentation, wenn Sie etwas nicht verstehen! So bekommen Sie relativ schnell einen Einblick in die Möglichkeiten der Programmierung und lernen auch, an welchen Stellen der Dokumentation sich welche Erklärungen finden. Gerade das Letztere ist wichtig, niemand kann alles im Kopf haben.

Schauen Sie sich bekannte Fraktale als Formel an!

Sicher, jeder Fraktalgenerator hat die Standardfraktale fest eingebaut, um die Rechengeschwindigkeit zu erhöhen. Deshalb brauchen Sie diese Formeln nicht zu kennen, wenn sie nur diese Fraktale berechnen lassen wollen.

Nehmen wir einmal das Apfelmännchen. Die Iterationsformel lautet, wenn man sie mathematisch als Reihenentwicklung ausdrückt, folgendermaßen:

zn+1 = zn2 + z0

Die Mandelbrotmenge ist dabei die Menge aller komplexen Zahlen, für die diese Iteration nicht über alle Grenzen wächst.

In normale Umgangssprache übersetzt, lautet diese Vorschrift: Der nächste Iterationswert wird bestimmt, indem der aktuelle Wert quadriert wird und der Startwert der Iteration hinzuaddiert wird. Wenn die Zahlen dabei innerhalb eines beschränkten Wertebereiches bleiben, handelt es sich um einen Punkt der Mandelbrotmenge. Bei der Programmierung macht man sich zu Nutze, dass ein Punkt nicht zur Mandelbrotmenge gehören kann, wenn bei der Iteration ein Folgeglied mit einem Betrag über 4 herauskommt, dies führt zur Formulierung einer einfachen Abbruchbedingung. Die darzustellenden Punkte der Mandelbrotmenge sind für das Program jene, bei denen die Iteration nach einer bestimmten Anzahl Durchläufen nicht diese Abbruchbedingung erfüllt hat.

Das ist noch kein Programm, sondern eine Beschreibung dessen, was das Programm tun soll. Was beim Programmieren zu tun ist, das ist die Übersetzung einer solchen Beschreibung in ein Programm, in eine Liste von Anweisungen, die vom Computer verstanden wird. Wenn man einen Fraktalgenerator benutzt, ist ein Teil dieser Programmierung bereits fertig, es muss im Wesentlichen die Iteration, eventuelle Vorbereitungen vor Beginn der Iteration und die Abbruchbedingung formuliert werden.

Damit man selbst sein Programm auch versteht, kann man es mit Kommentaren versehen, die vom Computer ignoriert werden. Gerade bei Passagen, die sich nicht von allein erklären, ist das empfehlenswert.

In FRACTINT könnte die Mandelbrotmenge etwa so programmiert werden (es ist nicht wirklich nötig, da sie „schon fertig“ in FRACTINT ist):

Mandelbrot {
;Startwert festhalten
c = pixel 
;Iterationswert festhalten
z = pixel
;Die Iterationsschleife beginnt
;mit einem Doppelpunkt
:
  ;Der Iterationswert wird quadriert
  ;und der Startwert hinzu addiert
  z = z * z + c
  ;solange dabei der Betrag des
  ;Iterationswertes kleiner 4 ist.
  |z| < 4
}

FRACTINT betrachtet alles, was nach einem Semikolon bis zum Zeilenende folgt, als Kommentar. Die Einrückungen in diesem Beispiel sind für FRACTINT unnötig, aber sie helfen mir beim Lesen. Ich verstehe den Ablauf besser, wenn die Iteration eingerückt ist. Der einfache Doppelpunkt als Trenner zwischen dem Vorbereitungsteil und dem Iterationsteil ist beim schnellen Lesen leicht zu übersehen; dies ist eine der Schwächen in der Syntax der FRACTINT-Formeln. Jeder Mensch entwickelt mit der Zeit seine eigene Konvention, wie er Programme so formatiert, dass er sie auch selbst versteht — und keiner schreibt Kommentare, in denen nur die verwendete Programmiersprache erklärt wird. Die Formel wird normalerweise sehr kompakt geschrieben:

Mandelbrot {
c = z = pixel
:
  z = z * z + c
  |z| < 4
}

FRACTINT wird mit einer großen Formeldatei ausgeliefert, die auch viele „bekannte“ Fraktale enthält. So können Sie sich sehr einfach mit der Programmierung vertraut machen und haben auch Ausgangsmaterial für etwaige Abwandlungen.

Wandeln Sie bekannte Formeln ab!

Und das leitet direkt zum „kreativen“ Teil dieser Anleitung über. Es ist relativ einfach, neue Fraktale aus bekannten Formeln abzuleiten, indem man kleine Abwandlungen an den Formeln vornimmt. Die meisten (aber nicht alle) meiner Entdeckungen sind so entstanden.

Der Vorteil dieser Vorgehensweise: Indem Sie von „guten“ Formeln ausgehen, haben Sie gute Chancen, andere „gute“ Formeln zu finden, die interessante Fraktale liefern.

Wenn man etwa die eben beschriebene, normale Mandelbrot-Iteration als Grundlage nimmt, gibt es viele Möglichkeiten, ein kleines Experiment hinzuzufügen.

E002 040Es ist ja nicht so, dass das „Apfelmännchen“ langweilig wäre. Man hat sich nur irgendwann daran sattgesehen und sucht nach neuen Formen. Wie würde es etwa aussehen, wenn man diese gut erprobte Iterationsformel so ändert, dass für die ersten 10 Durchläufe die normale quadratische Iteration verwendet wird, danach aber der aktuelle Wert nicht mehr quadriert wird, sondern statt dessen in die vierte Potenz erhoben wird, was ja für sich allein auch ein interessantes Fraktal ergibt? Dann wird doch die Grundform des „Apfelmännchens“ den Wertebereich der Iteration in einen gewissen Rahmen zwingen, bevor eine völlig andere Formel verwendet wird. Also die Idee mal schnell programmiert:

VierZwei {
i = 0
z = pixel
:
  if (i < 10)
    z = z * z + c
    i = i + 1
  else
    z = z * z * z * z + c
  endif
  |z| < 4
}

Und, wie sieht das aus? Oh, das ist ja durchaus interessant…

E002 041

Im Randbereich dieses Fraktales findet sich nun eine bunte Mischung aus Elementen der quadratischen Mandelbrot-Iteration und des Fraktales, das bei Anwendung der vierten Potenz entsteht, es sind aber zusätzlich auch weitere Formen bei dieser Überlagerung entstanden:

E002 042

Die Ergebnisse solcher Experimente sind immer wieder überraschend.

Machen Sie ihre Experimente parametrisierbar!

Es kann umständlich sein, jedes Mal die Formel zu editieren, wenn beim Experimentieren nur mal eben eine Zahl geändert werden soll. Im vorherigen Beispiel war das die Zahl 10, die Anzahl der Iterationen, nach der die Formel gewechselt werden soll. Es bietet sich an, mit dieser Zahl bei Experimenten herumzuspielen.

Die meisten Fraktalgeneratoren erlauben die Angabe von Parametern. Bei FRACTINT ist es dafür völlig ausreichend, die Variablennamen p1, p2, p3 oder p4 zu benutzen, diese Variable kann dann eingegeben werden.

Ein weiteres Feld für mögliche Experimente ist der Versuch, Julia-ähnliche Mengen aus einer solchen Iteration zu machen. Auch hier hat FRACTINT einen bestimmten Variablennamen vorgesehen, er lautet ismand. Wenn er definiert ist, kann in gewohnter Weise auf die Julia-Darstellung umgeschaltet werden, der Parameter der Julia-Darstellung wird dann als Parameter p1 übergeben. Es ist relativ leicht, diese beiden Verbesserungen in das Programm einzubauen, und der Spaß beim Erforschen des neuen Fraktales steigt davon ungemein:

VierZwei {
i = 0
z = pixel
if (ismand)
  c = z
else
  c = p1
endif
:
  if (i < real(p2))
    z = z * z + c
    i = i + 1
  else
    z = z * z * z * z + c
  endif
  |z| < 4
}

Zugegeben, die Struktur der Formel ist jetzt etwas komplexer geworden. Außerdem hat sich beim Parameter p2 noch eine kleine Tücke versteckt. Der Parameter ist eine komplexe Zahl, und um diese mit dem Iterationszähler vergleichbar zu machen, wird nur der Realteil verwendet. Dennoch ist die Erweiterung einfach und leicht durchschaubar, und nun lassen sich sehr leicht Julia-artige Mengen dieses Fraktales untersuchen. Diese sehen zum Teil sehr ansprechend aus, da sich auch hier Elemente verschiedener Fraktale kombinieren:

E002 045

Damit sind aber die Möglichkeiten noch lange nicht abgeschlossen.

Machen Sie Funktionen parametrisierbar!

Sehr viele Fraktalgeneratoren ermöglichen auch Funktionen als Parameter. Bei FRACTINT können bis zu vier Funktionen auswählbar gemacht werden, indem die Funktionsnamen fn1, fn2, fn3 und fn4 verwendet werden.

Wenn wir etwa unser kleines Experiment untersuchen, stellen wir folgendes fest. Zunächst wird für eine bestimmte Anzahl Iterationen eine Funktion (das Quadrieren) ausgeführt, darauf folgend wird eine zweite Funktion (in unserem Fall ist das wiederum das Quadrieren) ausgeführt, die aber nochmals quadriert wird. Es bietet sich an, diese beiden Funktionen austauschbar zu machen, was zu einer nur wenig komplexeren Programmierung führt.

FunktionsWechsel {
i = 0
z = pixel
if (ismand)
  c = z
else
  c = p1
endif
:
  if (i < real(p2))
    z = fn1 (z) + c
    i = i + 1
  else
    t = fn2 (z)
    z = t * t + c
  endif
  |z| < 4
}

Die zusätzliche Variable t ist eine kleine Optimierung, die das Programm schneller machen soll. Viele Funktionen werden sehr aufwändig berechnet, und die doppelte Berechnung der gleichen Funktion sollte deshalb besser vermieden werden.

Wenn hier für fn1 und fn2 jeweils die Funktion sqr (Quadrieren) angegeben wird, entsteht das bereits betrachtete Fraktal, nur dass die Berechnung ein wenig, aber spürbar länger dauert. Aber nun können beliebige Funktionen in diese Iteration eingefügt werden, die zum Teil sehr reizvolle Fraktale ergeben, wobei vor allem die Julia-Darstellungen manchmal sehr hübsch geraten. Die folgenden Bilder sind nur kleine Beispiele:

E002 052

E002 048

E002 051

Dass es sich um eine einfache, beinahe triviale Veränderung der gewöhnlichen Mandelbrot-Iteration handelt, ist angesichts des Formenreichtums dieses neuen Fraktales kaum zu erraten.

Es ist eigentlich überflüssig, zu erwähnen, dass nicht bei jedem derartigen Experiment ein interessantes Fraktal gefunden wird. Tatsächlich führen viele derartige Experimente zu wenig ansprechenden Formen, häufig lässt sich aber die Idee doch noch durch kleine Änderungen retten. Ich hätte das gern in diesem Text demonstriert, aber ich hatte heute ein gutes Händchen. Und warum soll man nicht einmal demonstrieren, dass man „Glück“ hat. 😉

Über 124c41

Gaga singt Dada aus der Statt der tausend Dröhne. Ein marginalisierter macht merglig kunst aus künstlich wohrten. Sieben schnabel überdruss.

Hinterlasse einen Kommentar