Html 5 Canvas绘制分形图Mandelbrot
2011-05-26 22:46
141 查看
为了测试一下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.
// 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.offsetX || (evt.clientX - canvas.offsetLeft);
var y0 = evt.offsetY || (evt.clientY - canvas.offsetTop);
var x1, y1, w, h;
var imgd = context.getImageData(0, 0, width, height);
update(evt);
function update(evt) {
x1 = evt.offsetX || (evt.clientX - canvas.offsetLeft);
y1 = evt.offsetY || (evt.clientY - 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 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); }
}
}
}
// ]]>
更为专业的Mandelbrot请check这里 http://www.atopon.org/mandel/
Your browser does not support the canvas element.
// 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.offsetX || (evt.clientX - canvas.offsetLeft);
var y0 = evt.offsetY || (evt.clientY - canvas.offsetTop);
var x1, y1, w, h;
var imgd = context.getImageData(0, 0, width, height);
update(evt);
function update(evt) {
x1 = evt.offsetX || (evt.clientX - canvas.offsetLeft);
y1 = evt.offsetY || (evt.clientY - 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 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); }
}
}
}
// ]]>
<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>
相关文章推荐
- HTML 5 Canvas通过 JavaScript 来绘制
- 【HTML】Canvas(1)-绘制图形
- IText&Html2canvas js截图 绘制 导出PDF
- HTML5 Canvas ( 线段的绘制 ) beginPath, moveTo, strokeStyle, stroke
- HTML canvas 绘制
- html 5 canvas 绘制太极demo
- HTML Canvas 绘制五角星
- HTML canvas绘制椭圆
- 【HTML】Canvas(2)-绘制文本
- 分别利用html+js和canvas绘制时钟
- HTML5 Canvas ( 填充图形的绘制 ) closePath, fillStyle, fill
- HTML5 Canvas ( 矩形的绘制 ) rect, strokeRect, fillRect
- 【HTML】Canvas(3)-绘制图片
- 利用Html 5的canvas标签绘制水流和水池动画
- 千呼万唤 HTML 5 (8) - 画布(canvas)之绘制图形
- [转]HTML5多点触摸演示源码(Canvas绘制演示)
- HTML5 -canvas拖拽、移动 绘制图片可操作移动,拖动
- 千呼万唤 HTML 5 (8) - 画布(canvas)之绘制图形
- 如何学习html画布呢(canvas)