File:Mandelbrot set rainbow colors.png

From testwiki
Jump to navigation Jump to search
Original file (4,000 × 3,000 pixels, file size: 2.21 MB, MIME type: image/png)

This file is from Wikimedia Commons and may be used by other projects. The description on its file description page there is shown below.

Summary

Description
English: Color image of the mandelbrot set. The color indicates the number of iterations before the absolute value of a complex number exceeds a certain value. The complex number is taken from the pixels coordinates. Succeeding values are calculated as .
Date
Source Own work
Author Geek3

Source Code

This image can be completely generated by the following source code. If you have the programs "g++", "netpbm" and "optipng" installed, the following commands compile the image:

g++ mandelbrot.cpp -o mandelbrot
./mandelbrot
mv mandelbrot.ppm mandelbrot1.ppm && cp mandelbrot1.ppm mandelbrot2.ppm &&
pnmflip -tb mandelbrot2.ppm > mandelbrot3.ppm && rm mandelbrot2.ppm &&
pnmcat -tb mandelbrot1.ppm mandelbrot3.ppm > mandelbrot.ppm && rm mandelbrot{1,3}.ppm
pnmtopng mandelbrot.ppm > mandelbrot.png && rm mandelbrot.ppm
optipng mandelbrot.png

Source code

C++ source code - click on the right to view

mandelbrot.cpp:
/* mandelbrot
* Copyright (C) 2008 Wikimedia Foundation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <iostream>
#include <cmath>
using namespace std;


/********************************** settings **********************************/
const int w = 4000; // image width
const int h = 1500; // image height
const double mx = 0.7, my = 0.0; // relative position of the origin 
const int u = 0.3 * w; // unit
const int iters = 2000; // maximum number of iterations
const bool smooth = true; // flattens the color steps
const int subpix = 16; // must be >= 1; decrease for much faster evaluation!
/******************************************************************************/

double fc(double x)
{	// makes the color slightly smoother
	if (x <= 0.0) return(0.0);
	if (x >= 1.0) return(1.0);
	return(2.0 * (1.0  + x * sqrt(x) - (1 - x) * sqrt(1 - x)) - 3.0 * x);
}

void color(double x, double rgb[])
{
	x += 0.52;	// arbitrary phase shift
	x -= (int)x;
	if (x < 0)
		x += 1.0;
	x *= 6;
	int xx = x;
	x -= xx;
	switch (xx)
	{
		case 0:	rgb[2] = 0; rgb[0] = 1.0; rgb[1] = fc(1.0 - x);
			break;
		case 1:	rgb[1] = 0; rgb[0] = 1.0; rgb[2] = fc(x);
			break;
		case 2:	rgb[1] = 0; rgb[2] = 1.0; rgb[0] = fc(1.0 - x);
			break;
		case 3:	rgb[0] = 0; rgb[2] = 1.0; rgb[1] = fc(x);
			break;
		case 4:	rgb[0] = 0; rgb[1] = 1.0; rgb[2] = fc(1.0 - x);
			break;
		case 5:	rgb[2] = 0; rgb[1] = 1.0; rgb[0] = fc(x);
			break;
	}
}

double flatten(double x0, double y0, double x, double y)
{	// creates a continuous gradient instead of color steps
	int steps = 0;
	double sqrxy = x * x + y * y;
	if (sqrxy >= 4.0)
	{
		while (sqrxy < 65536)	// high value >> 2
		{
			double x_old = x;
			x = x * x - y * y;
			y = 2 * x_old * y;
			x += x0;
			y += y0;
			steps++;
			sqrxy = x * x + y * y;
		}
		double m = steps + 1.5 - log2(log2(sqrxy));
		return(m);
	}
	return(0.0);
}

bool outcircle(double cx, double cy, double r, double x, double y)
{	// checks if (x,y) is outside the circle around (x0,y0) with radius r
	x -= cx;
	y -= cy;
	if (x * x + y * y > r * r)
		return(true);
	return(false);
}

int main()
{
	// open image file
	FILE *image_file = fopen("mandelbrot.ppm", "wb");
	fprintf(image_file, "P6\n%d %d\n255\n", w, h);
	
	// iterate pixels
	for(int row = 0; row < h; row++) {
	for(int column = 0; column < w; column++)
	{		
		double sum[3] = { 0.0, 0.0, 0.0 };
		// iterate subpixels
		for (int i = 0; i < subpix; i++) {
		for (int j = 0; j < subpix; j++)
		{
			// pixel -> coordinates
			double x0 = (-w * mx + column
					+ (j + 0.5) / subpix) / u;
			double y0 = (h * (1.0 - my)
					- row - (i + 0.5) / subpix) / u;
			double x = x0, y = y0;
			int n = -1;
			
			// skip values we know they are inside
			if ((outcircle(-0.11, 0.0, 0.63, x0, y0) || x0 > 0.1)
				&& outcircle(-1.0, 0.0, 0.25, x0, y0)
				&& outcircle(-0.125, 0.744, 0.092, x0, y0)
				&& outcircle(-1.308, 0.0, 0.058, x0, y0)
				&& outcircle(0.0, 0.25, 0.35, x0, y0))
			{
				for (int it = 0; it <= iters; it++)
				{	// iteration steps
					/********* fractal generation ********/
					double x_old = x;
					x = x * x - y * y;
					y = 2 * x_old * y;
					x += x0;
					y += y0;
					/*************************************/
					if (x * x + y * y > 4)
					{	// value is outside
						n = it;
						break;
					}
				}
			}
			
			double subpixel[3];
			if (n < 0)
			{	// black color inside
				for (int c = 0; c < 3; c++)
					subpixel[c] = 0;
			}
			else
			{
				double m = n;
				if (smooth)
					m += flatten(x0, y0, x, y);
				if (m <= -1.8)
					m = -0.8;
				m = 0.23 * log(1.8 + m);
				color(m, subpixel);
			}
			for (int c = 0; c < 3; c++)
				sum[c] += subpixel[c];
		}}
		
		// subpixels finished -> make arithmetic mean
		char pixel[3];
		for (int c = 0; c < 3; c++)
			pixel[c] = (int)(255.0 * sum[c] / (subpix * subpix)  + 0.5);
		fwrite(pixel, 1, 3, image_file);
		//pixel finished
	}}
	fclose(image_file);
	return(0);
}


Licensing

Geek3, the copyright holder of this work, hereby publishes it under the following licenses:
GNU head Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.
w:en:Creative Commons
attribution
This file is licensed under the Creative Commons Attribution 3.0 Unported license.
Attribution:
You are free:
  • to share – to copy, distribute and transmit the work
  • to remix – to adapt the work
Under the following conditions:
  • attribution – You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
You may select the license of your choice.

Captions

Zoom in 10⁷³⁵⁶

Items portrayed in this file

depicts

November 2008

2,317,382 byte

3,000 pixel

4,000 pixel

image/png

10a4d547858f3ae92c50e35ddf19c14665899979

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current00:41, 22 November 2008Thumbnail for version as of 00:41, 22 November 20084,000 × 3,000 (2.21 MB)wikimediacommons>Geek3smaller version, which is scalable by wikimedia software.

The following page uses this file: