Zbiór Mandelbrota

Z wikipedii :
Zbiór Mandelbrota (żuk Mandelbrota, żuczek Mandelbrota) - podzbiór płaszczyzny zespolonej, którego brzeg jest jednym ze sławniejszych fraktali. Nazwa tego obiektu została wprowadzona dla uhonorowania jego odkrywcy, francuskiego matematyka Benoit Mandelbrota.
Zbiór tworzą te punkty p dla których ciąg opisany równaniem rekurencyjnym:
(*)z0=0 , zn+1=(zn)2+p nie dąży do nieskończoności

Myszą powiększysz 2-krotnie aktualny zbiór- kliknięcie myszy wyznacza nowy punkt centralny

Benoit Mandelbrot urodził się w Polsce w 1924, studiował w Paryżu.
Na początku lat 80-tych iterując na komputerze proste wielomiany (kwadratowe) otrzymał na ekranie zbiór, którego zdjęcia obiegły dosłownie cały świat.

Interpretacja wzoru (*) podobna jak dla zbioru Julii.
Najistotniejsza część fraktala mieści się w kwadracie x : <-2 , 1> , y : <-1.5 , 1.5>.
Dla wygody aplet będzie też kwadratem (u nas 350x350 piksli).
Na początku rysujemy dla :
xmin=-2 do xmax=1
ymin=-1.5 do ymax=1.5
środek wykresu w s=(-1 , -1.5)
zaś dl=sz=3 (dl,sz gdy obszar prostokątny)

W naszym przykładzie wskazany myszą (przez kliknięcie) punkt staje się nowym środkiem rysunku, jego współrzędne obliczamy :
s.war(x_min+dl/2 , y_min+sz/2);
a więc dla nowego s=(s.x, s.y), mamy nowe parametry obszaru :
dl=dl/2; sz=sz/2;
xmin=s.x-dl/2; xmax=s.x+dl/2;
ymin=s.y-sz/2; ymax=s.y+sz/2;
"Nowy" obszar umieszczamy znowu na naszym aplecie, tak by zajął całą płaszczyznę. Aby uzyskać ten efekt wykonamy złożenie jednokładności z przesunięciem równoległym : JkTs .

Obliczmy więc potrzebną skalę powiększenia oraz dokładność rysunku :
void skaluj( ) 
{ 
  kx=2.0*lo28.max_x( )/dl; 
  ky=2.0*lo28.max_y( )/sz; 
  dx=dl/(2.1*lo28.sx); 
  dy=sz/(2.1*lo28.sy); 
}

(lo28.sx , lo28.sy) to środek apletu (w pikslach),
zaś lo28.max_x(), lo28.max_y(), największe liczby rzeczywiste odpowiednio osi OX i OY kartezjańskiego układu współrzędnych, w którym to wszystko jest rysowane.





Na koniec wreszczie komplet: procedura rysująca i funkcja ustalająca kolor:
void rysuj(Graphics g) 
{
  pkt2d p=new pkt2d(0,0); 
  pkt2d w=new pkt2d(0,0); 
  Color kolor; 

  for(p.x=x_min;p.x<x_max;p.x+=dx) 
   for(p.y=y_min;p.y<y_max;p.y+=dy) 
    {
      kolor=JakiKolor(p); 
      w.war(kx*(p.x-s.x),ky*(p.y-s.y));	
      lo28.punkt(g,w,kolor);
    }
}
Color JakiKolor(pkt2d a) 
{ 
  int il_it=50; 
  float r,g,b; 
  double x1,x,y,inf=3.0; 
  int i=0; 

  x=y=0; 
  while(x*x+y*y< inf && i< il_it) 
  { 
    i++; 
    x1=x*x-y*y+a.x; 
    y=2*x*y+a.y; 
    x=x1; 
  } 
  r=(float)Math.sin(1.5*Math.PI * i / il_it);
     if( r < 0)r = 0; 
  g=(float)Math.sin(1.5*Math.PI * i / il_it);
     if( g < 0) g = 0; 
  b=(float)Math.sin(0.8*Math.PI * i / il_it);
     if( b < 0) b = 0; 
  return(new Color(r,g,b)); 
}

Zobacz jeszcze na koniec wersję C++Builder