Html 5 Canvas绘制分形图Mandelbrot

为了测试一下js和Canvas的计算能力,做了一个Mandelbrot的分形图,支持鼠标Zoom In。Mandelbrot的定义很简单,虚数平面的每个点(x,y),通过反复计算zn+1 = zn2 + c,z0 = 0。只有结果收敛才属于Mandelbrot,否则根据n的设定一个颜色,越大越深,代表接近属于集合的点,可以把集合中的点理解为n=无穷大。推荐在chrome中打开本页,还支持firefox和ie9。 拖动鼠标可以明显发现chrome是最流畅的。

更为专业的Mandelbrot请check这里 http://www.atopon.org/mandel/

Your browser does not support the canvas element.


  
    
< canvas id = " canvas " width = " 600 " height = " 480 " style = " margin-left:100px " >
< p > Your browser does not support the canvas element. < / p>
< / canvas>
< p >< input id = " reset " type = " button " value = " Reset " / >< / p >

< script >
var canvas = document.getElementById( ' canvas ' );
var context = canvas.getContext( ' 2d ' );
var width = canvas.width ,height = canvas.height;
var maxIterations = 100 ;
var minRe = - 2.0 ;
var maxRe = 1.0 ;
var minIm = - 1 ;
var maxIm = minIm + (maxRe - minRe) * height / width;

reset();

document.getElementById(
" reset " ).onclick = reset;

canvas.onmousedown
= function (evt) {
var x0 = evt.pageX - canvas.offsetLeft;
var y0 = evt.pageY - canvas.offsetTop;

var x1, y1, w, h;
var imgd = context.getImageData( 0 , 0 , width, height);

update(evt);

function update(evt) {
x1
= evt.pageX - canvas.offsetLeft;
y1
= evt.pageY - canvas.offsetTop;
w
= Math.abs(x1 - x0), h = Math.abs(y1 - y0);
}

function clear(evt) {
if (w && h) {
context.clearRect(
0 , 0 , width, height);
context.putImageData(imgd,
0 , 0 );
}
}

canvas.onmousemove
= function (evt) {
clear(evt);
update(evt);
context.strokeStyle
= " red " ;
context.strokeRect(x0
< x1 ? x0 : x1, y0 < y1 ? y0 : y1, w, h);
}

canvas.onmouseup
= function (evt) {
clear(evt);
canvas.onmousemove
= canvas.onmouseup = null ;

minRe
= minRe + (maxRe - minRe) / width * (x0 < x1 ? x0 : x1);
maxRe
= minRe + (maxRe - minRe) / width * w;
minIm
= minIm + (maxIm - minIm) / height * (y0 < y1 ? y0 : y1);
maxIm
= minIm + (maxIm - minIm) / height * h;

draw();
}
}

function reset() {
minRe
= - 2.0 ;
maxRe
= 1.0 ;
minIm
= - 1 ;
maxIm
= minIm + (maxRe - minRe) * height / width;
draw();
}

function draw() {
context.fillRect(
0 , 0 , width, height);
var imgd = context.getImageData( 0 , 0 , width, height)
var pix = imgd.data;

var drawPixel = function (x, y, itr) {
var i = (y * width + x) * 4 ;

pix[i]
= pix[i + 1 ] = pix[i + 2 ] = Math.round(itr * 255 / maxIterations);
}

mandelbrot(width, height, drawPixel);
context.putImageData(imgd,
0 , 0 );
}

function mandelbrot(imageWidth, imageHeight, drawPixel) {
var re_factor = (maxRe - minRe) / (imageWidth-1);
var im_factor = (maxIm - minIm) / (imageHeight-1);

for ( var y = 0 ; y < imageHeight; ++ y)
{
var c_im = maxIm - y * im_factor;
for ( var x = 0 ; x < imageWidth; ++ x)
{
var c_re = minRe + x * re_factor;

var z_re = c_re, z_im = c_im;
var isInside = true ;
var n = 0 ;
for (; n < maxIterations; ++ n)
{
var z_re2 = z_re * z_re, z_im2 = z_im * z_im;
if (z_re2 + z_im2 > 4 )
{
isInside
= false ;
break ;
}
z_im
= 2 * z_re * z_im + c_im;
z_re
= z_re2 - z_im2 + c_re;
}

if ( ! isInside) { drawPixel(x, y, n); }
}
}
}
< / script>

你可能感兴趣的:(canvas)