Фракталы-применение canvas

Рисование фрактальных картинок на основе canvas

Фрактальные картинки можно рисовать с помощью более изящного кода, чем тот, который формирует строку тегов <div>. Для этого следует воспользоваться объектом canvas, предназначенным для работы с графикой (примеры).

Здесь я привожу код реализации фрактальной картинки:

Опробовать работу программы рисования фрактальной картинки на основе <canvas>

JavaScript-код с использование canvas

/* Пример вызова: */
function init(){
  myfr=new fractal();
  myfr.x0=-1;
  myfr.xk=1;
  myfr.lmax=100;
  myfr.kmax=30;
  myfr.a=new Array(1,0.5);
  myfr.b=new Array(0.5,0.5);
  myfr.get(); // рисуем фрактал
}
function fractal(x0,y0,xk,yk,dx,kmax,lmax,a,b,mode){ // конструктор

/* Описание:
   Данный объект рисует фрактальную картинку в элементе canvas,
   вычисленную по простой формуле.
   В прямоугольнике с координатами углов (x0,y0) и (xk,yk)
   тестируются все точки через интервал dx путем итерационного преобразования:
     z(i+1)=F(z(i)),
     где z - комплексное число вида x+yi;
         F() -функция преобразования комплексного числа в другое комплексное число.
   Если на какой-то итерации точка выйдет за круг радиуса lmax с центром
   в начальной точке или же количество итераций превысит kmax, исходная точка
   окрашивается в цвет, зависящий от номера итерации.
   Собственно формула преобразования задается кодом функции next(), а исследование судьбы точки
   при итерационном преобразовании — кодом функции explore().
   
   Параметры (свойства):
   x0,y0 - начальное число (вещественная и мнимая части комплексного числа)
   xk,yk - конечное число (вещественная и мнимая части комплексного числа)
   dx - приращение числа в итерации при вычислении функции F()
   kmax - максимальное количество итераций (ограничение)
   lmax - радиус круга с центром в начальной точке (при выхде из него итерации прекращаются)
   mode - задает формулу преобразования координат точек, т.е. функцию z(i+1)=F(z(i)):
   если не указан, то z(i+1)=a*z(i)*z(i)+b (a,b — некоторые комплексные числа);
   в противном случае z(i+1) определяется несколько иначе (см. функцию next()).
   В исходном варианте функция преобразования имеет вид z(i+1)=a*z(i)*z(i)+b.
   
   Метод get() возвращает строку тегов,описывающих фрактальную картинку;
   Свойство resume содержит строку отчета о работе; 
   
*/
/* Параметры: */
/* Примеры значений, которые вы можете изменить: */
this.x0=x0||-1.5;
this.y0=y0||-1.5;      
this.xk=xk||1.5;
this.yk=yk||1.5;
this.dx=dx||0.01;   // приращение чисел
this.kmax=kmax||100;// ограничение итераций
this.lmax=lmax||30; // радиус области
this.a=a;  // множитель a в формуле zi+1=a*F(zi)+b
this.b=b;  // слагаемое b в формуле zi+1=a*F(zi)+b
this.mode=mode||null;  // вид преобразования
this.resume="";
if (!a) this.a=new Array(1,0);
if (!b) this.b=new Array(0,0);

/* Метод, выводящий изображение в canvas: */
this.get=function() { 
  var  ctx = document.getElementById('canvas').getContext('2d');
  var time=new Date(); // хронометраж для отчета
  var t0=time.getTime();
  var x,y,n;
  var x0s=0;
  var y0s=0;
  var i=0;
  
for (y=this.y0;ythis.kmax) n=this.kmax;
    var color="000000"+toh(16715266-n*(16581891/this.kmax));
    ctx.fillStyle="#"+color.substr(color.length-6);//цвет заливки
    ctx.fillRect(x0s,y0s,1,1); // окрашиваем точку
    x0s++;
    i++;
  }
  y0s++;
}

  var time=new Date(); // хронометраж для отчета
  var t0=time.getTime()-t0;
/* Отчет: */
this.resume="Отчет\nТочек: "+i+"\nВремя: "+t0+"мс";

}

/*** Функции  ***********************************************/

function explore(x,y,kmax,lmax,a,b,mode){ /* исследует судьбу
                           точки; возвращает номер итерации */
var z,k,q,w;
z=new Array(x,y)
k=0;
while (true){
  z=next(z[0],z[1],a,b,mode);
  if (x==z[0]&&y==z[1]) return kmax; 
  k++;
  q=(x-z[0]);q=q*q;w=(y-z[1]);w=w*w;
  if ((q+w)>lmax*lmax)
    return k; // если вышли за пределы области 
  if (k>kmax) return kmax;// если количество итераций слишком велико 
}
}
/***************************************************/

function next(x,y,a,b, mode){  // возвращает координаты следующей точки
/* Возможны различные формулы вычисления */
if (mode){
  var x1=Math.sqrt(Math.abs(x*x-y*y));
  var y1=Math.sqrt(2*x*y);
}
if (!mode){ // Квадрат (по умолчанию)
  var x1=x*x-y*y;
  var y1=(2*x*y);
}
x=x1*a[0]-y1*a[1]+b[0];
y=y1*a[0]+x1*a[1]+b[1];
return new Array(x,y);
}
/***************************************************/
function toh(n){ // возвращает 16-е число, соответствующее 10-му числу n
n=Math.round(n);
var  hchars="0123456789abcdef"     /* строка, содержащая все
                                   шестнадцатеричные цифры */
  if (n<16) return hchars.charAt(n);
  var i=n%16;
  return toh((n-i)/16)+hchars.charAt(i) 
}
}
/*****************************************************************/