Visualizing the Mandelbrot Set with SFML: C Style

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.

This entry was posted in Programming. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s