Wie programmiere ich ein Fraktal?


77

Ich habe keine Erfahrung mit der Programmierung von Fraktalen. Natürlich habe ich die berühmten Mandelbrot-Bilder und so gesehen.

Können Sie mir einfache Algorithmen für Fraktale zur Verfügung stellen?

Die Programmiersprache spielt keine Rolle, aber ich kenne mich am besten mit Actionscript, C # und Java aus.

Ich weiß, dass ich beim Googeln von Fraktalen viele (komplizierte) Informationen erhalte, aber ich möchte mit einem einfachen Algorithmus beginnen und damit spielen.

Vorschläge zur Verbesserung des grundlegenden Algorithmus sind ebenfalls willkommen, z. B. wie man sie in diesen schönen Farben und so macht.


6
Basierend auf den Antworten in dieser Frage habe ich mit dem Canvas-Element einen Kern auf Github mit animiertem Mandelbrot in Javascript erstellt. gist.github.com/1853604
Sander Versluys

Antworten:


58

Das Programmieren des Mandelbrot ist einfach.
Mein Quick-n-Dirty-Code ist unten (nicht garantiert fehlerfrei, aber eine gute Übersicht).

Hier ist der Umriss: Die Mandelbrot-Menge liegt im Komplex-Gitter vollständig innerhalb eines Kreises mit Radius 2.

Beginnen Sie also damit, jeden Punkt in diesem rechteckigen Bereich zu scannen. Jeder Punkt repräsentiert eine komplexe Zahl (x + yi). Iterieren Sie diese komplexe Zahl:

[new value] = [old-value]^2 + [original-value] während Sie zwei Dinge im Auge behalten:

1.) die Anzahl der Iterationen

2.) die Entfernung von [neuer Wert] vom Ursprung.

Wenn Sie die maximale Anzahl von Iterationen erreicht haben, sind Sie fertig. Wenn der Abstand vom Ursprung größer als 2 ist, sind Sie fertig.

Wenn Sie fertig sind, färben Sie das Originalpixel abhängig von der Anzahl der durchgeführten Iterationen. Fahren Sie dann mit dem nächsten Pixel fort.

public void MBrot()
{
    float epsilon = 0.0001; // The step size across the X and Y axis
    float x;
    float y;
    int maxIterations = 10; // increasing this will give you a more detailed fractal
    int maxColors = 256; // Change as appropriate for your display.

    Complex Z;
    Complex C;
    int iterations;
    for(x=-2; x<=2; x+= epsilon)
    {
        for(y=-2; y<=2; y+= epsilon)
        {
            iterations = 0;
            C = new Complex(x, y);
            Z = new Complex(0,0);
            while(Complex.Abs(Z) < 2 && iterations < maxIterations)
            {
                Z = Z*Z + C;
                iterations++;
            }
            Screen.Plot(x,y, iterations % maxColors); //depending on the number of iterations, color a pixel.
        }
    }
}

Einige ausgelassene Details sind:

1.) Erfahren Sie genau, was das Quadrat einer komplexen Zahl ist und wie Sie es berechnen.

2.) Finden Sie heraus, wie der (-2,2) rechteckige Bereich in Bildschirmkoordinaten übersetzt wird.


29

Sie sollten in der Tat mit dem Mandelbrot-Set beginnen und verstehen, was es wirklich ist.

Die Idee dahinter ist relativ einfach. Sie beginnen mit einer Funktion komplexer Variablen

f (z) = z 2 + C.

Dabei ist z eine komplexe Variable und C eine komplexe Konstante . Jetzt iterieren Sie es beginnend mit z = 0, dh Sie berechnen z 1 = f (0), z 2 = f (z 1 ), z 3 = f (z 2 ) und so weiter. Die Menge der Konstanten C, für die die Folge z 1 , z 2 , z 3 , ... begrenzt ist , dh nicht ins Unendliche geht, ist die Mandelbrot-Menge (die schwarze Menge in der Abbildung auf der Wikipedia-Seite).

In der Praxis sollten Sie zum Zeichnen des Mandelbrot-Sets:

  • Wählen Sie ein Rechteck in der komplexen Ebene (z. B. von Punkt -2-2i bis Punkt 2 + 2i).
  • Decken Sie das Rechteck mit einem geeigneten rechteckigen Punktgitter (z. B. 400 x 400 Punkte) ab, das den Pixeln auf Ihrem Monitor zugeordnet wird.
  • Sei C für jeden Punkt / jedes Pixel der Punkt, berechne beispielsweise 20 Terme der entsprechenden iterierten Folge z 1 , z 2 , z 3 , ... und überprüfe, ob sie "ins Unendliche geht". In der Praxis können Sie während der Iteration prüfen, ob der absolute Wert eines der 20 Begriffe größer als 2 ist (wenn einer der Begriffe dies tut, sind die nachfolgenden Begriffe garantiert unbegrenzt). Wenn einige z_k tun, geht die Sequenz "ins Unendliche"; Andernfalls können Sie es als begrenzt betrachten.
  • Wenn die Sequenz, die einem bestimmten Punkt C entspricht, begrenzt ist, zeichnen Sie das entsprechende Pixel auf dem Bild in Schwarz (denn es gehört zur Mandelbrot-Menge). Andernfalls zeichnen Sie es in einer anderen Farbe. Wenn Sie Spaß haben und hübsche Handlungen erstellen möchten, zeichnen Sie diese je nach Größe der Bauchmuskeln (20. Term) in verschiedenen Farben.

Die erstaunliche Tatsache bei Fraktalen ist, wie wir aus einfachen und scheinbar harmlosen Anforderungen eine enorm komplexe Menge (insbesondere die Grenze der Mandelbrot-Menge) erhalten können.

Genießen!


10

Wenn komplexe Zahlen Kopfschmerzen verursachen, gibt es eine breite Palette von Fraktalen, die mit einem L-System formuliert werden können. Dies erfordert die Interaktion einiger Ebenen, aber jede ist für sich genommen interessant.

Zuerst brauchst du eine Schildkröte. Vorwärts, Zurück, Links, Rechts, Stift hoch, Stift runter. Es gibt viele lustige Formen, die mit Schildkrötengrafiken unter Verwendung der Schildkrötengeometrie erstellt werden können, auch ohne dass ein L-System sie antreibt. Suchen Sie nach "LOGO-Grafiken" oder "Turtle-Grafiken". Ein vollständiges LOGO- System ist in der Tat eine Lisp- Programmierumgebung, die eine nicht parästhesierte polnische Cambridge- Syntax verwendet. Aber Sie müssen nicht annähernd so weit gehen, um mit dem Schildkrötenkonzept ein paar hübsche Bilder zu machen.

Dann benötigen Sie eine Schicht, um ein L-System auszuführen. L-Systeme sind mit Post-Systemen und Semi-Thue-Systemen verwandt und überschreiten wie virii die Grenze der Turing-Vollständigkeit. Das Konzept ist das Umschreiben von Strings . Es kann als Makroerweiterung oder als Prozedursatz mit zusätzlichen Steuerelementen zum Binden der Rekursion implementiert werden. Wenn Sie die Makro-Erweiterung verwenden (wie im folgenden Beispiel), benötigen Sie weiterhin eine Prozedur zum Zuordnen von Symbolen zu Turtle-Befehlen und eine Prozedur zum Durchlaufen der Zeichenfolge oder des Arrays, um das codierte Turtle-Programm auszuführen. Für einen Prozedurensatz mit begrenzter Rekursion ( z. B. ) binden Sie die Turtle-Befehle in die Prozeduren ein und fügen jeder Prozedur entweder Überprüfungen auf Rekursionsebene hinzu oder rechnen sie einer Handlerfunktion aus.

Hier ist ein Beispiel eines Pythagoras-Baums in Postscript mit Makro-Erweiterung und einem sehr abgekürzten Satz von Turtle-Befehlen. Einige Beispiele in Python und Mathematica finden Sie in meiner Code-Golf-Herausforderung .

ps l-system pythagoras baum luser-droog


Das Bild wurde mit der hier beschriebenen Technik erstellt , um einen kurzen Codeausschnitt mit einer kleinen Abbildung zu kombinieren.
Luser Droog

8

Es gibt ein großartiges Buch namens Chaos and Fractals , das am Ende jedes Kapitels einen einfachen Beispielcode enthält, der ein Fraktal oder ein anderes Beispiel implementiert. Als ich dieses Buch vor langer Zeit las, konvertierte ich jedes Beispielprogramm (in einem einfachen Dialekt) in ein Java-Applet, das auf einer Webseite ausgeführt wird. Die Applets finden Sie hier: http://hewgill.com/chaos-and-fractals/

Eines der Beispiele ist eine einfache Mandelbrot-Implementierung.


6

Ein weiteres hervorragendes Fraktal ist das Sierpinski-Dreieck-Fraktal.

Zeichnen Sie grundsätzlich drei Ecken eines Dreiecks (ein gleichseitiges Dreieck wird bevorzugt, aber jedes Dreieck funktioniert) und beginnen Sie dann einen Punkt P an einer dieser Ecken. Bewegen Sie P nach dem Zufallsprinzip zur Hälfte in eine der drei Ecken und zeichnen Sie dort einen Punkt. Bewegen Sie P erneut auf halber Strecke in Richtung einer beliebigen Ecke, zeichnen Sie und wiederholen Sie den Vorgang.

Sie würden denken, dass die zufällige Bewegung ein zufälliges Ergebnis erzeugen würde, aber das tut es wirklich nicht.

Referenz: http://en.wikipedia.org/wiki/Sierpinski_triangle


2
Dies ist wirklich die Grundlage eines IFS, das als Verallgemeinerung der von Ihnen beschriebenen Methode angesehen werden kann.
Algorias

6

Das Sierpinski-Dreieck und die Koch-Kurve sind spezielle Arten von Flammenfraktalen. Flammenfraktale sind ein sehr verallgemeinerter Typ eines iterierten Funktionssystems, da es nichtlineare Funktionen verwendet.

Ein Algorithmus für IFS: es lautet wie folgt:

Start with a random point.

Wiederholen Sie die folgenden Schritte viele Male (mindestens eine Million, abhängig von der endgültigen Bildgröße):

Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5. Plot the new point on the screen.

Wenn sich der Punkt außerhalb des Bildschirms befindet, wählen Sie stattdessen zufällig einen neuen innerhalb des Bildschirms aus.

Wenn Sie schöne Farben wünschen, lassen Sie die Farbe von der zuletzt verwendeten Transformation abhängen.


5

Ich würde mit etwas Einfachem beginnen, wie einer Koch-Schneeflocke . Es ist ein einfacher Vorgang, eine Linie zu nehmen und zu transformieren und den Vorgang dann rekursiv zu wiederholen, bis er ordentlich aussieht.

Etwas sehr Einfaches wie 2 Punkte (eine Linie) zu nehmen und einen dritten Punkt (eine Ecke) hinzuzufügen und dann jeden neuen Abschnitt zu wiederholen, der erstellt wird.

fractal(p0, p1){
    Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
    fractal(p0,Pmid);
    fractal(Pmid, p1);
}

5

Ich denke, Sie sehen Fraktale möglicherweise nicht als Algorithmus oder Programmiermittel. Fraktale sind ein Konzept! Es ist ein mathematisches Konzept, bei dem sich detaillierte Muster wiederholen.

Daher können Sie ein Fraktal auf verschiedene Arten und mit verschiedenen Ansätzen erstellen, wie in der folgenden Abbildung dargestellt.

Geben Sie hier die Bildbeschreibung ein

Wählen Sie einen Ansatz und untersuchen Sie, wie Sie ihn implementieren können. Diese vier Beispiele wurden mit Marvin Framework implementiert . Die Quellcodes finden Sie hier


3

Das Mandelbrot-Set wird generiert, indem eine Funktion wiederholt ausgewertet wird, bis sie überläuft (eine definierte Grenze), und dann überprüft wird, wie lange Sie zum Überlaufen gebraucht haben.

Pseudocode:

MAX_COUNT = 64 // if we haven't escaped to infinity after 64 iterations, 
               // then we're inside the mandelbrot set!!!

foreach (x-pixel)
  foreach (y-pixel)
    calculate x,y as mathematical coordinates from your pixel coordinates
    value = (x, y)
    count = 0
    while value.absolutevalue < 1 billion and count < MAX_COUNT
        value = value * value + (x, y)
        count = count + 1

    // the following should really be one statement, but I split it for clarity
    if count == MAX_COUNT 
        pixel_at (x-pixel, y-pixel) = BLACK
    else 
        pixel_at (x-pixel, y-pixel) = colors[count] // some color map. 

Anmerkungen:

Wert ist eine komplexe Zahl. Eine komplexe Zahl (a + b i) wird quadriert, um (a a-b * b + 2 * a b i) zu ergeben. Sie müssen einen komplexen Typ verwenden oder diese Berechnung in Ihre Schleife aufnehmen.


1
Sind Sie sicher über value.absolutevalue <1 Milliarde ??? Sobald value.absolutevalue über 2 liegt, wird es "entkommen" und ins Unendliche gehen. Sie müssen also nur bis zu 2 testen, nicht bis zu 1 Milliarde.
Abelenky

3

Einfach und grafisch ansprechend gehen nicht wirklich Hand in Hand. Wenn Sie es ernst meinen mit der Programmierung von Fraktalen, empfehle ich Ihnen, sich über iterierte Funktionssysteme und die Fortschritte zu informieren, die beim Rendern erzielt wurden.

http://flam3.com/flame_draves.pdf


3

Hier ist ein einfacher und leicht verständlicher Code in Java für Mandelbrot und andere fraktale Beispiele

http://code.google.com/p/gaima/wiki/VLFImages

Laden Sie einfach die Datei BuildFractal.jar herunter, um sie in Java zu testen, und führen Sie sie mit dem folgenden Befehl aus:

java -Xmx1500M -jar BuildFractal.jar 1000 1000 Standard-MANDELBROT

Der Quellcode kann auch kostenlos heruntergeladen / erkundet / bearbeitet / erweitert werden.


2

Hier ist ein Codepen, den ich für das Mandelbrot-Fraktal mit einfachem Javascript und HTML geschrieben habe.

Hoffentlich ist der Code leicht zu verstehen.

Der komplizierteste Teil ist das Skalieren und Übersetzen der Koordinatensysteme. Kompliziert ist auch die Erstellung der Regenbogenpalette.

function mandel(x,y) {
  var a=0; var b=0;
  for (i = 0; i<250; ++i) {
    // Complex z = z^2 + c
    var t = a*a - b*b;
    b = 2*a*b;
    a = t;
    a = a + x;
    b = b + y;
    var m = a*a + b*b;
    if (m > 10)  return i;
  }
  return 250;
}

Geben Sie hier die Bildbeschreibung ein


Elegantes und konsequentes Beispiel. Danke fürs Teilen;)
blurryroots

1

Die oben genannten Personen verwenden die Suche nach Mittelpunkten für Sierra Pinski und Koch. Ich würde viel mehr empfehlen, Formen zu kopieren, zu skalieren und dann zu übersetzen, um den "fraktalen" Effekt zu erzielen. Pseudocode in Java für sierpinski würde ungefähr so ​​aussehen:

public ShapeObject transform(ShapeObject originalCurve)
    {
        Make a copy of the original curve
        Scale x and y to half of the original
        make a copy of the copied shape, and translate it to the right so it touches the first copied shape
        make a third shape that is a copy of the first copy, and translate it halfway between the first and second shape,and translate it up
        Group the 3 new shapes into one
        return the new shape
    }

1

Manchmal programmiere ich Fraktale zum Spaß und als Herausforderung. Sie finden sie hier . Der Code wird mit der Bibliothek P5.js in Javascript geschrieben und kann direkt aus dem HTML-Quellcode gelesen werden.

Für diejenigen, die ich gesehen habe, sind die Algorithmen recht einfach. Finden Sie einfach das Kernelement und wiederholen Sie es dann immer wieder. Ich mache es mit rekursiven Funktionen, kann aber anders gemacht werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.