With the onset of a new year, I’ve decided to shift my focus away from grinding out algorithm-based problems and start to code some actual projects. I’ve always been curious about fractals, and although I could explain them reasonably well, I wanted to see if I could implement them using only the console in C++, coupled with pan/zoom functionality.
The main idea behind the entire program is this: construct a 2D vector array where each element represents a pixel with a coordinate position in the complex plane.
When we think of the elements in this way, implementing the rest of the functionality becomes quite trivial. For starters, I decided to work with the Mandelbrot set. The next thing to do was to add a boolean function that determines whether or not each element is one that is included in the Mandelbrot set or not. We iteratively apply the formula (see image below) on each coordinate within the grid, and check after each iteration if the answer has remained bounded or not. If it is bounded after n iterations, it is within the set.
We also pass in a count variable by reference, which we will use to store the amount of times it takes for a non-set coordinate to become unbounded, to assign each element a respective color later. For now, however, elements not included within the set will be assigned an asterisk. Elements contained within the set will be colored black. Doing so on a grid of 14x14, we get the following result.
By adjusting how close the elements were together (i.e. changing the 0.5 spacing in the first illustration to a smaller value), we could increase the detail of the Mandelbrot, and keep it centered by resizing the vector grid according to the formula:
Lowering 𝛿 to 0.021 gives this result:
And then to 0.007:
While this looks fine, we’re still lacking an essential part of the Mandelbrot set: color. It’s time to bring back the count variable I mentioned earlier, and use that to assign a color based on range. For my program, I would change the color for every 10 iterations passed:
With the basic Mandelbrot finished, it was now time to implement zooming and panning functionality. I decided to use arrow keys for movement, and the ‘Z’ and ‘X’ keys for zooming and un-zooming, respectively. The way to implement this was quite simple. By having a constant screen size, and dividing the 𝛿 by some factor greater than 1 each time ‘Z’ was pressed, the screen would zoom in. I also changed the asterisks to a full-block ASCII character, as it looks more like a pixel.
To handle the panning, I would increment or decrement the X and Y based on what arrow key is pressed, and then call the GenerateSet function again to refresh the set based on the updated parameters.
You may have noticed that the view of the Mandelbrot is rather restricted. In order to combat this, I created a function that “renders” the current view of the Mandelbrot using a very large grid. This shows a lot of detail that is otherwise out of the normal viewing range, which allowed me to get some really interesting and beautiful screenshots. Of course, the program is not limited to just the Mandelbrot fractal; it has the functionality to display them all.
Overall, this small project was a great start to the new year and endless amounts of fun. I find myself messing around with it for hours, trying to find new spots within the fractal to screenshot and add to my collection. There are probably a lot of ways to do this better, however it got the job done and helped fill in my gaps of knowledge regarding the Mandelbrot and Julia sets, as well as fractal generation. Thank you for reading.