Conjunto de Mandelbrot

Dejo un pequeña “piece of code” de hace un par de años para generar el conjunto de Mandelbrot en un canvas con Javascript. Quería tener una imagen muy grande del conjunto con tonos azules, así que decidí generarla de la forma más rápida posible: un canvas y unas pocas líneas de código.

Fue una mala idea, descubrí entonces que la mayoría de navegadores soportan como máximo una dimensión en píxeles de 8192×8192 para el canvas; así que la imagen se limitaría como mucho a ese tamaño.

mandelbrot_thumb

Descargar imagen final en tamaño completo

En cualquier caso… desde aquí podéis ejecutar el script; y el código (hecho ad hoc para generar la imagen y nada más):

var width=7500;
var height=width*0.88;
var canvas=document.getElementById("canvas");
var control=document.getElementById("control");
canvas.width=width;
canvas.height=height;
var context=canvas.getContext("2d");
var minAbsRe=-2.00;
var maxAbsRe=+0.80;
var minAbsIm=-1.25;
var maxAbsIm=+1.25;
var zoom=1;
var y=0;
function draw()
{
   var minRe=minAbsRe*zoom;
   var maxRe=maxAbsRe*zoom;
   var minIm=minAbsIm*zoom;
   var maxIm=maxAbsIm*zoom;
   var reFactor=(maxRe-minRe)/(width-1);
   var imFactor=(maxIm-minIm)/(height-1);
   var maxIterations = 30;
   var c_im=maxIm-y*imFactor;
   for(var x=0;x<width;++x)
   {
      var c_re=minRe+x*reFactor;
      var zRe=c_re, zIm=c_im;
      var isInside=true;
      for(var n=0;n<maxIterations;++n)
      {
         var zRe2=zRe*zRe,zIm2=zIm*zIm;
         if(zRe2+zIm2>4)
         {
            isInside=false;
            if(n<maxIterations/2)
               context.fillStyle="rgb(0,0,"+(n*255/(maxIterations/2))+")";
            else
            {
               var a=Math.round((n-(maxIterations*0.5))*255/(maxIterations/2));
               var b=Math.round(a*Math.pow(n/maxIterations,3));
               context.fillStyle ="rgb("+b+","+a+",255)";
            }
            context.fillRect(x,y,1,1);
            break;
         }
         zIm=2*zRe*zIm+c_im;
         zRe=zRe2-zIm2+c_re;
      }
      if(isInside)
      {
         context.fillStyle="#000";
         context.fillRect(x,y,1,1);
      }
   }
   if(y<height)
   {
      var progress=(y*100/height);
      control.innerHTML=progress.toFixed(2)+"%";
      y++;
      setTimeout(draw,25);
   }
   else
   {
      var img=canvas.toDataURL("image/png");
      control.innerHTML='<img src="'+img+'"/>';
   }
}

Si te gusta esta entrada... compártela! 😉
Tweet about this on TwitterShare on Facebook0Share on Google+0Share on Tumblr0Pin on Pinterest0Share on LinkedIn0Share on Reddit0

Responder

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Límite de tiempo se agote. Por favor, recargar el CAPTCHA por favor.