algorytm.org

Implementacja w JavaScript



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Buddhabrot - Implementacja w JavaScript
Ocena użytkownikóww: *****  / 1
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 08 listopada 2011 12:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

buddhabrot.js:
//Buddhabrot
//(c) 2011 by Tomasz Lubinski
//www.algorytm.org

/* Render area coordinates */
var minX = -1.5;
var maxX =  1.5;
var minY = -2.0;
var maxY =  1.0;

/* Render area size */
var width = 0;
var height = 0;
var ratioX;
var ratioY;

/* Number of fractal levels */
var levelNum = 100;
var colors = new Array(levelNum+1);

/* Number of iterations (bailout) */
var bailout = 100;
var sequence_x;
var sequence_y;

/* Number of points */
var pointsNum = 10000000;
var currentPointsNum = 0;

/* Fractal image */
var data;
var imageData;
var canvas;
var ctx;

/* initialize color table */
function initializeColors()
{
	for (var level=0; level<=levelNum; level++)
	{
		colors[level] = new Object();
		colors[level].r = 255.0*level/levelNum;
		colors[level].g = 255.0*level/levelNum;
		colors[level].b = 255.0*Math.log(level)/Math.log(levelNum);
	}
}

/* value is inside set in the returned level */
function levelSet(p_re, p_im)
{
	var z_re = 0;
	var z_im = 0;
	var iteration = 0;
	var tmp_re, tmp_im;

	do
	{
		tmp_re = z_re*z_re - z_im*z_im + p_re;
		tmp_im = 2*z_re*z_im + p_im;
		z_re = tmp_re;
		z_im = tmp_im;
		sequence_x[iteration] = tmp_im;
		sequence_y[iteration] = tmp_re;
		iteration++;		
	} while ((z_re*z_re+z_im*z_im) < 4 && iteration < bailout);
	
	if (iteration >= bailout)
	{
		iteration = 0;
	}

	return iteration;
}

/* render Fractal */
function renderFractal()
{
	sequence_x = new Array(bailout);
	sequence_y = new Array(bailout);
	
	/* Clear data */
	for (var i=0; i<width*height; i++)
	{
		data[i] = 0;
	}
	
	currentPointsNum = 0;
	calculateFractal();
}

function calculateFractal()
{
	
	/* Calculate data */
	proccesPointsNum = 10000000 / bailout;
	for (var i=0; i<proccesPointsNum; i++)
	{
		p_im = 4.0*Math.random()-2.0;
		p_re = 4.0*Math.random()-2.0;
		level = levelSet(p_re, p_im);
		for (var j=0; j<level; j++)
		{
			if (sequence_x[j] > minX &&
			    sequence_x[j] < maxX &&
			    sequence_y[j] > minY &&
			    sequence_y[j] < maxY)
			{
				x = Math.floor((sequence_x[j] - minX)/ratioX);
				y = Math.floor((sequence_y[j] - minY)/ratioY);				
				x_dist = ((sequence_x[j] - minX)/ratioX) - x;
				y_dist = ((sequence_y[j] - minY)/ratioY) - y;
				data[x+y*width] += (1.0 - x_dist)*(1.0 - y_dist);
				data[(x+1)+y*width] += (1.0 - x_dist)*(y_dist);
				data[x+(y+1)*width] += (x_dist)*(1.0 - y_dist);
				data[(x+1)+(y+1)*width] += (x_dist)*(y_dist);
			}
		}
	}
	
	/* Check range */
	biggest = data[0];
	smalest = data[0];
	for (var i=1; i<width*height; i++)
	{
		if (data[i] > biggest)
		{
			biggest = data[i];	
		}
		else if (data[i] < smalest)
		{
			smalest = data[i];
		}
	}
	
	/* Generate image */
	for (var i=0; i<height; i++)
	{
		for (var j=0; j<width; j++)
		{
			index = (i*width+j)*4;
			imageData.data[index+3] = 0xff;
			level = 2*Math.floor(((data[j+i*width]-smalest)/(biggest-smalest))*levelNum);
			if (level > levelNum) level = levelNum;
			imageData.data[index+0] = colors[level].r;
			imageData.data[index+1] = colors[level].g;
			imageData.data[index+2] = colors[level].b;
		}
	}
	
	// copy the image data back onto the canvas
	ctx.putImageData(imageData, 0, 0);
	
	/* If not all points are calculated then show percent of done and call this function for 200 ms. */
	currentPointsNum += proccesPointsNum;
	if (currentPointsNum < pointsNum)
	{
		ctx.font          = "15pt Arial";
		ctx.fillStyle     = "red";
		ctx.textBaseline  = "top";
		ctx.textAlign     = "center";
		ctx.fillText(Math.floor((currentPointsNum / pointsNum)*100) + "%", width/2, height - 50);
		setTimeout("calculateFractal()",200);
	}
}

/* initialize environment and render Fractal */
function initializeFractal()
{
	canvas = document.getElementById("canvas");
	ctx = canvas.getContext("2d");

	// read the width and height of the canvas
	width = canvas.width;
	height = canvas.height;

	// create a new pixel array
	data = new Array(width * height);
	imageData = ctx.createImageData(width, height);
	
	ratioX = (maxX - minX) / width;
	ratioY = (maxY - minY) / height;
	
	initializeColors();
	renderFractal();
}
Dodaj komentarz