{
Jozef Sivek ml. 2. jun 2004
program na generovanie juliovych mnozin
}
program madelbrotove_mnoziny;
uses crt,graph;

type pole_v=array[1..2] of real;

var a,b,c:pole_v;
    input,exp:integer;
    gd,gm:integer;
    lim:integer;

{testovanie pre okienko}
function ok(x,y:integer):boolean;
         begin
         if (x>=a[1]) and (x<=a[2]) then if (y>=b[1]) and (y<=b[2]) then begin ok:=false; exit; end;
         ok:=true;
         end;

{napisanie exponentu na obrazovku}
procedure write_onscreen(input_c:pole_v; input_exp:integer; color:byte);
          var ch,ch2:string;
          begin
          setcolor(color);
          ch:='c| ';
          str(input_c[1]:1:12,ch2);
          ch:=ch+ch2+' ';
          str(input_c[2]:1:12,ch2);
          ch:=ch+ch2+'i ; e';
          str(input_exp:2,ch2);
          ch:=ch+ch2;
          outtextxy(0,470,ch);
          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])) > 1000 then begin
                                                                 overflow:=true;
                                                                 exit;
                                                                 end;
                             end;
          input[1]:=c[1];
          input[2]:=c[2];
          end;

{generovanie mnoziny s exp v rovnici}
procedure generate(c:pole_v; exp:integer);
          var poc:integer;
              x,y:integer;
              z,zx:pole_v;
              overflow:boolean;
          begin
          exp:=abs(exp);
          write_onscreen(c,exp,15);

          for x:=0 to getmaxX do begin
          for y:=0 to getmaxY do begin
          poc:=0;
          if ok(x,y) then begin
           overflow:=false;
           z[1]:=(x-(getmaxX / 2))/(getmaxY div 4);
           z[2]:=(y-(getmaxY / 2))/(getmaxY div 4);
           repeat
            umocni(z,exp,overflow);
            z[1]:=z[1]+c[1];
            z[2]:=z[2]+c[2];
            inc(poc);
           until (poc >= lim) or ( ( sqr(z[1]) + sqr(z[2]) ) > 4) or overflow;
           if poc>=lim then putpixel(x,y,0)
                       else putpixel(x,y,poc);
                            end;
                                 end;
                                 end;
          write_onscreen(c,exp,0);
          end;

{slideshow}
procedure preview;
          var c:pole_v;
          begin
           repeat
           c[1]:=random*4-2;
           c[2]:=random*4-2;
           generate(c,exp);
           until keypressed;
          end;

begin
randomize;{spustam generator}
a[1]:=0;
a[2]:=340;
b[1]:=470;
b[2]:=479;

write('= Juliove mnoziny');
writeln('od Jozef Sivek (c)2004':50);
writeln('mas komplexnu rovnicu z = z0^exp + c , pre z0 = d z roviny');
writeln('ak chces zadat cislo c napis cislo;... alebo [0] pre slideshow');
readln(input);
if input<>0 then begin
                 write('c[1]= ');
                 readln(c[1]);
                 write('c[2]= i*( ');
                 readln(c[2]);
                 end;
writeln('zadaj exp v rovnici ako exponent');
readln(exp);
writeln('chces zmenit pocet opakovani cyklu? Ak ano zadaj, pre [0] je lim implicitne 30.');
readln(lim);
if lim=0 then lim:=30;

{}
gd:=detect;
initgraph(gd,gm,'c:/bp/bgi');
if graphresult <> grok then halt(1);
{koniec inicializacie}

case input of
0:preview;
else begin
     generate(c,exp);
     repeat until keypressed;
     end;
end;

Closegraph;

end.
