[JAVA] Zeichnen Sie ein Mandelbrot-Set, das mit Processing zu schön ist

Einführung

Dieser Artikel ist der 22. Tagesartikel des Meiji University Comprehensive Mathematics Advent Calender 2017. Dies ist der 7. Auftritt dieses Adventskalenders. Vielen Dank.

Ziel

** Zeichnen Sie einen Mandelbrot-Satz in Verarbeitung. ** ** **

Was ist das Mandelbrot-Set?

Ein Mandelbrot-Set ist eine schöne Figur. Das ist meine Lieblingsfigur. Ich habe sogar so eine Krawatte. Screen Shot 2017-12-22 at 02.04.01.png Unverzichtbar für mathematikbezogene Ereignisse. cool.

Es ist nicht gut, nur zu lieben, also lasst uns eine richtige mathematische Definition machen.

Betrachten Sie für eine komplexe Zahl $ c $ die komplexe Zahlenfolge $ z_0, z_1, z_2, \ cdots , die durch $ z_0 = 0, \ z_ {n + 1} = z_n ^ 2 + c $$ erhalten wird. Die Mandelbrot-Menge ist das gesamte $ c , also $ \ lim_ {n \ to \ infty} z_n <\ infty $$.

Kurz gesagt, es geht darum, einen gut erzogenen komplexen $ c $ zu erhalten, der nicht ins Unendliche divergiert, selbst wenn Sie $ z_ {n + 1} = z_n ^ 2 + c $ immer und immer wieder tun.

Auf einem Computer zeichnen

Lassen Sie es uns jetzt in Processing implementieren, aber Processing und Java haben keine komplexe Klasse. Natürlich können Sie eine komplexe Zahlenklasse implementieren, aber Sie können sie auf andere Weise angreifen.

Denken Sie daran, dass komplexe Zahlen in Real- und Imaginärteile unterteilt werden können, sagen wir $ c = a + bi $. Kurz gesagt, sowohl $ a $ als auch $ b $ sind reelle Zahlen, und $ i $ ist eine imaginäre Einheit. $ i = \ sqrt [] {-1} $. Sagen wir auch $ z_n = x_n + iy_n $. Wiederum sind $ x_n $ und $ y_n $ reelle Zahlen.

Ersetzen wir nun den oben gezeigten allmählichen Ausdruck. Ersetzen

\begin{eqnarray}
  x_{n + 1} + iy_{n + 1} & = & (x_{n} + iy_n)^2 + (a + bi) \\
  & = & (x_n^2 - y_n^2 + a) \ + \ (2x_ny_n + b)i
\end{eqnarray}

Es wird sein. Da sowohl $ x_ {n + 1} $ als auch $ y_ {n + 1} $ reelle Zahlen sind, haben wir zwei allmähliche Gleichungen für den Real- und den Imaginärteil.

\begin{eqnarray}
x_0 = 0, & \quad &  x_{n + 1} = x_n^2 - y_n^2 + a \\
y_0 = 0, & \quad & y_{n + 1} = 2x_ny_n + b
\end{eqnarray}

Alles was Sie tun müssen, ist dies zu implementieren und $ a $ und $ b $ zu finden, damit $ x_n $ und $ y_n $ nicht auf unbestimmte Zeit voneinander abweichen.

Was bedeutet es, nicht ins Unendliche zu divergieren?

Wir wissen Folgendes, wenn die Sequenz $ z_0, z_1, \ cdots $ für die Mandelbrot-Menge gegen unendlich abweicht.

Gibt esnÜber|z_n| \ge 2Dann divergiert die Zahlenfolge gegen unendlich.

Wenn Sie also $ z_n $ und seinen absoluten Wert verfolgen, dh $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $ wird 2 oder mehr, ist das $ c $, an das Sie zu diesem Zeitpunkt gedacht haben, die Mandelbrot-Menge. Dies bedeutet, dass bestätigt wird, dass Sie kein Mitglied sind.

Mit anderen Worten, wir können sehen, dass sich die Punkte der Mandelbrot-Menge alle innerhalb eines Kreises mit einem Radius von 2 befinden.

Ideen zum Zeichnen

Das einzige, was noch übrig ist, ist, wie man zeichnet. Betrachten Sie zunächst den Bereich, in dem Sie das Mandelbrot-Set zeichnen möchten. Nehmen wir hier an, dass sowohl die reale als auch die imaginäre Achse zwischen -2 und 2 liegen. Wie Sie im obigen Abschnitt sehen können, erhalten Sie das vollständige Bild des Mandelbrot-Sets.

Teilen wir den Bereich, der als nächstes gezeichnet werden soll, in ein Gittermuster. Teilen wir es zum Beispiel vertikal und horizontal in 600 auf. Screen Shot 2017-12-22 at 03.08.16.png

Wählen Sie dann einen Punkt, der jedes Gitter darstellt. Dieses Mal wird die obere linke der vier Ecken jedes Quadrats dargestellt.

Lassen Sie uns abschließend die Graduierungsformel des Mandelbrot-Sets für alle Gitter berechnen. Berechnen Sie in diesem Beispiel mit 600 x 600 = 360.000 Gittern und merken Sie sich, ob es divergiert oder nicht. Wenn Sie die Anzahl der Berechnungen im Voraus festlegen und $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $ bis zur Anzahl der Berechnungen kleiner als 2 ist, ist $ c $ ein Element der Mandelbrot-Menge.

Programm

Ich habe mir verschiedene Möglichkeiten ausgedacht, um es schön aussehen zu lassen. Die Verarbeitung besteht übrigens aus 3 Serien.

mandelbrot.pde


// # of grids
int w = 800;
int h = 700;

// grid information
int[][] m = new int[h][w];
// iteration limit
int iteration = 1000;

// canvas size
float reMin = -2.0;
float reMax = 0.70;
float imMin = (reMin - reMax) * h / (float)w / 2.0;
float imMax = -imMin;

void settings() {
  size(w, h);
}

void setup () {
  background(255);
  
  float a, b;
  
  // iterate Mandelbrot!!!!
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      a = map((float)j, 0, (float)w, reMin, reMax);
      b = map((float)i, 0, (float)h, imMin, imMax);
      
      m[i][j] = isInMandelbrot(a, b);
    }
  }
  
  drawMandelbrot(m);
}

// check whether c = a + bi is in Mandelbrot set
// 1 = yes, -iteration ~ -1 = diverging speed
int isInMandelbrot (float a, float b) {
  float x = 0;
  float y = 0;
  float prevX = x;
  float prevY = y;
  
  for (int i = 0; i < iteration; i++) {
    if (x * x + y * y >= 4.0) {
      return -i;
    }
    else {
      prevX = x;
      prevY = y;
      x = nextX(prevX, prevY, a);
      y = nextY(prevX, prevY, b);
    }
  }
  return 1;
}

// calculating x_{n + 1} and y_{n + 1}
float nextX (float x, float y, float a) {
  return x * x - y * y + a;
}

float nextY (float x, float y, float b) {
  return 2 * x * y + b;
}

// color the canvas
void drawMandelbrot(int[][] m) {
  noStroke();
  
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (m[i][j] == 1) {
        fill(0);
      }
      else {
        fill(map(- m[i][j], 0, iteration * 0.1, 255, 0));
      }
      
      rect(j, i, 1.0, 1.0);
    }
  }
}

Ausführungsergebnis

Gesamtansicht (tatsächliche Achse ist -2,0 bis 0,7) Screen Shot 2017-12-23 at 22.11.29.png

Die reale Achse ist ungefähr (-0,9 bis -0,6). Das Seepferdchen-Tal ist ein schöner und unwiderstehlicher Ort. Screen Shot 2017-12-22 at 04.44.00.png

Fazit

** Ich konnte ein Mandelbrot-Set zeichnen. ** ** **

Recommended Posts

Zeichnen Sie ein Mandelbrot-Set, das mit Processing zu schön ist
[Frage] Zeichne einen Diamanten in ein Quadrat
Escape-Verarbeitung beim Erstellen einer URL in Ruby
Erstellen Sie in Eclipse ein einfaches Stapelverarbeitungsframework.
Richten Sie einen Webhook in der benutzerdefinierten App von Shopify ein
Bitmap zu groß, um in eine Textur hochgeladen zu werden, die versucht, eine große Bitmap in der Android ImageView festzulegen
[Ruby / Rails] Legen Sie einen eindeutigen (eindeutigen) Wert in der Klasse fest
Informationen zum Hinzufügen von Variablen in der iterativen Verarbeitung in der while-Anweisung
[Rails 6] So legen Sie ein Hintergrundbild in Rails [CSS] fest
Rufen Sie ein in Swift geschriebenes Programm von Processing (Java) auf.