Skip to content

Instantly share code, notes, and snippets.

@sahands
Last active December 19, 2015 20:49
Show Gist options
  • Save sahands/6016136 to your computer and use it in GitHub Desktop.
Save sahands/6016136 to your computer and use it in GitHub Desktop.
HTML5 Canvas and Javascript Mandelbrot Fractal
function Complex(real, imaginary) {
this.a = real;
this.b = imaginary;
}
Complex.prototype.abs = function() {
return Math.sqrt(this.a * this.a + this.b * this.b);
};
Complex.prototype.toString = function() {
return "(" + this.a + "," + this.b + ")";
};
Complex.add = function(a, b) {
return new Complex(a.a + b.a, a.b + b.b);
};
Complex.multiply = function(a, b) {
return new Complex(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a);
};
Complex.prototype.add = function(b) {
return Complex.add(this,b);
};
Complex.prototype.multiply = function(b) {
return Complex.multiply(this,b);
};
function MandelbrotPixelValue(z, c, nlimit) {
rmax = 2; // Max value before deciding the point converges to infinity
var j = 0;
for (; j < nlimit && z.abs() < rmax; j++) {
z = z.multiply(z);
z = z.add(c);
}
j *= 3;
return {
r : 240,
g : j % 255,
b : 0,
a : 0xff
};
}
function Fractal(canvasElement, pixelValueFunction) {
this.pixelValueFunc = pixelValueFunction;
this.element = canvasElement;
}
// start indicates where in the complex plane to start, must be of type Complex
// z is the fractal's constant
//
Fractal.prototype.DrawFractal = function(start, inc, z, nlimit, options) {
startTime = new Date().getTime();
context = this.element.getContext("2d");
width = parseInt(this.element.getAttribute("width"));
height = parseInt(this.element.getAttribute("height"));
imageData = context.createImageData(width, height);
var x, y;
var xend = start.a + width * inc;
var yend = start.b + height * inc;
var i = 0, j = 0, c = 0;
for (y = start.b; y < yend && j < height; y += inc) {
i = 0;
for (x = start.a; x < xend && i < width; x += inc) {
color = this.pixelValueFunc(z, new Complex(x, y), nlimit);
imageData.data[c++] = color.r;
imageData.data[c++] = color.g;
imageData.data[c++] = color.b;
imageData.data[c++] = color.a;
// alpha
i++;
}
j++;
}
context.putImageData(imageData, 0, 0);
processingTime = new Date().getTime() - startTime;
context.fillStyle = '#fff';
context.font = '10px courier';
context.textAlign = 'left';
var line = 0;
var heightDelta = 12;
var xstart = 10;
if (options.display.processingTime) {
context.fillText("Processing time: " + processingTime + "ms", xstart,
line += heightDelta);
}
if (options.display.parameters) {
context.fillText("Limit: " + nlimit + "", xstart, line += heightDelta);
context.fillText("Start: " + start.toString() + "", xstart, line += heightDelta);
context.fillText("Constant: " + z.toString() + "", xstart, line += heightDelta);
context.fillText("Max Magnitude: " + rmax + "", xstart, line += heightDelta);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment