Hinweis: Wäre JavaScript aktiviert würden die Bilder in den Fraktal-Galerien als Popup erscheinen und zusätzliche Informationen würden eingeblendet....
Hinweis: Wäre JavaScript aktiviert würden die Bilder in den Fraktal-Galerien als Popup erscheinen und zusätzliche Informationen würden eingeblendet....
Wait...
3D-Fraktale
Julia-, Mandelbrot-,
Mandelbulb- und Mandelbox-Fraktale
(und auch ein paar 2D-Fraktale)
Für Eilige
Schnitt durch ein Mandelbrot Julia-Fraktal Juliabulb-Ausscnitt Mandelbox

Für alle die ja doch nur wieder Bildchen schauen wollen geht's hier direkt zur Galerie...
Was sind Fraktale?

Für alle die es bis hierher geschafft haben :-) folgt nun eine kurze Einführung in die Thematik...
"Normale" (nicht fraktale) Gebilde haben die Eigenschaft, dass man ab einer bestimmten - wenn auch unter Umständen sehr hohen - Auflösung alle Details erkennen kann. Fraktale unterscheiden sich genau in dieser Hinsicht, denn bei Fraktalen kann man beliebig kleine Teilbereiche (engl.: " fractions ") betrachten und bekommt immer wieder gleichermaßen komplizierte Strukturen zu Gesicht. Normalerweise sieht das was man in verschiedenen Auflösungen sieht immer wieder ähnlich aus. Diese Selbstähnlichkeit ist ebenfalls eine typische Eigenschaft von Fraktalen.

2D-Julia-Fraktal (links) mit Ausschnittsvergrößerungen  (mitte und rechts...
und das Zoomen liesse sich beliebig oft wiederholen - es sähe immer ähnlich aus)
Das Fraktal selbst ist schwarz, die Umgebung hier bunt dargestellt.

Die Tatsache, dass die Strukturen bei höheren Auflösungen nicht einfacher werden kann mit der "Fraktalen Dimension" bzw. "Hausdorff-Besikovitch-Dimension" beschrieben und gemessen werden:

Fraktale Dimension (Hausdorff-Besikovitch-Dimension):
Dim  =
ln(c)
ln(a)
c = Segmentvermehrungs-Faktor
a = Zoomfaktor

Hierzu wird der Darstellungs-Raum (üblicherweise entweder zwei- oder aber dreidimensional) zunächst in ein Raster aus Segmenten einer bestimmten Kantenlänge k unterteilt (Quadrate im R2, oder Würfel im R3).
  • Nimmt man nun eine Linie, die in n Segmenten liegt, so wird diese bei einer Verdoppelung der Auflösung (Halbierung von k) doppelt so viele Segmente umfassen. Dieses ergibt nach obiger Formel die Dimension 1 (ln(2)/ln(2)), was man ja auch erwarten sollte.
  • Ein Rechteck, das zunächst k Segmente füllt, wird bei einer doppelten Auflösung viermal so viele Segmente umfassen. Auch damit erhält man die erwartete Dimensionszahl von 2 (ln(4)/ln(2)).
  • Ein Quader, der k Segmente füllt wird bei doppelter Auflösung achtmal so viele Segmente beanspruchen. Wiederum ergibt sich erwartungsgemäß die Dimensionszahl 3 (ln(8)/ln(2)).
Auch andere Zoom-Faktoren als 2 ändern an diesen Dimensionalitäten nichts, wie man sich leicht überlegen kann.
Für ein komplizierteres Objekt als es z.B. ein Quader ist, welches aber selbst aus einzelnen Quadern zusammengesetzt ist, kann man natürlich eine Auflösung finden, die zu niedrig ist als dass alle Details des Objekts erkennbar würden. Jedoch lässt sich eine Anfangsauflösung bestimmen, die hinreichend hoch ist damit alle Details differenziert werden können. Ausgehend von diesem Auflösungsgrad ergeben sich für höhere Auflösungen die erwarteten Dimensionalitäten (also 3 für ein Objekt, welches aus Quadern besteht; 2 für ein Objekt aus Rechtecken und 1 für ein Objekt aus Linien).
Dieses gilt aber nicht für Fraktale, bei denen ja bei jeder "verbesserten" (höheren) Auflösung nur wieder weitere Details zum Vorschein kommen, welche in ihrer Komplexität denen zuvor schon erkennbaren größeren Strukturen nicht nachstehen. Für solche Objekte wird die Dimensionszahl größer als eigentlich erwartet. Dabei muss man aber darauf achten, was denn das "fraktale" an dem Fraktal ist. Bestimmt man die Fläche des oben dargestellten "2D"-Julia-Fraktals durch Zählen der Bildpixel bei verschiedenen Auflösungen erhält man die Dimensionszahl 2. Damit besitzt die Fläche keine fraktalartigen Eigenschaften! Das Fraktal hat jedoch eine fraktale Umrisslinie, für die sich eine Dimension >1 (hier ca. 1.25) ergibt. Zu deren Bestimmung kann man die Bild-Pixel, die am Rand des Fraktals liegen bei verschiedenen Auflösungen zählen.
Für künstlich erzeugte Fraktale ist die Dimensionszahl weitgehend unabhängig von der Anfangsauflösung und dem Zoom-Faktor. Für die vielen Fraktaltypen die durch rekursive Prozesse gebildet werden ist diese Eigenschaft oft sogar unmittelbar aus dem Konstruktionsprinzip (Rekursion) ableitbar1). Auch natürliche Prozesse können fraktale Strukturen hervorbringen - ein schönes und bekanntes Beispiel sind Küstenlinien. Für diese kann die Fraktale Dimension aber stark von der Auflösung abhängen und bei höheren Anfangsauflösungen bis auf Normal-Niveau (d.h. Nicht-Fraktal-Niveau) absinken.


1)
Schönes Beispiel ist das "Schneeflocken-Fraktal", an dem sich die Fraktale Dimension auch besonders schön erklären lässt, was aber von den hier verwendeten Fraktaltypen wegführen würde.
Mandelbrot und Julia
Im Weiteren beschränke ich mich auf  Mandelbrot- und Julia-Fraktale, die sicher zu den bekanntesten Fraktaltypen zählen. Sie sind nicht "per Definition" (durch ihre Konstruktionsvorschrift) schon dazu "verdammt" Fraktale zu sein, sondern entstehen "zufällig" aus extrem einfachen rückgekoppelten Systemen. Das schon solch einfache Systeme derartig komplexe Strukturen erzeugen und damit ein analytisch nicht mehr vorhersagbares ("chaotisches") Verhalten an den Tag legen ist ein Umstand der in vielen Bereichen große Probleme aufwirft. Die Regelung solcher Systeme ist i.d.R. alles andere als trivial. Nur sind ja eigentlich alle dynamischen Vorgänge (also eigentlich alle realen Prozesse) in diesem Sinne rückgekoppelte Systeme, da der zukünftige Systemzustand u.a. vom aktuellen Zustand abhängt. Andererseits macht genau das die Sache erst spannend - und nett anzusehen sind die Dinger obendrein auch noch...
Schnitt durch
                        Apfelmännchen
Das berühmte Apfelmännchen (also das Mandelbrot-Fraktal)

2D-Julia- oder Mandelbrot-Fraktale werden mit Hilfe von komplexen Zahlen berechnet.  Dabei werden Real- und Imaginär-Teil einer komplexen Zahl als X- bzw. Y-Koordinate interpretiert. Statt der "zweidimensionalen" komplexen Zahlen werden für 3D-Julia- und Mandelbrot-Fraktale (letztere machen nur begrenzt Sinn) Quaternions (oder auch Hypercomplex Numbers) verwendet. Diese bestehen aus 4 statt aus 2 Komponenten. Davon werden die ersten drei als X-, Y- und Z-Koordinate interpretiert 1), während die letzte ("überflüssige") Komponente für ein bestimmtes Fraktal auf einen festen Wert gesetzt wird. "Vierdimensionale" Zahlensysteme verwendet man übrigens nur deshalb, weil es offenbar keine in sich konsistenten "dreidimensionalen" Zahlensystem gibt2).

Berechnungsvorschriften für komplexe Zahlen / Quaternions:


 
 
Komplexe Zahlen:  
 
Quaternions:
Addition C = A+B:

 C.r = A.r+B.r
 C.i = A.i +B.i


 C.x = A.x + B.x 
 C.y = A.y + B.y
 C.z = A.z + B.z
 C.w = A.w + B.w
Multiplikation C = A*B:


 C.r = A.r * B.r - A.i * B.i
 C.i = A.r * B.i + A.i * B.r


 C.x = A.x * B.x - A.y * B.y - A.z * B.z - A.w * B.w
 C.y = A.x * B.y + A.y * B.x + A.z * B.w - A.w * B.z
 C.z = A.x * B.z + A.z * B.x + A.w * B.y - A.y * B.w
 C.w = A.x * B.w + A.w * B.x + A.y * B.z - A.z * B.y
( X.r = Real-Teil, X.i = Imaginär-Teil ;   X.x, X.y, X.z, X.w = Quaternion Komponenten )

Im Übrigen ist die Berechnungsvorschrift  für 2D- und 3D-Fraktale identisch. Und darüber hinaus auch erfreulich einfach - was in gewisser Weise wiederum erschreckend ist, wenn man bedenkt was für komplexe Strukturen damit erzeugt werden.

Folgende Reihe wird evaluiert:


 
Z' = (Z*Z)+C
alternative Darstellung: 
Z(i+1) = (Z(i)*Z(i))+C ,     i=0,1,2,...
( i = Iterations-Zähler )

Ziel der Berechnung ist zu entscheiden ob ein Punkt (2D: (X,Y), 3D: (X,Y,Z)) der Mandelbrot- bzw. Julia-Menge angehört. Entscheidend für die Mengenzugehörigkeit ist die Entwicklung der Z-Werte in oben genannter Reihe:

  • Entfernt sich Z immer weiter vom Ursprung, d.h. der Abstand geht gegen Unendlich, so gehört der Wert nicht zur Mandelbrot-/Julia-Menge.
  • Konvergiert die Reihe aber oder oszilliert sie zwischen verschiedenen Punkten, so gehört der Wert der Julia-/Mandelbrot-Menge an.

Um einen Wert sicher der jeweiligen Menge zuordnen zu können müsste diese Reihe (leider) für unendlich viele Schritte berechnet werden - denn das chaotische Verhalten dieser Reihe mach es unmöglich den Ausgang einfacher (analytisch) vorherzusagen. Umgekehrt kann dagegen wenigstens die Mengenzugehörigkeit für einen Z-Wert, dessen Abstand zum Ursprung >2 ist mit Sicherheit ausgeschlossen werden (die Reihe geht danach sicher gegen Unendlich). Zur Abschätzung (in endlicher Zeit) wird die Reihe spätestens nach einer festen Anzahl (MaxIter) von Schritten abgebrochen. Wird innerhalb dieser Schrittanzahl der Abstand 2 zum Ursprung nicht erreicht, so wird der Wert als der Menge angehörig angesehen (teilweise wird aus Effizienzgründen bereits bei kleineren Abständen abgebrochen, s.u.: BailOut ).
Kleinere Werte für MaxIter und BailOut führen jeweils dazu, dass mehr Werte (fälschlich) den Mengen zugeordnet werden. Die fraktalen Strukturen in den Randbereichen  werden dadurch weniger gut herausgearbeitet.

Abbruchbedingung (Wert nicht inMandelbrot-/Julia-Menge):

Bedingung 1:  
 
sqrt(Z1(i)2 + ... + Zk(i)2) > BailOut,  
 
(harte Bedingung, wenn BailOut >= 2)
Bedingung 2:

i >MaxIter

(Heuristik)
( k = Anzahl der Komponenten  2D: k = 2 (real, imaginär), 3D: k = 4 )

Um die Mandelbrot- bzw. Julia-Mengen zu berechnen wird die Formel unterschiedlich angewendet:

  • Für die Mandelbrot-Berechnung ist C der zu berechnende Punkt (d.h. die Komponenten der komplexen (hyper-komplexen) Zahl C entsprechen den Koordinaten des fraglichen Punkts z.B.: C.real = X und C.imag=Y). Z wird dagegen auf "0" gesetzt (alle Komponenten = 0, für 2D also Z.real = 0 und Z.imag=0).
  • Für die Julia-Berechnung entspricht das (initiale) Z (auch Z(0) geschrieben) dem fraglichen Punkt während C beliebig aber fest gewählt ist. C sollte dabei der Mandelbrot-Menge angehören, um eine nicht leere Julia-Menge zu erhalten. Interessant sind insbesondere C-Werte aus dem "Randbereich" der Mandelbrot-Menge. Setzt man C dagegen auf den Koordinatenursprung (alle Komponenten auf 0) so entsteht gar kein Fraktal, sondern ein Kreis (2D) bzw. eine Kugel (3D).
Initialisierung:


 
 
2D  
 
3D
Mandelbrot:


 Z(0) = (0,0),
C = (X,Y)


 Z(0) = (0,0,0,0), C = (X,Y,Z,T), T=const
Julia:


 Z(0) = (X,Y),
C aus M-Set


 Z(0) = (0,0,0,0), C aus M-Set
(M-Set = Mandelbrot-Menge)

Man kann viele interessante Variationen erzeugen indem man die, in diesem Kapitel vorgestellten, Berechnungsvorschriften verändert (viele der unten gezeigten Fraktale sind nicht mit dem "originalen" Berechnungsschema entstanden, sondern mit solchen Abwandlungen. Da die Beschreibung, der von mir verwendeten speziellen Fraktalberechnungsarten aber recht länglich ist, habe ich dieses Kapitel hierher ausgelagert. Zudem habe musste ich inzwischen erkennen, dass diese Formeln alle reichlich instabil sind und die Menge eigentlich leer ist und nur durch einen nicht allzu hoch gewählten Parameter MaxIter überhaupt (und damit eigentlich fälschlich) Punkte der Menge zugeordnet werden. Trotzdem sind einige ganz nette Strukturen dabei. Zwei Abwandlungen verdienen allerdings besondere Beachtung und werden im nächsten Kapitel beschrieben.


1)
 
Quaternions werden auch zur Berechnung von Transformationen im R3 benutzt. Dabei korrespondieren aber die letzten drei Komponenten mit X, Y und Z. Dadurch sollte man sich bitte nicht verwirren lassen...
2)
Hamilton, der die Quaternion-Zahlen entdeckte, hat vorher jahrelang erfolglos nach dreiwertigen Zahlen gesucht.
Mandelbulb und Mandelbox
Diese beiden Abwandlungen des normalen 3D-Mandelbrot-Fraktals habe ich selbst erst kürzlich im Internet entdeckt.

Mandelbulb Mandelbox
Mandelbulb (links) und Mandelbox (rechts)

Das Mandelbulb-Fraktal geht zurück auf eine Formel von Daniel White (der auch wunderschöne Fraktal-Bilder auf seiner Seite hat). Das Problem an der oben beschriebenen Form 3D-Mandelbrot-Fraktale mit Quaternion-Zahlen zu berechnen besteht darin, dass die 3D-Form nur dadurch entsteht, dass die Form um die X-Achse rotiert und die feinen Strukturen entsprechen zu ringförmigen Strukturen langgezogen werden (unten in der Galerie ist ein Bild auf dem das schön zu erkennen ist). Bei 3D-Julia-Fraktalen ist das Problem nicht ganz so offensichtlich, da die Rotationsverzerrung komplexer ist, prinzipiell ist es aber auch hier vorhanden. Die Formel von White definiert die Operationen für das Quadrieren und die Addition auf dreiwertigen Zahlen und führt zu einem Mandelbrot-Fraktal in dem die feinen Strukturen kleine "Knollen" ("Bulbs") formen. Da diese Knollen dann beliebig klein werden kommt ein Problem zum Tragen, das ich bisher völlig ignoriert hatte - doch dazu im nächsten Kapitel mehr, hier erstmal die Formel:

Berechnungsvorschriften für Mandelbulbs:
Da die Funktionen Sinus, Cosinus, Asin und Atan2 relativ langsam sind kann man diese auch vermeiden, was hier (nur) für den häufigsten Fall von Mandelbulbs achter Ordnung gezeigt ist:




Mandelbulb:

Mandelbulb (speziell für n=8):
Addition C = A+B:

 C.x = A.x + B.x
 C.y = A.y + B.y
 C.z = A.z + B.z


(identisch)
Multiplikation C = A*A:


 C.x = rn * cos(theta) * cos(phi),
 C.y = rn * sin(theta) * cos(phi),
 C.z = rn * -sin(phi)

 mit:
 r = sqrt(A.x2 + A.y2 + A.z2),
  theta = n * atan2(A.y, A.x),
 phi = n * asin(A.z / r),
 wobei n die "Ordnung" angibt (üblicher Weise n=8)


Wenn A.x = 0 und A.y = 0:
C.x = C.y = C.z = 0  (also C = (0,0,0))     
Sonst:
C.x =  64*x*z*y*(x2-y2)*k4*(x4-6*x2*y2+y4)*k1*k2
C.z = -16*z2*k3*k4*k4 + k1*k1
C.y = -8 * z * k 4 * (x 4 *x 4 - 28*x 4 *x 2 *y 2
                             + 70*x
4*y4 - 28*x 2*y2*y4
                             + y
4*y4) * k1 * k2
C.w = 0
 
mit:

x2 = A.x2

y2 = A.y2
z2 = A.z2

x4 = x22
y4 = y22
z4 = z22
   
k3 = x2 + y2
k2 = 1 / sqrt(k37)
k1 = x4 + z4 + y4 - 6*z2*y2 - 6*x2*z2 + 2*y2*x2
k4 = x2 - z2 + y2
(X.x, X.y, X.z = Dreiwertige Zahlen)

Vielleicht sogar noch interessanter ist das Mandelbox-Fraktal, das mit folgender Berechnungsformel entsteht und welches (anders als das Mandelbulb und "normale" Mandelbrot- und Julia-Fraktale) in beliebigen hoch-dimensionalen Räumen gebildet werden kann (der Einfachheit halber beschreibe ich es hier für den dreidimensionalen Fall, obwohl ich intern alle Fraktale mit den vierdimensionalen Quaternions berechne, wobei für Mandelbulbs die vierte Komponente ungenutzt bleibt). Hier die Formeln:

Berechnungsvorschriften für Mandelboxes:


 
 
Mandelbox:
Addition C = A+B:

 C.x = A.x + B.x
 C.y = A.y + B.y
 C.z = A.z + B.z
 ...
Multiplikation C = A*A:


if v.x > 1: v.x =  2 - v.x
elseif v.x < -1: v.x = -2 - v.x
if v.y > 1: v.y =  2 - v.x
elseif v.y < -1: v.y = -2 - v.x
if v.z > 1: v.z =  2 - v.x
elseif v.z < -1: v.z = -2 - v.x
...


v.x = v.x * f
v.y = v.y * f
v.z = v.z * f 
...

m2 = |a|2
if m2 < r2: a.x = a.x / r2
a.y = a.y / r2
a.z = a.z / r2
...
elseif m2 < 1: a.x = a.x / m2
a.y = a.y / m2
a.z = a.z / m2
...

v.x = v.x * s
v.y = v.y * s
v.z = v.z * s
...

standardmäßig mit:
s = 2 (scale)
f = 1
r = 0.5 (radius)
(X.x, X.y, X.z, ... = Mehrwertige Zahlen)

Fraktale in der Natur
Ich wurde bereits gefragt, ob es Mandelbrot- und Julia-Fraktale auch in "echt", also in der Natur gibt. Prinzipiell haben viele natürliche Strukturen fraktale Eigenschaften. Wobei natürlich in der Natur nicht unendlich kleine Ausschnitte vergrößern kann, ohne das irgendwann der Detaillierungsgrad abnimmt - von wegen kleinste Bausteine der Materie und so... Andersherum gibt es auch Fraktale, die eindeutig natürliche "Vorbilder" haben - das bereits erwähnte Schneeflockenfraktal, oder Fraktale, die farnähnliche Gebilde hervorbringen sind Beispiele dafür. Aber gibt es auch Entsprechungen für Mandelbrot- und Julia-Fraktale?
Es gibt einige Seiten die Kornkreise anführen. Die Seiten, die ich gesehen haben schwurbeln da fröhlich von "absolut exakten" Fraktalen, obwohl auf den (meist schlechten) Bildern nur andeutungsweise das Apfelmännchen oder ähnliche Strukturen abgebildet sind, die meist einfach aus  Kreisen zusammengesetzt sind und außerdem eben gerade nicht sonderlich exakt wirken. Na gut nach der langen Reise kann man von den Außerirdischen auch wirklich nicht verlangen noch aufwändigere Gebilde in das Kornfeld zu latschen. Aber "fraktal" sind diese Strukturen nun wirklich nicht, dafür brauchts dann schon einen gewissen Detaillierungsgrad...
Die beste Entsprechung für ein 2D-Mandelbrot- / Julia-Fraktal, die mir bisher untergekommen ist, ist der unten abgebildete "Embaise de Almendra", ein Stausee in Spanien den ich kürzlich aus dem Flugzeug heraus erblickte und natürlich sofort ablichten musste. Gerade in Spanien gibt es aber noch einige weitere Stauseen, die zumindest auf der Karte auch in diese Richtung gehen. Viel darf man da aber (meiner Meinung nach) nicht hineininterpretieren, es handelt sich einfach um eine zufällige Ähnlichkeit...

Embaise de
                        Almendra
Der Stausee "Embaise de Almendra" in Spanien sieht doch tatsächlich ein bisschen wie ein Julia- oder ein Ausschnitt aus dem Mandelbrot-Fraktal aus.


Darstellung 2D / 3D
2D- und 3D-Darstellungen unterscheiden sich in einer Beziehung deutlich:
  • bei 2D-Fraktalen wird die eigentliche Menge normalerweise einheitlich schwarz dargestellt, während die umliegenden (nicht der Menge angehörenden Werte) z.B. entsprechend ihrer "Fluchtgeschwindigkeit" (Anzahl Schritte bis ein Abstand >2 vom Ursprung erreicht wird) eingefärbt werden. Natürlich kann man über diesen Weg auch eine Höheninformation generieren und das Fraktal damit dreidimensional darstellen. Tatsächlich sind die meisten Fraktale, die man als 3D-Fraktale findet derartige Darstellungen zweidimensionaler Fraktale (siehe auch letztes Bild der Galerie).
  • bei 3D-Fraktalen wird die Menge selbst als dreidimensionaler Körper dargestellt, die umliegenden Bereiche sind hingegen "durchsichtig" (Luft). Im einfachsten Fall lässt man das Fraktal selbst einfarbig. Man kann aber auch ähnlich dem 2D-Fall "Nebenprodukte" der Berechnung zur Farbgebung verwenden. Z.B. kann man den Z-Wert beim Abbruch (nach MaxIter-Schritten) heranziehen und die ersten drei Komponenten in RGB-Werte umrechnen (so haben die meisten unten gezeigten Fraktalen ihre Farben erhalten). Allerdings gibt das sehr pixelige Farb-"Verläufe". Bessere Methoden werden unten besprochen. Bei einem Schnitt durch das Fraktal kann man auch wieder das Fraktal durchsichtig und die umliegenden Bereiche farbig machen, so dass sich das Frakal als Negativ in einem "soliden" Block darstellt  (Beispiele dafür sind unten in der Galerie zu finden).
Ein weiterer Unterschied besteht darin, dass man bei einem 2D-Fraktal einfach alle (X,Y)-Punkte des darzustellenden Bereichs berechnet, während man bei einem 3D-Fraktal zweckmäßiger Weise versucht, den Bereich in dem sich das darzustellende "Objekt" befindet, möglichst gut einzugrenzen ("Fraktal du bist umzingelt"), um nicht die vielen Punkte eines (X,Y,Z) Raumes abarbeiten zu müssen.

Distance-Estimation eines Julia-Fratals Distance-Estimation eines Mandelbrot-Fratals
Schnitt durch ein Julia-Fraktal (links) und ein Mandelbrot-Fraktal (rechts), wobei die Punkte entsprechend des geschätzten Abstands eingefärbt wurden (rot=nah, über gelb, grün und blau=fern). Man sieht u.a. auch, dass das Abstandsmaß innerhalb des Fraktals nicht funktioniert.

Häufig wird dabei ein Ansatz verwendet, der ein Abstandsmaß verwendet, welches für jeden Punkt im Raum angibt wie weit der nächstliegende Punkt des Fraktals noch entfernt ist (allerdings nicht in welcher Richtung). Man geht also von einem Punkt p immer soweit in Richtung des virtuellen Licht-Strahls voran, wie es der, für diesen Punkt p berechnete Abstandswert erlaubt und prüft dann erneut (der nächstliegende Punkt kann sich ja seitlich von der Geraden (des "Strahls") befinden auf der man sich bewegt, man "fliegt" also an diesem nächsten Punkt vorbei und nähert sich danach ggf. einem anderen Punkt). Ein solches Abstandsmaß bietet auch eine elegante Möglichkeit, die Oberfläche eines Fraktals zu glätten, indem man alle Punkte die nicht weiter als ein bestimmter Abstand vom eigentlichen Fraktal entfernt sind, ebenfalls noch als dem Fraktal zugehörig ansieht. Dies ist insbesondere für die oben besprochenen Mandelbulb- und Mandelbox-Fraktale notwendig, die sehr fein strukturierte Oberflächen besitzen. Daher verwende ich inzwischen auch diesen Ansatz, der darüber hinaus den Vorteil hat, dass man das Fraktal "on-the-fly" rendern kann, ohne dessen Oberfläche zunächst in eine Struktur "scannen" zu müssen, was einen sehr großen Speicherbedarf zur Folge haben kann... Bei Interesse kann man einige Details zu dem Rendering-Verfahren hier nachlesen.

Ray-Marching
Das Abstandsmaß wird benutzt um sich schnell der Oberfläche anzunähern. Für den Ausgangspunkt eines "Lichtstrahls" wird damit der Abstand berechnet, dann bewegt man sich um diesen Abstand weiter auf dem Strahl und berechnet das Abstandsmaß für diesen neuen Punkt, usw., bis man sich der Oberfläche weit genug angenähert hat.


Abstandsmaß für Mandelbrot- und Julia-Fraktale:
Der Abstand d ist durch folgende Formel gegeben:

d = 
G  1)
|G'|
wobei gilt:
G
lim
n to Inf

 
1  
log(|Zn|)
  2)
pn

Dabei ist n die Anzahl von Iterationen (bis zum Abbruch) und p ist die Potenz von Z; bei normalen Mandelbrot-/Julia-Fraktalen ist p=2 (daZ = Z2 + C), bei Mandelbulbs wird dagegen häufig mit der achten Potenz gerechnet, demnach wäre hier p=8.


Für normale Mandelbrot-/Julia-Fraktale kann die Formel für |G'(c)| bestimmt werden durch:

|G'|= 
lim
n to Inf
 
1
 
|Z'n|
pn |Zn|

Wobei Z' die Ableitung von Z = Z2 + C ist, was wiederum selbst eine Reihe darstellt, die parallel zu Z evaluiert wird:

initial: 
Z'0 = (1,0,0,0)
folgende: 
Z'i+1 = 2 Zi Z'i  (Julia)
bzw.: 
Z'i+1 = 2 Zi Z'i + 1  (Mandelbrot1))

Damit bestimmt sich der Abstand d zu:

  d = 
lim
n to Inf
 
|Zn| log(|Zn|)
|Z'n|

Leider ist Z'n nicht direkt als Normalenvektor zu gebrauchen. Bisher habe ich nur für Mandelbrot-Fraktale herausgefunden, wie sich der Normalenvektor aus Z'n berechnen lässt.2)
Für Mandelbulb- und Mandelbox-Fraktale sind zwar ebenfalls Ableitungen bekannt, diese sind jedoch insbesondere für das Mandelbulb-Fraktal recht komplex. Ich benutze daher (nach einer Idee von Iñigo Quilez, bei der ich allerdings immer noch nicht ganz sicher bin, ob ich das ganz richtig umgesetzt habe) die "Rohform" der Formel, wie sie durch Formel 1) beschrieben ist. G lässt sich mit der Formel 2) abschätzen indem man das letzte Zn benutzt. Der Faktor 1/pn kürzt sich heraus, wodurch die Potenz p keine Rolle mehr spielt. Der Gradient G' wird näherungsweise bestimmt, indem man die Reihe Z = Z*Z + C nicht nur mit einem initialen Wertepaar für Z und C beginnt, sondern noch ein bis zwei Nachbarn in jeder Dimension evaluiert. Für Quaternion-Zahlen also zusätzlich zu Z0 und C0 auch für folgende Paare (wobei je nach Fraktal-Typ nur entweder C oder Z mit einem Offset versehen wird, während der jeweils andere Wert eines Wertepaares auf C0 bzw. Z0 gesetzt wird):

Julia

 
Mandelbrot
Z0 = (Z.x, Z.y, Z.z, Z.t),  

C0 = (C.x, C.y, C.z, C.t)
Z1 = (Z.x + r, Z.y, Z.z, Z.t), C1 = (C.x + r, C.y, C.z, C.t)
Z2 = (Z.x - r, Z.y, Z.z, Z.t), C2 = (C.x - r, C.y, C.z, C.t)
Z3 = (Z.x, Z.y + r, Z.z, Z.t), C3 = (C.x, C.y + r, C.z, C.t)
Z4 = (Z.x, Z.y - r, Z.z, Z.t), C4 = (C.x, C.y - r, C.z, C.t)
Z5 = (Z.x, Z.y, Z.z + r, Z.t), C5 = (C.x, C.y, C.z + r, C.t)
Z6 = (Z.x, Z.y, Z.z - r, Z.t), C6 = (C.x, C.y, C.z - r, C.t)
Z7 = (Z.x, Z.y, Z.z, Z.t + r), C7 = (C.x, C.y, C.z, C.t + r)
Z8 = (Z.x, Z.y, Z.z, Z.t - r), C8 = (C.x, C.y, C.z, C.t - r)

Wobei r ein möglichst kleiner Offset ist (der aber noch zu numerisch stabilen Ergebnissen führt - ich arbeite derzeit mit r=10-8).
Für die höchste Genauigkeit nimmt man dann alle Nachbarn und bildet die mittleren Differenzen:

G' = ((G1 + G2) / (2 * offset), (G3 - G4) / (2 * offset), (G5 - G6) / (2 * offset), (G7 - G8) / (2 * offset))

Man kann aber auch nur die Hälfte der Nachbarn (gerade oder ungerade) nehmen (also nur halb soviele zusätzliche Reihen evaluieren), dann ist:

G' = ((G0 - G1) / offset, (G0 - G3) / offset, (G0 - G5) / offset, (G0 - G7) / offset)
oder
G' = ((G2 - G0) / offset, (G4 - G0) / offset, (G6 - G0) / offset, (G8 - G0) / offset)

Für Julia-Fraktale gilt dann:
|G'| = sqrt(G'.x2 + G'.y2 + G'.z2 + G'.t2)

während für Mandelbrot-Fraktale
|G'| = sqrt(2) * sqrt(G'.x2 + G'.y2 + G'.z2 + G'.t2)
besser passt (warum weiß ich leider nicht genau).
Interessant an dieser Variante ist aber dass G' (bzw. die ersten drei Komponenten von G') auch gleich als Normalenvektor genutzt werden kann! Damit kann man sich eine ähnlich aufwändige Berechnung der Normalenvektoren, wie sie bei den "Ableitungs-Verfahren" noch nötig wäre sparen, weshalb ich momentan grundsätzlich diese Variante benutze.

Die Evaluierung der Reihe wird übrigens bereits vor Erreichen von MaxIter abgebrochen, wenn der quadrierte Abstand von Z0 größer wird als 1020, oder der Abstand von Z0 zu einem seiner Nachbarn Z1..8 größer wird als r/100. Beides hat numerische Gründe, da die Berechnung sonst instabil wird, oder im nächsten Schritt die im Rechner darstellbaren Bereiche verlassen könnte.

Früher verwendete ich aber (größtenteils aus Unkenntnis) einen anderen Ansatz, den ich "Tiefenbohrungsmethode" getauft habe. Bei dieser Methode wird die Oberfläche des Fraktals "abgescannt" und die gefundenen Punkte in einer internen Struktur abgelegt. Ein grundsätzliches Problem beim Finden des Objekts wird dabei auch durch die oft sehr dünnen Strukturen aufgeworfen.
Der Online-Fraktal-Creator funktioniert z.B. noch nach diesem Prinzip. Dieser gibt auch eine kleine Statistik aus, die z.B. so aussieht:

STATISTICS:
evaluated 19930433 of 1024000000 pnts (1.94633%)
with 560668 hits at 19930433 trials (2.81313%)

Diese Auswertung zeigt an, dass die Berechnung, ob ein bestimmter Punkt im Raum zum Fraktal gehört "nur" 19930433, also knapp 20 Millionen mal durchgeführt wurde. Das ist zwar eine recht beachtliche Zahl, jedoch sind das weniger als 2 Prozent (1.94633%) der Zahl die herausgekommen wäre, wenn die Berechnung für alle 800x800x1600=1024000000, also gut eine Milliarde Punkte des Suchraumes durchgeführt worden wäre. Trotz des offensichtlichen Effizienzgewinns stellte sich nur bei 560668 Punkten heraus, dass sie Teil des Objekts (Fraktals) waren, das sind weniger als drei Prozent (2.81313%) der knapp 20 Millionen berechneter Punkte. Die restlichen gut 97 Prozent stellten sich also als "Luft" heraus. Die konkreten Trefferquoten schwanken natürlich stark, abhängig vom Aussehen und der Größe (relativ zum Suchraum) des Fraktals. Aber für die meisten unten dargestellten Fraktale sind das recht gute Beispielwerte.

Tiefenbohrungsmethode:
Die Methode, um mit möglichst wenigen Berechnungen alle relevanten Punkte zu finden, nenne ich "Tiefenbohrungsmethode".
Die allererste Idee bestand darin den Raum zunächst in Würfel einzuteilen (also eine Art dreidimensionalem Schachbrettmuster). Berechnet werden sollten im ersten Schritt nur die Eckpunkte der Würfel. Dort wo man fündig geworden wäre sollte durch eine feinere Unterteilung des umliegenden Raumes rekursiv weitergesucht werden. Natürlich darf dabei die initiale Größe der Würfel nicht zu groß gewählt werden, da sonst die Gefahr besteht das Objekt komplett zu übersehen. Diese Methode funktionierte leider nicht sonderlich gut, da dünne Strukturen leicht übersehen werden, was insbesondere in Z-Richtung unangenehm ist.
Daher wird stattdessen an den Eckpunkten eines (2D) Schachbrettmusters "in die Tiefe gebohrt", d.h. es wird an diesen Stellen jeweils jeder Punkt (entsprechend der gewählten Auflösung) in Z-Richtung berechnet (bei einer Bildtiefe von 1600 Punkten also jeweils 1600 Berechnungen). Danach wird das Suchraster schrittweise verfeinert, wobei für alle weiteren Punkte eben nicht mehr von ganz vorne gesucht wird, sondern die jeweils bereits berechneten umliegenden Punkte berücksichtigt werden. Die Annahme, die dabei gemacht wird ist, dass sich der Z-Wert in einem Suchraster von (x +/- delta, y +/- delta) nicht um mehr als delta ändern sollte. Diese Annahme muss nicht stimmen, jedoch habe ich bisher, bei "meinen" Fraktalen damit keine Probleme beobachtet. Auch hier darf aber natürlich die Rastergröße für den ersten Suchschritt nicht zu groß gewählt werden. Ansonsten ist das Verfahren jedoch deutlich robuster als das zuvor beschriebene. Eine erste Verbesserung besteht darin aus zwei gegenüberliegenden Richtungen (also vorne und hinten) gleichzeitig zu suchen, um den Suchraum noch besser eingrenzen zu können. Früher bestand das Ergebnis lediglich aus einer 2D-Matrix mit Höhe x Breite Elementen, die jeweils den dem Beobachter nächstliegenden Punkt repräsentierten (also insbesondere dessen Z-Wert und dessen Farbe). Inzwischen ist es jedoch möglich, auch in eine Art 3D-Matrix zu scannen. Dabei muss nicht nur von vorne und hinten, sondern auch von oben und unten sowie von rechts und links gescannt werden, um alle Oberflächen-Punkte zu finden. Zudem sollten mehrere hintereinanderliegende Oberflächen erfasst werden, indem man nachdem die äußersten Oberflächen-Punkte gefunden wurden weiter nach innen geht bis man wieder eine Oberfläche findet, usw.
Oberflächenscan

Surface-Scan in 3D-Matrix
Hier sind alle Raumpixel dargestellt die für die Berechnung eines Fraktals (kleines Bild) ausgewertet wurden, egal ob sie dann zum Fraktal gehörten oder nicht (man sieht die "Bohrlöcher", die in Scan-Richtung, also hier der Z-Achse verlaufen). Die Punkte werden in einer 2D-Matrix abgelegt, die jeweils nur den Punkt enthält der dem Betrachter am nächsten ist (kleinster Z-Wert).
 
Zum Scannen in eine 3D-Matrix kann mit demselben Verfahren von allen Seiten gescannt werden. Zusätzlich werden mehrere Ebenen hintereinanderliegender Oberflächen gescannt, indem ab den Z-Werten der jeweils letzten Ebene weitergesucht wird. Die "3D-Matrix"kann wegen der enormen Anzahl von Elementen nicht einfach als 3D-Array (z.B. Point[][][]) repräsentiert sein!

Kombination der Methoden: Die beiden Methoden lassen sich auch kombinieren: Statt einen "Sicht-Strahl" nämlich immer beim Beobachter beginnen zu lassen, kann man die umliegenden Punkte berücksichtigen, um bereits weiter vorne zu beginnen - das spart Rechenzeit. Mein derzeit schnellster Algorithmus scannt daher in dieser Form den Suchraum aus der Sicht des Beobachters, sowie auch aus der Sicht aller Lichtquellen (nötig für die Schattenberechnung) und legt die gefundenen Punkte in 2D-Matritzen ab. Bei spiegelnden Oberflächen muss allerdings, ohne Hilfe eines solchen Scans weitergesucht werden, indem der reflektierte Sichtstrahl weiterverfolgt wird...

Oberflächenscan
Mit der oben beschriebenen Methode wird das Objekt (Fraktal) zunächst aus der Perspektive des Beobachters (blauer Punkt) sowie entsprechend aller Lichtquellen (hier nicht dargestellt) in eine 2D-Matrix (hier symbolisch schwarz umrandet) gescannt. Wobei die "Abtaststrahlen" hier nicht parallel verlaufen, sondern entsprechend der Perspektive im Beobachter zusammenlaufen.


1)
 
Ich habe beide Varianten im Netz gefunden - dass die eine Formel aber nur für Mandelbrot-, die andere dagegen nur für Julia-Fraktale zu stimmen scheint, habe ich auch nur durch Ausprobieren herausgefunden...
2)

Für Julia-Fraktale dreht sich Z' auf seltsame Art auch in der vierte Dimension. Ich habe noch keine Ahnung was das zu bedeuten hat, oder wie es sich vermeiden lässt...
Farbgebung
Mein erster Ansatz bestand darin das letzte Zn der Reihe Z = Z2 + C zu nehmen und die ersten drei Komponenten Z.x, Z.y und Z.z in die Farb-Kanäle Rot, Grün und Blau umzurechnen. Viele Fraktale, die in der "alten" Galerie zu sehen sind, habe so ihre Farben erhalten. Das funktioniert ganz gut, solange man nur wenige Iterationen macht und bei BailOut=2 abbricht. Wenn man aber mit einem Abstandsmaß rechnet, macht man i.d.R. viele Iterationen (da der MaxIter-Parameter nicht mehr zur Glättung ge-/missbraucht wird) und den BailOut-Parameter gibt es dann gar nicht mehr. Das führt zu sehr pixeligen Farb-"Verläufen".
Eine schöne Alternative bieten aber z.B. die sogenannten Orbit-Traps. Hier wird geschaut wie nahe Z im Verlauf der Evaluierung der Reihe Z = Z2 + C einem oder mehreren Punkten, den sogenannten "Orbit-Traps" kommt. Der minimale Abstand (also min(|Zn - OrbitTrap|)) wird dann zur Farbgebung herangezogen - z.B. als Hue-Wert einer Farbe, oder bei drei Orbit-Traps als Rot-, Grün- und Blau-Werte. Statt eines punktförmigen Orbit-Traps kann z.B. auch der minimale Abstand zu einer oder mehreren Geraden benutzt werden (z.B. den drei Hauptachsen). Außerdem ist es möglich andere Maße als den minimalen Abstand zu benutzen. Hier sind also zahlreiche Variationen möglich... Einige Beispiele sind in der neuen Galerie unten zu sehen.
Fraktale im Film
Auch auf dieser Seite zu finden sind ein paar Fraktal-Filme (die allerdings noch mit der alten Methode erzeugt wurden, also ohne Verwendung eines Abstandsmaßes). Hierbei wurden die C-Werte kontinuierlich verändert und die entstehenden einzelnen Fraktal-Bilder als Film abgespeichert. Zusätzlich wurden die Fraktale dabei gedreht und teilweise die Beleuchtungsrichtung verändert. Beispiele sind ganz unten auf dieser Seite in der Galerie zu finden. Das funktioniert, weil kontinuierliche Änderungen von C zu ebenso kontinuierlichen (also nicht sprunghaften) Änderungen der Form führen. Das Prinzip ist im Folgenden nochmal veranschaulicht - das mittlere Bild ist sowohl, was den C-Wert angeht, als auch in Bezug auf die Form, irgendwo zwischen den beiden außen dargestellten Fraktalen (die Sprünge zwischen den Bildern sind hier natürlich noch viel zu groß - für einen Film muss man eine wesentlich feinere Abstufung der Einzelbilder wählen):


Bild 1 Bild 2 Bild 3
C = (-0.9, 0.2, -0.2, 0.05)
C = (-0.575, 0.225, -0.25, 0.05) C = (-0.25, 0.25, -0.3, 0.05)
Fraktale Dimension bei Julia-Fraktalen
Hausdorf-Dimensionen von 3D-Julia-Fraktalen
                      in Abhängigkeit vom C-Wert Ein kleiner Nachtrag zu der Fraktalen Dimension. Links sind die Werte der Fraktalen Dimension (farblich codiert) für 2D-Julia-Fraktale in Abhängigkeit von verschiedenen C-Werten (X- und Y-Achse) abgetragen. Zu erkennen ist, dass der C-Wert eines Julia-Fraktals aus der Mandelbrot-Menge stammen muss (das typische "Apfelmännchen" ist sichtbar). Zudem sieht man dass die Dimensionszahl zu den Rändern hin steigt, während sie um den Koordinatenursprung herum nahe 1 liegt - also mit C-Werten aus diesem Bereich keine Fraktale entstehen.
Code
Den ganzen C++ Code für die eigentliche Fraktal-Berechnung runterladen kann man hier (nicht enthalten ist das Rendering und das effiziente Einschränken des Suchraums)
Allerdings ist das noch das alte "Zeug", auf dem z.B. auch der inzwischen abgeschaltete Online-Fractal-Creator basierte - d.h. ohne Abstandsmaß. Der neuere Kram ist als Java-Applikation hier zu finden (allerdings noch ohne Source-Code).

Außerdem hier mal ein ganz einfaches Beispiel wie man ein 2D-Mandelbrot-Fraktal mit Octave bzw. Matlab erzeugen und visualisieren kann (auch das ohne Abstandsmaß). Octave/Matlab hat den Vorteil, dass man direkt mit kompletten Vektoren und Matrizen rechnen kann und grafische Ausgaben besonders einfach sind. Um das Programm zusätzlich möglichst simpel zu halten wird immer Max-Iter mal iteriert und nicht bei einem vorgegebenen Abstand zum Ursprung (Bail-Out) abgebrochen. Bail-Out dient nur hinterher zur Bestimmung, welche Werte zum Fraktal gehören und welche nicht. Für ein Julia Fraktal müsste übrigens nur Z so initialisiert werden wie hier C und C muss stattdessen ein einzelner Wert (als Komplexe Zahl) aus der Mandelbrot-Menge sein.

Mit
                      Octave erstelltes 2D-Mandelbrot-Fraktal
Mit dem rechts dargestellten Programm unter Octave erzeugtes Fraktal
% Mandelbrot

% Max-Iter und Bail-Out festlegen
% (Bail-Out wird hier aber nicht zur Optimierung genutzt)
maxIter = 10;
bailOut = 2;

% X- und Y-Werte des Suchrasters
x = [-2.25:0.01:1.0];  % Zeilenvektor
y = [-1.5:0.01:1.5]';  % Spaltenvektor

% Erzeuge eine Matrix C in der jede Kombination der X- und Y-Werte
% in je einer komplexen Zahl abgelegt ist
(X=Real-, Y=Imaginärteil)
C = repmat(x, length(y), 1) + repmat(y, 1, length(x)) * i;

% Erzeuge eine leere Matrix Z derselben Größe (alle Werte 0)
Z = zeros(size(C));

% Iteriere alle Werte MaxIter mal (kein vorzeitiger Abbruch)
for iteration=1:maxIter
  Z = Z .* Z + C;
end;

% Berechne für alle Z-Werte den euklidischen Abstand zum Ursprung
D = sqrt(real(Z).^2 + imag(Z).^2);

% Ausgabe: wo der Abstand kleiner als bailOut ist setze stattdessen
% den Maximal-Abstand (nur zur besseren Sichtbarkeit des Fraktals)
maxD = max(max(D));    % Max-Wert in D (über alle Spalten und Zeilen)
D(D < bailOut) = maxD; % wo D < bailOut setze stattdessen maxD in D
imagesc(log(D));             % Anzeige (mit log() sieht es schöner aus)
Online-2D-Fraktal-Generator
Hier kannst du selbst 2D-Fraktale generieren (für 3D-Fraktale wäre JavaScript dann doch etwas zu langsam - siehe das nächste Kapitel bzgl. 3D-Fraktal-Generatoren). Bilder, die mit diesem Generator erzeugt wurden sind in der 2D-Galerie zu finden.

Voraussetzungen: Dein Browser sollte nicht zu alt sein (sonst siehst du wahrscheinlich "CANVAS NOT SUPPORTED") und JavaScript muss aktiviert sein (sonst funktioniert's einfach nicht).
Start: Starte indem du einen der vordefinierten Farbgebungs-Algorithmen auswählst (zweite Drop-Down-Liste). Außerdem kannst du zwischen Mandelbrot- und verschiedenen Julia-Fraktalen wählen und einstellen, ob das Fraktal oder/und die Umgebung eingefärbt werden sollen.
Zoom: Zoomen kannst indem du in das Bild klickst und bei gedrückter linker Maustaste den Zoombereich ziehst. Schrittweises bzw. komplettes Herauszoomen geht über die beiden Lupen-Icons unten um Bild. Die Verzögerungseinstellung ist hilfreich, wenn du ein Bild mit dem Zoom-Rahmen abspeichern willst (dazu bitte mit der rechten Maustaste auf das Bild klicken bevor es neu gezeichnet wird).
Speichern: Das Speichern läuft über die normalen Funktionalitäten des Browsers - üblicher Weise: rechte Maustaste → Speichere Bild unter...
Tipp: Durch Erhöhung der Anzahl Zeilen die auf einmal gezeichnet werden lässt sich die Generierung u.U. etwas beschleunigen.

Wer größere Bilder (1024x1024) erzeugen will, kann das hier machen. Na dann viel Spaß damit...
CANVAS NOT SUPPORTED
Java-3D-Fraktal-Generator
Hier kannst Du einen nach Java konvertierten, erweiterten und mit einer Benutzeroberfläche versehenen Fraktal-Generator herunterladen, mit dem viele der unten gezeigten Fraktale erstellt werden können (und erstellt wurden). Allerdings gilt das nur noch für die Bilder aus der "neuen Galerie", da die Möglichkeit veränderte Berechnungsvorschriften zu benutzen (abgesehen von Mandelbulbs und Mandelboxen), wieder rausgeflogen ist (alle diese veränderten Fraktale waren in Wirklichkeit leider vollkommen instabil).
E3DFractalRenderer
Screenshot des Java-Fraktal-Generators

2D-Galerie
(zum Warmwerden zunächst ein paar 2D-Bilder)
Die folgenden Bilder wurden mit dem oben zu findenden Online 2D-Fraktal-Generator erzeugt:
Mandelbrot:
Mandelbrot
"Mandelbäumchen"

Ausschnitt aus dem Mandelbrot-Fraktal. Eingefärbt mit einem Orbit-Trap-Algorithmus (3 Orbit-Traps, die Werte für Farbe, Sättigung und Helligkeit (HSV) bestimmen und zwar sowohl für die Umgebung, als auch für das Fraktal selbst)


"Mandelbäumchen"
Mandelbrot
"Mandelflocke"

Ein anderer Ausschnitt des Mandelbrot-Fraktals, wieder mit einem Orbit-Trap-Algorithmus (HSV) eingefärbt (siehe auch voriges Bild)


"Mandelflocke"
Mandelbrot
"Mandelstern"

Noch ein anderer Ausschnitt des Mandelbrot-Fraktals, wieder mit einem Orbit-Trap-Algorithmus (HSV) eingefärbt (siehe auch erstes Bild)


"Mandelstern"
Mandelbrot
"Mandelrelief"

Derselbe Ausschnitt wie im vorigen Bild, aber mit einem Algorithmus eingefärbt, der den (geschätzten) Normalenvektor an jedem Punkt in Rot-, Grün- und Blau-Werte umrechnet. Das ergibt einen leicht 3D-artigen Effekt.


"Mandelrelief"

Mandelbrot
"Feuerdrache"

Nochmal ein anderer Ausschnitt des Mandelbrot-Fraktals, wobei hier nur das Fraktal selbst, nicht jedoch die Umgebung eingefärbt wurde ("Invers-Modus")


"Feuerdrache"
Mandelbrot
"Mandelwirbel"

Derselbe Ausschnitt wie im vorigen Bild, nur dass hier wieder alle Bildpunkte eingefärbt wurden und das mit einem anderen Algorithmus


"Mandelwirbel"


Julia:
Julia-Fraktal
"Juliawirbel"

Ein Ausschnitt aus einem Julia-Fraktal (C=-0.6+0.45i), eingefärbt mit einem HSB-Orbit-Trap-Algorithmus


"Juliawirbel"
Julia-Fraktal
"Julia strickt"

Ausschnitt aus einem Julia-Fraktal (C=-1.8+0i), welches durch seinen C-Wert aus der "Antenne" des Mandelbrot-Fraktals spezielle, teilweise fast rechtwinklige Strukturen erzeugt.


"Julia strickt"
Julia-Fraktal
"Julia-Muscheln"

F¨r ein Julia-Fraktal relativ typische muschelartig verdrehte Strukturen


"Julia-Muscheln"
Julia-Fraktal
"Julia-Keim"

Ein weiterer Ausschnitt aus einem Julia-Fraktal


"Julia-Keim"

Julia-Fraktal
"Julia on Fire"

Wieder die typisch verdrehte Julia-Struktur, in dieser Färbung an Magma erinnernd...


"Julia on Fire"
Julia-Fraktal
"Eclipse"

Ein Julia-Fraktal mit C=(0+0i) ergibt kein Fraktal, sondern lediglich einen Kreis; allerdings kann die Färbung (hier wieder mit einem HSB-Orbit-Trap-Algorithmus) dann doch noch was halbwegs ansehnliches rausholen...


"Eclipse"

Galerie
(neue Bilder mit Ray-Tracer und Abstandsmaß)
Die folgenden Bilder wurden mit dem oben genannten Java 3D-Fraktal-Generator erzeugt, dieser nutzt einen Ray-Tracer-Algorithmus und beherrscht "Ray-Marching", also die schnelle Annäherung an die Objekt-Oberfläche durch Berechnung eines Abstandsmaßes; außerdem sind dort verschiedene Orbit-Trap-Algorithmen zum Einfärben implementiert:
Mandelbrot:

Mandelbrot
"Antennenbrot"

Normales 3D-Mandelbrot-Fraktal mit C = (x,y,z, 0.00). Coloriert wurde dieses Fraktal mit einem Orbit-Trap-Algorithmus der die minimalen Abstände von Zi zu drei Punkten (gegeben durch drei beliebig gewählte Quaternion-Zahlen) in die Farb-Kanäle Rot, Grün und Blau umrechnet. Da das 3D-Mandelbrot-Fraktal nur ein Rotationskörper des bekannten 2D-Mandelbrot-Fraktals um die X-Achse darstellt ist es nicht soooo spannend...


"Antennenbrot"
Schnitt durch ein Mandelbrot
"Schnittbrot"

Der Teil des Normalen 3D-Mandelbrot-Fraktal der unterhalb von y=0 und hinter z=0 liegt (also ein aufgeschnittenes Fraktal) mit C = (x,y,z, 0.00). Coloriert wurde auch dieses Fraktal wieder mit einem Orbit-Trap-Algorithmus der die minimalen Abstände von Zi zu drei Punkten (gegeben durch drei beliebig gewählte Quaternion-Zahlen) in die Farb-Kanäle Rot, Grün und Blau umrechnet. Durch den Schnitt erkennt man hier besser als im letzten Bild das bekannte Mandelbrot und dessen fraktale Strukturen.


"Schnittbrot"


Julia:
Julia-Fraktal
"Skeleton"

"Normales" Julia-Fraktal mit C = (-0.5, 0.45, -0.35, 0.25) und Z = (x,y,z,0.00). Mein erstes "eigenes" Fraktal, aber jetzt besser gerendert (siehe auch die Galerie der "alten" Fraktale). Coloriert wurde dieses Fraktal mit einem sogenannten Orbit-Trap-Algorithmus, der den minimalen Abstand der Zi zu drei (relativ willkürlich gewählten) Punkten ("Orbit-Traps") in Rot-, Grün- und Blau-Werte umsetzt. Die Möglichkeit der Glättung, habe ich hier nur minimal genutz, da ich den "skelettartigen" Eindruck des ungeglätteten Fraktals mag)


"Skeleton"
Julia-Fraktal-Ausschnitt
"Pearl"

Ausschnitt aus dem vorigen Julia-Fraktal, stärker geglättet und anders coloriert, so dass ein perlmuttartiger Eindruck entsteht.


"Pearl"
Julia-Fraktal
"Sling"

Julia-Fraktal mit C=(0.59, -0.25, -0.54, 0.04) und Z=(x,y,z,0). Leider ist ein Fraktal aus diesem Bereich (numerisch) recht instabil, was unter anderem zu Lücken führt, die ich hier mit Tiefen(un-)schärfe etwas zu kaschieren versuche...


"Sling"
Julia-Fraktal
"Jumping Dragon"

Die rechte Hälfte eines Julia-Fraktals mit C=(-0.84,-0.42,0.42,0) und Z=(x,y,z,0), Blickwinkel 45° von oben.


"Jumping Dragon"

Mandelbulb:
Mandelbulb
Mandelbulb-Fraktal.

Coloriert mit einem Orbit-Trap-Algorithmus, bei dem die minimale Distanz eines Zi als Hue-Wert einer Farbe verwendet wird. Das Interessante im Vergleich zu "normalen" 3D-Julia-/Mandelbrot-Fraktalen ist, dass sich die Strukturen zu "Knollen" ("Bulbs") verdrehen, wodurch man erst ein "echtes" 3D-Fraktal erhält in das man beliebig hineinzoomen kann...


Mandelbulb
Mandelbulb-Ausschnitt
"Sunny Bulb-World"

Ausschnitt aus dem vorigen Mandelbulb-Fraktal. Coloriert wurde auch dieses Fraktal mit einem sogenannten Orbit-Trap-Algorithmus, allerdings in diesem Fall mit einem der die minimalen Abstände der Zi zu den drei Hauptachsen (X, Y und Z) in Werte fü Rot, Grün und Blau umrechnet.


"Sunny Bulb-World"
Mandelbulb-Ausscnitt
"The Dark Side of Bulb"

Ein weiterer Ausschnitt aus dem Mandelbulb-Fraktal - aus einem eher instabilen Bereich, wie man leider an einigen Kanten sieht...


"The Dark Side of Bulb""
Mandelbulb-Ausschnitt
"Peak"

Eine enorme Vergrößerung aus dem Mandelbulb-Fraktal. Hier haben numerische Instabilitäten und das Abbruchkriterium sicher auch ihre schmutzigen Finger im Spiel gehabt.


"Peak"

Juliabulb:
Julia-Bulb
"Bouquet"

Ein Julia-Bulb-Fraktal, mit C=(0.96, -0.25, -0.54, 0.04) und Z=(x,y,z,0). Ein Julia-Bulb ist ein Julia-Fraktal, das mit dem Multiplikations-Operator für Mandelbulbs berechnet wurde. Wählt man C aus den mittleren Regionen der Mandelbulb-Menge, sieht das Julia-Bulb-Fraktal dem Mandelbulb sehr ähnlich. Je weiter man mit C aber in die Randzonen der Mandelbulb-Menge kommt, desto stärker löst sich das Julia-Bulb-Fraktal auf. Die äußersten Knollen und Ringe halten dabei am längsten, was dieses "Blumengebinde" erzeugt. Gegen die Instabilität habe ich eine starke Glättung verwendet - und die Tiefenunschärfe verschleiert das Übrige :-)


"Bouquet"
Julia-Bulb-Ausschnitt
"Flower"

Eine "Blüte" aus dem vorigen Julia-Bulb-Fraktal, jedoch mit weniger Glättung (also einem kleineren Abstandswert). Daher zerfällt der "Stengel" und aus den einzelnen "Blüten-Blättern" werden selbst wieder Blüten, die an weiteren Ringen "befestigt" sind.


"Flower"
Juliabulb-Ausscnitt
"Julia's Bulb-Garden"

Ein Ausschnit aus einem Julia-Bulb-Fraktal - also einem Julia-Fraktal, das mit dem Multiplikations-Operator für Mandelbulbs berechnet wurde.


"Julia's Bulb-Garden"
Juliabulb-Ausscnitt
"Stormy Seas"

Ein Ausschnit aus einem Julia-Bulb-4-Fraktal. Alle anderen Bulb-Fraktale auf dieser Seite sind übrigens Bulb-8-Fraktale.


"Stormy Seas"

Mandelbox:

Mandelbox
"Golden Chest"

Mandelbox-Fraktal (Scale=2.0) (Coloriert mit einem Orbit-Trap-Algorithmus, der den minimalen Abstand von Zi zum Mittelpunkt (0,0,0,0) als Hue-Wert der Farbe benutzt)


"Golden Chest"
Mandelbox Detail
"Cavities"

Linke obere Ecke des Mandelbox-Fraktals mit Scale 2.0 Ich weiß übrigens nicht genau, was den Schatten über der ganzen linken Seite verursacht, da hat sich der Algorithmus wohl selbst verwirklicht :-)


"Cavities"
(Ausschnitt links)
Mandelbox
"Urban Canyon"

Ausschnitt aus einem Scale-2.5-Mandelbox-Fraktal (etwa in der Mitte der rechten Seite), mit starker Perspektivischer Verzerrung). Die hier zu sehende "Unterseite" ist keine echte Fraktalgrenze, sondern nur das Ende des gescannten Bereichs (also ein Schnitt durch das Fraktal).


"Urban Canyon"
(Ausschnitt rechts)

Mandelbox
"Heavy Cube"

Mandelbox (Scale=2.5), kräftig perspektivisch verzerrt, mit viel Glanz und coloriert mit drei Orbit-Traps (je einer für Rot, Grün und Blau)


"Heavy Cube"
Mandelbox
"Cold Fusion"

Coloriert wurde diese Mandelbox (Scale=-2.5) mit einem Algorithmus, der einen kugelförmigen Bereich um die Mitte anders einfärbt und leuchten lässt (mit fließenden Übergängen an den Rändern). Man sieht hier nebenbei bemerkt, dass mein Abstandsmaß für Mandelboxen noch nicht optimal funktioniert... (oder dieser "Kalte-Fusions-Reaktor" brennt bald mal durch :-)


"Cold Fusion"
Mandelbox
"Green Energy"

Mandelbox-Fraktal (Scale=-2.0) mit einem extrem kleinen Max-Iter-Wert von 5 berechnet (normal sind Werte ≥ 500), was dieses irgendwie bollig blubbernde Aussehen ergibt. Auch dieses Bild wurde mit einem Algorithmus der einen kugelförmigen Bereich um die Mitte anders einfärbt und leuchten lässt coloriert. Zusätzlich ist die Mandelbox von spiegelnden Wänden umgeben.


"Green Energy"
Mandelbox
"After Sunset"

Wieder ein quasi-standard Mandelbox-Fraktal (Scale=2.0) mit noch einer anderen Variation zum Thema "inneres Glühen", wobei diesmal ein würfelförmiger Bereich innerhalb des Fraktals zum Leuchten gebracht wurde.


"After Sunset"
Mandelbox
"Urban Canyon II"

Ein Ausschnitt aus einer Mandelbox (Scale=2.5), perspektivisch verzerrt und zudem mit Spiegelungen, was verteufelt Rechenzeit kostet :-) Gespiegelt werden übrigens sechs (hier allerdings identische Bilder), die sich auf den sechs Seiten einer Box befinden, die virtuell die Szene umgibt. Hier habe ich es allerdings so eingestellt, dass diese Bilder nur indirekt (also über die Spiegelungen) sichtbar sind und der Hintergrund in einem einheitlichen Blau erscheint.


"Urban Canyon II"
(Ausschnitt oben)
Mandelbox
"Platine"

Coloriert wurde diese Mandelbox (Scale=-2.5) mit einem Algorithmus, der die Anzahl der Iterationen auswertet


"Platine"
Mandelbox
"Box City"

Die Oberseite eines Mandelbox-Fraktals (Scale=-2.5) mit einem Stadt-artigem Aussehen (samt Unterwelt)


"Box City"
Mandelbox
"The Fog"

Viel Tiefenunschärfe und nach hinten immer heller und leicht bläulicher werdend ergibt dieses nebelartige Aussehen.


"The Fog"
Mandelbox
"Real Steel"

Zum Abschluss der Mandelbox-Reihe eine Version mit leichtem "inneren Leuchten", was hier zu einem leicht metallischem Aussehen führt.


"Real Steel"

Juliabox:
Juliabox
"Ruin"

Ausschnitt aus einer Juliabox (Scale=2.0) - also einem Julia-Fraktal, das mit der Mandelbox-Multiplikation berechnet wurde. Ich weiß leider noch nicht warum, aber diese Fraktale scheinen häufig (immer?) keine äußere Grenze zu haben, so dass man nur Ausschnitte zeigen kann. Außerdem sind sie ausgesprochen instabil, was dieses halb zerfallene Gebilde zur Folge hat (mit viel Tiefenunschärfe hat das aber schon wieder was...)


"Ruin"
Juliabox (Scale=2.0)
Juliabox
"Mein Block"

Ausschnitt aus einer Juliabox (Scale=2.5). Etwas solider als die letzte Juliabox, aber ebenfalls nicht mehr ganz fit...


"Mein Block"
Juliabox(Scale=2.5)
Juliabox
"Concrete"

Derselbe Ausschnitt wie bei der ganz linken Juliabox, nur aus einer anderen Perspektive und mit Scale=1.4, statt 2.0. Auch diesem Fraktal scheint es nicht sonderlich gut zu gehen. Ich finde aber dieser "verwitterte Beton-Look" steht einer mathematischen Funktion (zu den richtigen Anlässen) ja auch mal ganz gut, oder nicht, oder was...


"Concrete"
Juliabox (Scale=1.4)
Juliabox
"Inner Light"

Julia-Boxen, die noch nicht ganz so kaputt sind, verspüren auch mal so ein inneres Leuchten und fangen dann vor Freude an zu Hüpfen... Das "kaputte" Aussehen der Julia-Boxen scheint übrigens zum großen Teil daran zu liegen, dass das verwendete Abstandsmaß nicht gut funktioniert. Hier habe ich den geschätzten Abstand jeweils noch durch 20 geteilt - damit halten sich die "Bröckeleien" in Grenzen...


"Inner Light"
Juliabox (Scale=3.0)
Galerie
(alte Bilder ohne Ray-Tracer und Abstandsmaß)
Die folgenden Bilder wurden mit einer alten (nicht mehr verfügbaren) Programmversion erzeugt, die weder einen echten Ray-Tracing-Algorithmus, noch Ray-Marching kannte und nur sehr simple Färbe-Algorithmen beinhaltete:
Julia:
3D-Julia-Fraktal mit folgenden Parametern:
C = (-0.5,0.45,-0.35,0.25),
Z = (x,y,z,0.05),
Maxiter = 15,
Bailout = 2.0
"Mein erstes eigenes 3D-Fraktal", zudem noch mit einer Frühform meines Renderers "abgelichtet" - keine Farbe, eher diffuse Konturen, ... aber dafür historisch wertvoll :-)

3D-Julia-Fraktal
"Green Hornet"

Praktisch dasselbe Fraktal wie vorher, nur mit "falscher" Quaternion-Multiplikation (zweimal "sinnlos" Sinus eingefügt)


Mit "falscher"
Quaternion-Multiplikation

"Gold und Silber"

"Gold und Silber"
"Muschel"

"Muschel"

(Aus-)Schnitte:

Schnitt durch Apfelmännchen
Schnitt durch ein 3D-Apfelmännchen (Mandelbrot-Fraktal)

Durch den Schnitt wird praktisch das allseits bekannte Apfelmännchen sichtbar, nur dass hier die zur Mandelbrotmenge gehörenden Teile eingefärbt sind, anstatt, wie bei 2D-Julia- und Mandelbrot-Fraktalen sonst üblich, die umliegenden, nicht zum Fraktal gehörenden, Bereiche einzufärben.


Schnitt durch ein
3D-Apfelmännchen
(Mandelbrot-Fraktal)

Schnitt
                          durch Apfelmännchen
Ausschnittsvergrößerung des letzten Bilds

Gleichzeitig wurde auch der Iterations-Wert erhöht, so dass das Fraktal stärker konturiert ist (sonst sähe ein so starker Zoom auch eher langweilig aus). Man ahnt schon, dass man beliebig weiter hineinzoomen könnte...


Ausschnittsvergrößerung
des letzten Bilds

Schnitt durch ein 3D-Julia-Fraktal
                        (invers)
Schnitt durch das erste Fraktal (invers)

Hier wurde das Fraktal selbst durchsichtig und die umliegenden Punkte farbig dargestellt. Die Farbe wurde, wie in der normalen Darstellung auch, anhand der Koordinaten zum Zeitpunkt des Abbruchs der Iteration (also beim Überschreiten des durch den Parameter Bailout festgelegten maximalen Abstands zum Koordinaten-Ursprung) bestimmt. Die scharfen Grenzen zeigen jeweils die Anzahl der Iterationen, bis der Bailout-Abstand erreicht und die Iteration abgebrochen wurde. Dies wären also die gefundenen Grenzen des Fraktals bei kleinerem Maxiter-Parameter (je kleiner desto aufgeblähter und "schwammiger" erscheint das Fraktal).


Schnitt durch das
erste Fraktal (invers)

Schnitt durch
                        Apfelmännchen (invers)
Schnitt durch ein 3D-Apfelmännchen (invers)

Hier wurde das Fraktal selbst durchsichtig und die umliegenden Punkte farbig dargestellt. Die Farbe wurde, wie in der normalen Darstellung auch, anhand der Koordinaten zum Zeitpunkt des Abbruchs der Iteration (also beim Überschreiten des durch den Parameter Bailout festgelegten maximalen Abstands zum Koordinaten-Ursprung) bestimmt. Die scharfen Grenzen zeigen jeweils wieder die Anzahl der Iterationen bis der Bailout-Abstand erreicht und die Iteration abgebrochen wurde. Dies wären also die gefundenen Grenzen des Fraktals bei kleinerem Maxiter-Parameter (je kleiner desto aufgeblähter und "schwammiger" erscheint das Fraktal). Das Fraktal ist übrigens leicht gedreht, damit man den runden Querschnitt des 3D-Apfelmännchens besser sieht.


Schnitt durch ein
3D-Apfelmännchen (invers)


Verschlungenes:
"Herbst"

"Herbst"
"Grünes Urzeitvieh"

"Grünes Urzeitvieh"
"Schlingen"

"Schlingen"
"Kompaktklasse"

"Kompaktklasse"


Zum Kugeln:

"Ball"
(Die Form ist hier allein
durch BailOut bestimmt)

"Flummi"
"BallaBalla"

Die Kugelform entsteht durch den BailOut-Parameter. Der hier allerdings nicht allein für die Form verantwortlich ist, sonst würde eben wirklich eine Kugel herauskommen.


Hier ist nicht mehr nur BailOut
für die Form verantwortlich
"Welle"

"Welle"

Abwandlungen:

"Orbit"

"Orbit"
C = (-0.5, 0.26,
                          -0.35, 0.25); T = 0.05; Iterator = C_POW_Z_Z
"Starwars"
Dieses Fraktal hat wurde mit einer abgewandelten Formel berechnet:
C = (-0.5, 0.26, -0.35, 0.25)
Z = (x, y, z, 0.05)
Max-Iter = 6
Bailout = 2.0
Iterator = Z = C^(Z*Z)

"Starwars"
"Holzwurm"

"Holzwurm"
Mandelbulb
                          Detail-Sicht
Mandelbulb-Ausschnitt

Mein erster halbwegs brauchbarer Versuch: mit einer einfachen Glättung und Tiefenunschärfe, aber noch ohne echten Ray-Tracer und ohne Abstandsmaß berechnet. Die Probleme bei den Mandelbulbs veranlassten mich dazu meinen Renderer komplett neu zu schreiben (Ergebnisse siehe oben in der neuen Galerie).


Mandelbulb

2
D2D3:

Julia-Fraktale
                      in Schichten
Jede Zeile ist ein 2D-Julia-Fraktal
(von "oben" gesehen), wobei mit der
Y-Koordinate der Real-Teil des
C-Wertes verändert wurde

2D-Julia-Fraktal, wobei die Entfernung von Z zum Koordinaten-Ursprung zum Abbruchszeitpunkt als Höhe interpretiert wurde.


2D-Julia-Fraktal, wobei die
Entfernung von Z zum Koordinaten-
Ursprung zum Abbruchszeitpunkt als
Höhe interpretiert wurde


Bewegendes (MPEG-Filme):

"Zapfenflug"

Ein "Flug" über verschiedene Werte für C eines mit einem Logarithmus veränderten Julia-Fraktals. Da die Auflösung leider nicht so berauschend ist, sollten die Videos besser in Originalgröße geschaut werden (siehe Buttons rechts oben).


"Murmelflug"

Ein "Flug" über dieselben Werte für C eines diesmal mit einer Power-Funktion veränderten Julia-Fraktals.



"Amöbenflug"

Ein "Flug" wieder über dieselben Werte für C eines mit einer Tanh-Funktion veränderten Julia-Fraktals.


"Kreuzflug"

Noch ein "Flug", wieder über dieselben Werte für C, eines mit einer Tanh-Funktion veränderten Julia-Fraktals.

Ein "Flug" über verschiedene Werte für C eines mit einem Logarithmus veränderten Julia-Fraktals.
Ein "Flug" über dieselben Werte für C eines diesmal mit einer Power-Funktion veränderten Julia-Fraktals.
Ein "Flug" wieder über dieselben Werte für C eines mit einer Tanh-Funktion veränderten Julia-Fraktals.
Ein "Flug" wieder über dieselben Werte für C eines mit einer Tanh-Funktion veränderten Julia-Fraktals.
Feedback
Freue mich über eure Meinungen, Anregungen, usw.
Mail-Adresse.

Feedback-Formular
Patrick Rammelt, 2011