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