I use fractals as my “Hello World” when I want to explore graphics libraries. Since I’m learning SFML at the same time I’m learning C++ I figured it would be a good idea to explore different ways of doing the same thing.
I’m going to go into it in detail, but here’s a C-style implementation. Over the next few days I’ll see if I can implement a proper C++ class-based approach that achieves the same result.
#include <SFML/Graphics.hpp> void CalcMandelbrotSet(int screenHoriz, int screenVert); float PixelCoordToGraphCoord(int pixelCoord, float graphWidth, int imageWidth, float graphMin); int CalcMandelbrotEscapeValueForComplexNum(float real, float imaginary, int escapeMax); int horizontalResolution = 200; int verticalResolution = 200; int escapeMax = 500; float graphXMax = 2; float graphXMin = -0.5; float graphYMax = 1; float graphYMin = -1; sf::VertexArray varray; int main() { sf::RenderWindow window(sf::VideoMode(horizontalResolution, verticalResolution), "Mandelbrot"); CalcMandelbrotSet(horizontalResolution, verticalResolution); while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(); window.draw(varray); window.display(); } return 0; } void CalcMandelbrotSet(int screenHoriz, int screenVert) { varray.clear(); float graphX; float graphY; int x, y, escape; sf::Vertex vertex; for (y = 0; y < screenVert; y++) { graphY = PixelCoordToGraphCoord(y, graphYMax - graphYMin, screenVert, graphYMin); for (x = 0; x < screenHoriz; x++) { vertex.position = sf::Vector2f(x, y); graphX = PixelCoordToGraphCoord(x, graphXMax - graphXMin, screenHoriz, graphXMin); escape = CalcMandelbrotEscapeValueForComplexNum(graphX, graphY, escapeMax); if (escape == escapeMax) { vertex.color = sf::Color::Green; } else { vertex.color = sf::Color::White; } varray.append(vertex); } } } float PixelCoordToGraphCoord(int pixelCoord, float graphWidth, int imageWidth, float graphMin) { return ((float)pixelCoord * (graphWidth / (float)imageWidth)) + graphMin; } int CalcMandelbrotEscapeValueForComplexNum(float real, float imaginary, int escapeMax) { float zReal, zImag; float z0Real, z0Imag; int n, escape; zReal = zImag = 0; z0Real = z0Imag = 0; for (n = 0; n <= escapeMax; n++) { z0Real = ((zReal * zReal) - (zImag * zImag) - real); z0Imag = (2 * (zReal * zImag)) + imaginary; if (((z0Real * z0Real) + (z0Imag * z0Imag)) >= 4) { escape = n; return escape; } zReal = z0Real; zImag = z0Imag; escape = escapeMax; } return escape; }
Nothing too terribly elaborate. I split out some of the more interesting calculations into their own functions for readability.