Loading web-font TeX/Math/Italic

Thursday, May 23, 2019

Mandelbrot and Julia Fractals

The Mandelbrot set and the Julia sets are very similar in the way they're defined. Both are generated iteratively by the equation:

z_{n+1} = z_{n}^2 + c

Where z and c are complex numbers.

The Mandelbrot set is generated by starting with z_{0}=0 and varying c. Each c that causes the iteration to converge to some complex number is part of the set, while each c that causes it to diverge is not part of the set.

The Julia sets are similar to the Mandelbrot set, except z_{0} is varied, and c is constant. Each c will create a unique Julia set.

Both sets can be visualized by treating each pixel in an image as a complex number where the horizontal axis is the real component of a complex number, and the vertical axis is the imaginary component. Each pixel will represent c in the Mandelbrot set and z_{0} in the Julia sets.

Here is an image of the Mandelbrot set that I generated using a small program I wrote in C++



Here is the most relevant function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::vector<unsigned char> generateMandelbrot(const unsigned width, const unsigned height, int iterations, double scale, double realAnim, double imagAnim) {
 int offset{ -static_cast<int>(width) / 4 };
 int maxX{ static_cast<int>(width / 2) + offset }, minX{ -static_cast<int>(width / 2) + offset };
 int maxY{ static_cast<int>(height / 2) }, minY{ -maxY };
 std::vector<unsigned char> img(width * height * 4, 255);

 for (int y{ minY }; y < maxY; ++y)
  for (int x{ minX }; x < maxX; ++x) {
   Complex z{ realAnim, imagAnim };
   Complex c{ x / (scale * 500), y / (scale * 500) };
   int i;
   for (i = 0; i < iterations; ++i)
   {
    z = z * z + c;
    if (complexLength(z) > 2)
     break;
   }
   unsigned index{ 4 * width * (y + height / 2) + 4 * (x + width / 2 - offset) };
   addRGBA(img, index, static_cast<double>(i) / iterations);
  }
 return img;
}


Here are two Julia fractals:



And here's the function I wrote for the Julia fractals:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
std::vector<unsigned char> generateJulia(const unsigned width, const unsigned height, int iterations, double scale, int offset, const Complex& c) {
 int maxX{ static_cast<int>(width / 2) + offset }, minX{ -static_cast<int>(width / 2) + offset };
 int maxY{ static_cast<int>(height / 2) }, minY{ -maxY };
 std::vector<unsigned char> img(width * height * 4, 255);

 for (int y{ minY }; y < maxY; ++y)
  for (int x{ minX }; x < maxX; ++x) {
   Complex z{ x / (scale * 500), y / (scale * 500) };
   int i;
   for (i = 0; i < iterations; ++i)
   {
    z = z * z + c;
    if (complexLength(z) > 2)
     break;
   }
   unsigned index{ 4 * width * (y + height / 2) + 4 * (x + width / 2 - offset) };
   addRGBA(img, index, static_cast<double>(i) / iterations);
  }
 return img;
}

I was curious what it would look like to vary some of the parameters for Mandelbrot and Julia fractals so I made an animation of it and put it on my new YouTube channel. It turned out pretty cool, take a look:




No comments:

Post a Comment