Page 1 of 1

Mandelbrot + SFML

Posted: Wed Dec 08, 2010 9:05 pm
by ibly31
Hi guys, its been a while since I've posted asking for help. Basically what I'm doing pertains to all programming, the SFML is just what I'm using to show my results. I have recently become very interested in fractals and mathematical ideas like it. I decided to check out the wikipedia page for some help to graph the mandelbrot set. I've got it working:

http://www.ibly31.com/Stuff/thankyouthreeve.png

But its black and white. The wikipedia page says to graph each color depending on the number of iterations it took to reach. But right now its only taking 1 iteration or infinity. I'll post some code, hopefully you can spot what I'm doing wrong. Thanks!

EDIT: Infinity as in taking the max_iterations and exiting the loop due to the fact that it is taking too long to compute one pixel. If any of you know why it has to scale from -2.5 to 1, and -1 to 1, please explain! Thanks

Code: Select all

sf::Color ColorForPointOnFractal(float xx, float yy){
	float x0 = ((xx * 3.5) / SCREENWIDTH ) - 2.5;
	float y0 = ((yy * 2)   / SCREENHEIGHT) - 1;
// these first two lines take the XX and YY values (0-1440, 0-900 respectively) and fit them into a scale of -2.5 to 1, and -1 to 1 respectively. The wikipedia's psuedocode section told //me to do this, i don't really understand why though.
	float x = 0;
	float y = 0;
	
	unsigned int iteration = 0;
	unsigned int max_iteration = 1000;
	
	while(x*x + y*y <= 4 && iteration < max_iteration){
		float xtemp = x*x - y*y + x0;
		y = 2*x*y + y0;
		
		x = xtemp;
		iteration++;
	}
	if(iteration == max_iteration)
		return sf::Color(125, 125, 125);
	else
		return sf::Color(255, 255, 255);
		//return sf::Color(iteration / max_iteration * 255, iteration / max_iteration * 255, iteration / max_iteration * 255);
		// this commented out line basically warps the iteration number from a scale from 1-255 resulting in a grayscale value for the color.
	
}

void CalculateFractal(){
	for(int x = 0; x < SCREENWIDTH; x++){
		for(int y = 0; y < SCREENHEIGHT; y++){
			Fractal.SetPixel(x, y, ColorForPointOnFractal((float)x, (float)y));
		}
	}
}

Re: Mandelbrot + SFML

Posted: Thu Dec 09, 2010 12:16 am
by qpHalcy0n
It does not appear that your code is wrong. However, your color logic appears to be flawed. You should pass black (255, 255, 255) if it's reached a max iteration. The colors are usually done from a LUT. So before you start the calculation you can either read in a real pretty color gamut texture, or you can procedurally generate a color buffer with however many entries before you do this. However large the buffer is (width * height) turns into a seed for a lookup.

So if you have 4096 individual pixels in the LUT, and you've run through n iterations, the color becomes LUT[n % 4096]; Thats what makes them look really pretty.

The first two lines are a screen space mapping. You're taking the width and mapping it to a -2.5 to 1 range, and the height to a -1 to 1 range. The mandelbrot set has a domain somewhere around -2 to 1 and a range from around -1 to 1. Values lying in the screenspace range are useless for this algorithm, hence the mapping.

Re: Mandelbrot + SFML

Posted: Thu Dec 09, 2010 8:31 am
by N64vSNES
Jesus christ I've got such a headache now :shock2:

Re: Mandelbrot + SFML

Posted: Thu Dec 09, 2010 2:02 pm
by ibly31
QP, thanks for your explanation - it cleared stuff up a bit.

The problem still remains though, basically what it is is the while loop is only repeating once, or infinity. Its no where in between. The article says things take usually like 1,2,5,8 etcetera. My original idea was to color the infinities just black, and then have the number of iterations / max Iterations to get a percent, then multiply that by 255 to get a grayscale value... but it was returning black because it would end up taking only 1 iteration EVERY time other than the ones that take infinity. I changed the part you mentioned to (125,125,125) because I thought maybe It was just giving a very dark color for the ones that did take multiple iterations and wanted to differentiate... but no.

If you didn't read that paragraph (TL;DR), basically what I'm saying is that for some reason (maybe float calculations are off, maybe something else) each tested location from (-2.5, 1) and (-1, 1) is either taking a single iteration to exit out of the while loop, or taking infinity (the max iterations). It should be somewhere in between to get the colors that I want.

Re: Mandelbrot + SFML

Posted: Thu Dec 09, 2010 2:57 pm
by qpHalcy0n
Well the reason your color gradient is not working is because iteration / max_iteration is an unsigned integer division which will ALWAYS result in 0 since iteration is ALWAYS less than max_iteration. Cast either one of those values to float and you should see the greyscale gradient. The code appears to terminate in as timely a manner as it can, thus it appears the algorithm is working. It's difficult to debug something like this without a graphical aid such as your greyscale mapping as this algorithm won't yield you any interesting results until you get close to 600,000 iterations deep so simply taking a cursory step through will be fruitless for you. :)