Atraktor Henona 2
Janusz Sobieraj - 28 LO

Atraktor 2

Najbardziej znany atraktor Henona. Każda wyszukiwarka internetowa zawsze go znajduje.
Określony wzorem (układ Henona)
xn+1=yn+1-a·(yn)2
yn+1=b·xn

Aplet obok pozwala ci obserwować wybrane fragmenty figury w powiększeniu. Punkt wskazany myszą znajdzie się w środu apletu, zaś atraktor zostanie 2 x powiększony.
Dopiero powiększona pozwala poznać swoje piękno, kolejne powiększenia tego dziwnego atraktora pokazują nam dopiero jego złożoność - składa się on z nieskończenie wielu parabolopodobnych warstw !

Wybierzmy współczynniki np a i b a=1.4 i b=0.3 (to najczęściej wybierana para) oraz współrzędne punktu "startowego". Ja wybrałem (-0.7,0.4).Wielokrotnie zastosuję przekształcenie : (x,y)=(y+1-a·y2 , b·x)
Rysunek "standardowy" jest bardzo skromny (u nas kolor niebieski).
Otrzymana figura mieści się w prostokącie x:<-1.3 ; 1.3> oraz y:<-0.4 ; 0.4>

pkt2d P(pkt2d p) 
{double xp; 
  xp=p.x; 
  p.x=p.y+1-a*xp*xp; 
  p.y=b*xp; 
  return(p); 
} 
//--------------------------------------- 
void rysuj(Graphics g) 
{ 
  pkt2d w=new pkt2d(-0.7,0.4); 
  double pom,a=1.4,b=0.3; 

  g.setColor(Color.blue) 
  for(int i=0;i<50000;i++) 
  { 
    w=P(w); 
    lo28.punkt(g,w); 
  } 
}
Oto pierwsza wersja procedury rysującej, wg której uzyskałem "niebieski" atraktor.
Pomysł na prezentację atraktora jest więc oczywisty - należy go powiększyć, tak by lepiej zobaczyć jego kształt i budowę. I tak pierwszy "powiększony" obraz to nasz atraktor w świecie x:<-1.3 ; 1.3> oraz y:<-0.4 ; 0.4>
Zastosuję jednokładność o skali k i środku (s.x,s.y)
Jsk[(x,y)]=(k(x-s.x),k(y-s.y))
Wprowadzę oznaczenia oraz obliczę potrzebną skalę jednokładności.
x_min=-1.3;x_max=1.3;
y_min=-0.4;y_max=0.4;

dl=x_max-x_min; sz=y_max-y_min;
kx=2.0*lo28.max_x()/dl;
ky=2.0*lo28.max_y()/sz;

Teraz rysowanie punktu realizujemy stosując powyższy wzór na jednokładność :
r.x=kx*(w.x-s.x);
r.y=ky*(w.y-s.y)
lo28.punkt(g,r);
Wskazany myszą punkt staje się środkiem apletu, powiększamy rysunek 2-krotnie, a to za sprawą następującego kodu;
public boolean handleEvent(Event zd) 
{ 
  if(zd.id==Event.MOUSE_DOWN) 
  { 
    s.x=x_min+dl*((double)(zd.x)/(2.0*lo28.sx)); 
    s.y=y_max-sz*((double)(zd.y)/(2.0*lo28.sy)); 
    dl/=2; 
    sz/=2; 
    x_min=s.x-dl/2; 
    x_max=s.x+dl/2; 
    y_min=s.y-sz/2; 
    y_max=s.y+sz/2; 
    kx=2.0*lo28.max_x( )/dl; 
    ky=2.0*lo28.max_y( )/sz; 
    repaint(); 
  } 
  return true; 
}

Pozostaje tylko uprzedzić, że po kolejnych powiększeniach punkty atraktora pojawiają się wolniej. Kolejne obszary są mniejsze i po prostu mniej punktów tam trafia.