[JAVA] Draw a too beloved Mandelbrot set in Processing

Introduction

This article is the 22nd day article of Meiji University Comprehensive Mathematics Advent Calender 2017. This is the 7th appearance of this Advent Calender. Thank you.

Target

** Draw a Mandelbrot set in Processing. ** **

What is the Mandelbrot set?

A Mandelbrot set is a beautiful figure. This is my favorite shape. I even have a tie like this. Screen Shot 2017-12-22 at 02.04.01.png Indispensable for math-related events. cool.

It's not good just to love, so let's define it properly.

For the complex number $ c $, consider the complex number sequence $ z_0, z_1, z_2, \ cdots $ obtained by $ z_0 = 0, \ z_ {n + 1} = z_n ^ 2 + c $. The Mandelbrot set is the entire $ c , which is $ \ lim_ {n \ to \ infinty} z_n <\ intty $$.

In short, it's about getting a well-behaved complex number $ c $ that doesn't diverge to infinity even if you do $ z_ {n + 1} = z_n ^ 2 + c $ over and over again.

To draw on a computer

Now, let's implement it in Processing, but Processing and Java do not have complex class. Of course, you can implement a complex class, but you can attack it in a different way.

Recall that complex numbers can be divided into real and imaginary parts, let's say $ c = a + bi $. In a nutshell, both $ a $ and $ b $ are real numbers, and $ i $ is an imaginary unit. $ i = \ sqrt [] {-1} $. Also, let's say $ z_n = x_n + iy_n $. Again, $ x_n $ and $ y_n $ are real numbers.

Now, let's substitute it for the recurrence formula shown above. Substituting

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

It will be. Since both $ x_ {n + 1} $ and $ y_ {n + 1} $ are real numbers, we have two recurrence formulas for the real and imaginary parts.

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

All you have to do is implement this and find $ a $ and $ b $ so that $ x_n $ and $ y_n $ do not diverge infinitely.

What does it mean to not diverge to infinity?

We know the following about when the sequence $ z_0, z_1, \ cdots $ for the Mandelbrot set diverges to infinity.

is therenabout|z_n| \ge 2Then, the sequence diverges to infinity.

So, if you keep track of $ z_n $ and its absolute value, that is, $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $, becomes 2 or more, the $ c $ you were thinking about at that point is the Mandelbrot set. It means that it is confirmed that you are not a member.

In other words, we can see that the points of the Mandelbrot set are all inside a circle with a radius of 2.

Ideas for drawing

The only thing left is how to draw. First, consider the range in which you want to draw the Mandelbrot set. Here, let's assume that both the real axis and the imaginary axis are from -2 to 2. As you can see from the section above, this gives you the full picture of the Mandelbrot set.

Let's divide the area to be drawn next in a grid pattern. For example, let's divide it into 600 vertically and horizontally. Screen Shot 2017-12-22 at 03.08.16.png

Then choose a point that represents each grid. This time, the upper left of the four corners of each square will be represented.

Finally, let's calculate the recurrence formula of the Mandelbrot set for all grids. In this example, calculate with 600 x 600 = 360,000 grids and remember whether or not it diverged. If you decide the number of calculations in advance and $ \ sqrt [] {x_n ^ 2 + y_n ^ 2} $ is less than 2 all the way to the number of calculations, that $ c $ is an element of the Mandelbrot set.

program

I devised various ways to make it look beautiful. By the way, Processing is 3 series.

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

Execution result

Overall view (actual axis is -2.0 to 0.7) Screen Shot 2017-12-23 at 22.11.29.png

The real axis is roughly (-0.9 to -0.6). The Seahorse valley is a lovely and irresistible place. Screen Shot 2017-12-22 at 04.44.00.png

Conclusion

** I was able to draw the Mandelbrot set. ** **

Recommended Posts

Draw a too beloved Mandelbrot set in Processing
[Question] Draw a diamond in a rectangle
Steps to set a favicon in Rails
Escape processing when creating a URL in Ruby
Create a simple batch processing framework in Eclipse.
Set up a webhook in Shopify's custom app
Bitmap too large to be uploaded into a texture trying to set a large Bitmap in Android ImageView
[Ruby / Rails] Set a unique (unique) value in the class
Addition of variables in iterative processing in a while statement
[Rails 6] How to set a background image in Rails [CSS]
Call a program written in Swift from Processing (Java)