[JAVA] Dessinez un ensemble de Mandelbrot trop beau avec Processing

introduction

Cet article est l'article du 22ème jour du Calendrier de l'Avent 2017 des mathématiques complètes de l'Université Meiji. C'est la 7e apparition de ce calendrier de l'Avent. Je vous remercie.

Cible

** Dessinez un ensemble de Mandelbrot dans Traitement. ** **

Qu'est-ce que le set Mandelbrot?

Un ensemble Mandelbrot est une belle figure. C'est ma figure préférée. J'ai même une telle cravate. Screen Shot 2017-12-22 at 02.04.01.png Indispensable pour les événements liés aux mathématiques. cool.

Ce n'est pas juste d'aimer, alors faisons une définition mathématique appropriée.

Pour le nombre complexe $ c $, considérons la séquence de nombres complexes $ z_0, z_1, z_2, \ cdots $ obtenue par $ z_0 = 0, \ z_ {n + 1} = z_n ^ 2 + c $. L'ensemble de Mandelbrot est le $ c $ entier, qui est $ \ lim_ {n \ to \ infty} z_n <\ infty $.

En bref, il s'agit d'obtenir un complexe $ c $ bien comporté qui ne diverge pas à l'infini même si vous faites $ z_ {n + 1} = z_n ^ 2 + c $ encore et encore.

Dessiner sur un ordinateur

Maintenant, implémentons-le dans Processing, mais Processing et Java n'ont pas de classe complexe. Bien sûr, vous pouvez implémenter une classe de nombres complexes, mais vous pouvez l'attaquer d'une manière différente.

Rappelez-vous que les nombres complexes peuvent être divisés en parties réelles et imaginaires, disons $ c = a + bi $. En un mot, $ a $ et $ b $ sont des nombres réels et $ i $ est une unité imaginaire. $ i = \ sqrt [] {-1} $. Disons aussi $ z_n = x_n + iy_n $. Encore une fois, $ x_n $ et $ y_n $ sont des nombres réels.

Maintenant, remplaçons-le par l'expression graduelle montrée ci-dessus. Remplacer

\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}

Ce sera. Puisque $ x_ {n + 1} $ et $ y_ {n + 1} $ sont des nombres réels, nous avons deux équations graduelles pour les parties réelle et imaginaire.

\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}

Tout ce que vous avez à faire est d'implémenter ceci et de trouver $ a $ et $ b $ pour que $ x_n $ et $ y_n $ ne divergent pas indéfiniment.

Que signifie ne pas diverger à l'infini?

Nous savons ce qui suit à propos du moment où la séquence $ z_0, z_1, \ cdots $ pour l'ensemble de Mandelbrot diverge à l'infini.

y a-t-ilnsur|z_n| \ge 2Ensuite, la séquence de nombres diverge à l'infini.

Donc, si vous gardez une trace de $ z_n $ et de sa valeur absolue, c'est-à-dire que $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $ devient 2 ou plus, le $ c $ auquel vous pensiez à ce moment-là est l'ensemble de Mandelbrot. Cela signifie qu'il est confirmé que vous n'êtes pas membre.

En d'autres termes, nous pouvons voir que les points de l'ensemble de Mandelbrot sont tous à l'intérieur d'un cercle de rayon 2.

Idées de dessin

La seule chose qui reste est de savoir comment dessiner. Tout d'abord, considérez la plage dans laquelle vous souhaitez dessiner l'ensemble de Mandelbrot. Ici, supposons que l'axe réel et l'axe imaginaire sont tous deux compris entre -2 et 2. Comme vous pouvez le voir dans la section ci-dessus, cela vous donne une image complète de l'ensemble de Mandelbrot.

Divisons la zone à dessiner ensuite dans un motif de grille. Par exemple, divisons-le en 600 verticalement et horizontalement. Screen Shot 2017-12-22 at 03.08.16.png

Choisissez ensuite un point qui représente chaque grille. Cette fois, le coin supérieur gauche des quatre coins de chaque carré sera représenté.

Enfin, calculons la formule de graduation de l'ensemble de Mandelbrot pour tous les treillis. Dans cet exemple, calculez avec 600 x 600 = 360 000 grilles et rappelez-vous si elle a divergé ou non. Si vous décidez à l'avance du nombre de calculs et que $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $ est inférieur à 2 jusqu'au nombre de calculs, ce $ c $ est un élément de l'ensemble de Mandelbrot.

programme

J'ai imaginé différentes façons de le rendre beau. À propos, le traitement est de 3 séries.

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);
    }
  }
}

Résultat d'exécution

Vue d'ensemble (l'axe réel est de -2,0 à 0,7) Screen Shot 2017-12-23 at 22.11.29.png

L'axe réel est à peu près (-0,9 à -0,6). La vallée de Seahorse est un endroit charmant et irrésistible. Screen Shot 2017-12-22 at 04.44.00.png

Conclusion

** J'ai pu dessiner un ensemble de Mandelbrot. ** **

Recommended Posts

Dessinez un ensemble de Mandelbrot trop beau avec Processing
[Question] Dessinez un diamant dans un carré
Traitement d'échappement lors de la création d'une URL dans Ruby
Créez un cadre de traitement par lots simple dans Eclipse.
Configurer un webhook dans l'application personnalisée de Shopify
Bitmap trop volumineux pour être téléchargé dans une texture en essayant de définir un grand Bitmap dans Android ImageView
[Ruby / Rails] Définissez une valeur unique (unique) dans la classe
À propos de l'ajout de variables dans le traitement itératif dans l'instruction while
[Rails 6] Comment définir une image d'arrière-plan dans Rails [CSS]
Appeler un programme écrit en Swift depuis Processing (Java)