Advertisement
Grafundzijus

Mandelbrot fractal

Nov 4th, 2021
1,012
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 5.67 KB | None | 0 0
  1.  FOR EACH pixel:
  2.          REPEAT
  3.            CALCULATE Z(n)=Z(n-1)^2+C
  4.            iterations=iterations+1
  5.          UNTIL value=infinite OR iterations>max_iterations
  6.          SET COLOR=ITERATIONS
  7.  
  8.     (T.y., su kiekvienu ekrano tašku atliekame procesą Z(n)=(Z(n-1))2+C, kurį aptarėme puslapyje Mandelbroto aibė, iki tol, kol nustatysime, kad Z(n) tolsta į begalybę arba kol procesą pakartosime tam tikrą skaičių, kurį pažymėjome max_iterations. Tada taško spalva bus tokia, kurios numeris atitinka proceso pakartojimų (iteracijų) skaičių).
  9.     Kaip minėta, Z(n)=(Z(n-1)) 2+C ir .Tai reiškia:
  10. Z(1)=C
  11.        Z(2)=C2+C
  12.                             Z(3)=(C2+C)2+C    ir t.t.
  13.     Kaip žinia C=a+ib. Tuomet skaičiuosime pagal formules:
  14.             Re Z(n)=(Re Z(n-1)) 2 -(Im Z(n-1)) 2 +Re C
  15.             Im Z(n)=2* Re Z(n-1)* Im Z(n-1)+Im C
  16.     (Tai iš formulių (x+iy)2+a+ib=(x2-y2+a)+(2xy+b)i, kur Z(n-1)=x+iy).
  17.     Dabar turime nustatyti, kada Z(n) tolsta į begalybę.
  18.     Z(n) reiškia vektorių, išvestą iš koordinačių pradžios ir turintį koordinates {Re Z(n), Im Z(n)}. Tuomet, mes galime rasti jo ilgį (ILGIS=kvadratinė šaknis iš (Re Z(n)) 2+(Im Z(n)) 2).
  19.     Taigi, kada ilgis begalinis? Bloga žinia: Jūs negalite patikrinti, ar jis begalinis. Gera žinia: jeigu tik kada ilgis viršys 2, tai jis tikrai taps (kurią tai dieną) begaliniu.
  20.     Patikslinsime programą:
  21.         FOR EACH pixel:
  22.              REPEAT
  23.                 CALCULATE Z(n)=Z(n-1)^2+C
  24.                 Length=(Re Z(n)) ^2 +(Im Z(n)) ^2
  25.                 iterations=iterations+1
  26.              UNTIL Length>4 OR iterations>max_iterations
  27.         SET COLOR=ITERATIONS
  28.  
  29.     Pastebėkite, kad skaičiavome, ar ilgis viršija 4, o ne 2, ir kad skaičiuodami ilgį netraukėme šaknies.
  30.     Turėtumėte žinoti, kad šaknies traukimas užima daug laiko, tad kodėl gi negalime skaičiuoti 'Length'>4, kai SQRT(Length) >2 ?!?
  31.     Kad būtų patogiau, parašykime funkciją, kur C yra jos kintamasis, o iteracijų skaičius yra jos reikšmė.
  32.  
  33.     FUNCTION CALC_PIXEL(CA,CBi: REAL): INTEGER;
  34.     CONST MAX_ITERATION=128;
  35.     VAR
  36.         OLD_A:REAL                     {pagalbinis kintamasis 'a' reikšmei saugoti}
  37.         ITERATION:INTEGER      {skaičiuoja iteracijas}
  38.         A,B:REAL                           {z realioji ir menamoji dalys}
  39.         LENGTH_Z:REAL              {z ilgis kvadratu}
  40.     BEGIN
  41.         A:=0; B:=0;                         {Z(0):=0
  42.         ITERATION:=0;
  43.         REPEAT
  44.             OLD_A:=A;
  45.             A:=A*A-B*B+CA;
  46.             B:=2*OLD_A*B+CBi;
  47.             length_z:=a*a+b*b;          {netraukėme šaknies !}
  48.         UNTIL (length_z>4) OR (iteration>max_iteration);
  49.         Calc_Pixel:=iteration;
  50.     END;
  51.  
  52.     Mandelbroto aibės radimui jums reikės tokios programos:
  53.  
  54.     FOR y:=-1.25 to 1.25 DO
  55.           FOR x:=2 to 1.25 DO
  56.          color:=CALC_PIXEL(x,y);
  57.  
  58. Bet jūs dar negalite aibės pavaizduoti ekrane. Prisiminę apie ekrano koordinates (mūsų atveju naudojamės 640*480VGA):
  59.  
  60.   FOR y:=0 to 480-1 DO
  61.    FOR x:=0 to 640-1 DO
  62.     BEGIN
  63.        color:=CALC_PIXEL(Re(x),Im(y));
  64.        PUTPIXEL(X,Y, color);
  65.     END;
  66.  
  67.     Ši programa jau gali pavaizduoti Mandelbroto aibę ekrane, bet dar reikia apibrėžti, kaip skaičiuoti realią ir menamą kiekvieno taško dalį.
  68.     Kad gauti visą Mandelbroto aibę, x turi kisti nuo -2 iki 1.25, o y nuo -1.25 iki1.25. Šiuos rėžius aprašysime konstantų dalyje:
  69.  
  70.  PROGRAM Mandelbrot;
  71.  CONST MinX=-2;
  72.     MaxX=1.25;
  73.     MinX=-1.25;
  74.     MaxX=1.25;
  75.    [likusi programos dalis...]
  76.  
  77.     Jei viršutinis kairysis kampas (MinX, MinY), o dešinysis apatinis (MaxX, MaxY), gausime tokias formules:
  78.           Re=MinX+x*(MaxX-MinX)/screenwidth;
  79.           Im=MinY+y*(MaxY-MinY)/screenheight;
  80. arba, kad išvengtume dažno dalijimo (kas užimtu daugiau laiko):
  81.           dx= MaxX-MinX)/screenwidth;
  82.           dy=(MaxY-MinY)/screenheight;
  83.           Re=MinX+x*dx;
  84.           Im=MinY+y*dy;
  85.  
  86.     Gavome beveik baigtą programą:
  87.  
  88.  PROGRAM Mandelbrot;
  89.   CONST MinX=-2;
  90.               MaxX=1.25;
  91.               MinX=-1.25;
  92.               MaxX=1.25;
  93.   VAR dx,dy : REAL;
  94.            x,y : INTEGER;
  95.  BEGIN
  96.      dx= MaxX-MinX)/640;
  97.      dy=(MaxY-MinY)/480;
  98.      FOR y:=0 to 480-1 DO
  99.      FOR x:=0 to 640-1 DO
  100.          BEGIN
  101.           color:=CALC_PIXEL(MinX+x*dx, MinY+y*dy);
  102.           PUTPIXEL(X,Y, color);
  103.         END;
  104.  END.
  105.  
  106.     Galų gale, mūsų programa atrodo taip:
  107.  
  108. program Mandelbrot;
  109. USES Crt, Graph;
  110. Const MinX=-2;
  111.          MaxX=1.25;
  112.          MinY=-1.25;
  113.          MaxY=1.25;
  114. var dx,dy:real;
  115.     x,y:integer;
  116.     color:integer;
  117.     screen_x,screen_y:integer;
  118.     grDriver:integer;
  119.     grMode:integer;
  120.     ErrCode:integer;
  121.  
  122. Function calc_pixel(CA,CB:real):integer;
  123. const max_iteration=64;
  124. var
  125.    old_a:real;
  126.    iteration:integer;
  127.    a,b:real;
  128.    length_z:real;
  129. begin
  130.     a:=0;b:=0;
  131.     iteration:=0;
  132.     repeat
  133.          old_a:=a;
  134.          a:=a*a-b*b+ca;
  135.          b:=2*old_a*b+cb;
  136.          iteration:=iteration+1;
  137.          length_z:=a*a+b*b;
  138.      until (length_z>4) or (iteration>max_iteration);
  139.      Calc_Pixel:=iteration;
  140. End;
  141.  
  142. Begin
  143.     grdriver:=Detect;
  144.     InitGraph(grDriver,grMode,'c:\mokymas\tp\bgi\');
  145.     ErrCode:=GraphResult;
  146.     if ErrCode<>grOk then
  147.       begin
  148.         writeln('could not');
  149.         Writeln('do you have correct..??');
  150.         halt;
  151.       end;
  152.     screen_x:=getmaxx;
  153.     screen_y:=getmaxy;
  154.     dx:=(MaxX-MinX)/screen_x;
  155.     dy:=(MaxY-MinY)/screen_y;
  156.     for y:=0 to screen_y-1 do
  157.       for x:=0 to screen_x-1 do
  158.          begin
  159.           color:=calc_pixel(MinX+x*dx,MinY+y*dy);
  160.           putpixel(x,y,color);
  161.         end;
  162.      repeat until keypressed;
  163. End.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement