{Jozef Sivek ml. 2.november 2004 az 19.december 2004
program integrujuci generovanie Mandelbrotovej mnoziny ako aj Juliovych mnozin
ide vlastne o procedury, ktore sa hodia implementovat do inych programov
}
program fract;
uses crt, graph;

type pole_v=array[1..2] of real;{klasicky vektorovy priestor}
type pole_v_int=array[1..2] of integer;{-//- pre cele cisla}

var g_position,g_size:pole_v;{ohranicenie mnoziny}
    position,size:pole_v_int;{ohranicenie okna}
    g_color_m,g_color_start,g_color_no:word;{color management}
    which:boolean;{ktora mnozina 0 je m  a 1 je j}
    input,exp:integer;
    gd,gm:integer;
    lim:word;
    c_j:pole_v;{c pre juliu}

procedure init_g;
          begin
          gd:=detect;
          initgraph(gd,gm,'c:/bp/bgi');
          if graphresult <> grok then halt(1);
          {koniec inicializacie}
          end;

procedure close_g;
          begin
          Closegraph;
          end;

procedure draw(x,y:integer; color:word);{tato procedura posluzi hl. tym co tento program budu "objektovat"}
          begin
          {max hodnota color je vlastne lim!}

          if color>=lim then putpixel(x,y,g_color_m)
                        else putpixel(x,y,g_color_start + color mod g_color_no);

          end;

{umocnenie komplexneho cisla}
procedure umocni(var input:pole_v; exp:integer; var overflow:boolean);
          var c,cx:pole_v;
              I:integer;
          begin
          {a+bi * c+di =
               (ac - bd) + (ad + bc)i}
          c[1]:=1;
          c[2]:=0;
          for I:=1 to exp do begin
                          cx[1]:=c[1]*input[1] - c[2]*input[2];
                          c[2]:=c[1]*input[2] + c[2]*input[1];
                          c[1]:=cx[1];
                          if (sqr(c[1]) + sqr(c[2])) > 50   then begin
                                                                 overflow:=true;
                                                                 exit;
                                                                 end;
                             end;
          input[1]:=c[1];
          input[2]:=c[2];
          end;


procedure generate(position, size: pole_v_int);{vygenerovanie mnoziny}

         var poc:word;{vnorenie}
             x,y:integer;{poloha na obrazovke}
             z,c_m:pole_v;
             c:pole_v;{zjednoteny prameter, dufam, ze to bude rychlejsie}
             overflow:boolean;{kontrola mozneho pretecenia}
         begin
         exp:=abs(exp);
         size[1]:=abs(size[1])-1;{to -1 pretoze sa pocita od 0}
         size[2]:=abs(size[2])-1;{pre nezbednych nechcem si predstavovat co by to robilo pri R-}

         {taka pmuocka, v podstate ju netreba}
         setcolor(red);
         line(position[1],position[2]+size[2] div 2,position[1]+size[1],position[2]+size[2] div 2);

         {kedze juliova mnozina ma c_j ako konstantu}
                if which=true then begin
                                c[1]:=c_j[1];
                                c[2]:=c_j[2];
                                end;


          for x:=0 to size[1] do begin
          for y:=0 to size[2] do begin

                   overflow:=false;

                   if which=false then begin
                                   z[1]:=0;z[2]:=0;{vychodzi parameter}
                                   c[1]:=g_position[1] + (x/size[1]) * g_size[1];{realne koordinaty  daneho bodu}
                                   c[2]:=g_position[2] - (y/size[2]) * g_size[2];
                                   {ak by sme chceli zachovat pomery mierky tak:
                                   c[2]:=g_position[2] - (y/size[2]) * (size[2]/size[1]) * g_size[1];
                                   }

                                   {takto to bolo
                                   c_m[1]:=(x-(getmaxX / 2))/(getmaxx div 4);
                                   c_m[2]:=(y-(getmaxY / 2))/(getmaxx div 4);

                                   a zas pre juliu
                                   z[1]:=(x-(getmaxX / 2))/(getmaxY div 4);
                                   z[2]:=(y-(getmaxY / 2))/(getmaxY div 4);
                                   }
                                   end;
                   if which=true then begin
                                   z[1]:=g_position[1] + (x/size[1]) * g_size[1];{nachadzanie realnych koordinatov pre bod}
                                   z[2]:=g_position[2] - (y/size[2]) * g_size[2];
                                   {c je vychodzi parameter pre generovanie mnoziny
                                   a definuje sa externe}
                                   end;

               {boogie woogie, alebo ide sa na skumat vlastnost bodu}

               poc:=0;
               repeat
               umocni(z,exp,overflow);
               z[1]:=z[1]+c[1];
               z[2]:=z[2]+c[2];
               inc(poc);
               until (poc >= lim) or overflow or ( ( sqr(z[1]) + sqr(z[2]) ) > 4);

               {nakoniec nakreslime bod}
               draw(position[1]+x,position[2]+y,poc);

          end;end;


         end;

var I,M,x,y:integer;



begin
write('= Fract');
writeln('od Jozef Sivek (c)2004':50);
writeln('press Enter to begin and then to close!');
readln;
init_g;
       {
       example1

       zakladne parametre generovania mnozin, s tymi si robte podla vuole
        ja to realne ohranicenie Gausovej roviny ktora sa bude skenovat
        g_position[1]:=-2;
        g_position[2]:=0.2;
        g_size[1]:=3;
        g_size[2]:=0.4;

       which:=false;0=m 1=j
       lim:=150;miera presnosti, uz pri 30 - 50 je to slusne, pri 1000
              si muozte odskocit na caj alebo sa Vam zavari pocitac ;-)
       exp:=2;

       julia
              c_j[1]:=-1.5;
              c_j[2]:=0.00000;

       parametre okna, odosielaju sa procedure generate
       position[1]:=0;
       position[2]:=0;
       size[1]:=639;
       size[2]:=79;

       color management
       g_color_m:=0;
       g_color_start:=10;
       g_color_no:=; pocet farieb
       }

{example 2}
randomize;

size[1]:=50;
size[2]:=50;

g_position[1]:=-2;
g_position[2]:=2.2;
g_size[1]:=4.5;
g_size[2]:=4.5;
     which:=true;
     lim:=50;
     exp:=2;
g_color_m:=0;
g_color_start:=15;
g_color_no:=16;

for I:=0 to 12 do begin
for M:=0 to 9 do begin
       position[1]:=I*50;
       position[2]:=M*50;

       c_j[1]:=((I*50)/getmaxx) * g_size[1] + g_position[1];
       c_j[2]:=((M*50)/getmaxy) * g_size[2] - g_position[2];
       g_color_start:=round(random*15);

       generate(position,size);

end;end;

{example 3

size[1]:=50;
size[2]:=480;


g_position[2]:=1.5;
position[2]:=0;
g_size[1]:=0.3;
g_size[2]:=2.7;
     which:=false;
     lim:=100;
     exp:=2;
g_color_m:=0;

randomize;

for I:=0 to 12 do begin

       position[1]:=I*50;
       g_position[1]:=-2 + ((I*53)/getmaxx) * g_size[1]*12;

       g_color_start:=round(random*16);
       g_color_no:=round(random*5+1);

       generate(position,size);

end;}

   readln;
close_g;
end.

