{ Ce petit bout de code est sous Copyright (c) Samuel Bizien - 2008 
Il est donnée *sans aucune garantie* sous licence GNU/GPL version 3 (ou suivante).
Vous pouvez retrouver le texte de cette licence sur internet :
 http://www.gnu.org/licenses/gpl.txt 
}

program calculer_dimension(input, output, sortie);
const maxiter	 = 200;
   k		 = 0.5;
   u0_r		 = 1.0;
   u0_i		 = 0.0;
   precision_min = 0.001;
   nb_mesures	 = 3;
   xbas		 = -2.9;
   xhaut	 = 1.1;
   ybas		 = -2.0;
   yhaut	 = 2.0;
var precision : real;
   i, j	      : integer;
   sortie     : text;

function est_dans_beryl(zre, zim, yre, yim: real):boolean;
var zretmp, zimtmp, yretmp, modz, mody : real;
   i				       : integer;
begin
   i:=0;
   repeat
      zretmp:=k*(zre+yre);
      zimtmp:=k*(zim+yim);
      yretmp:=zre*yre-zim*yim;
      yim:=zre*yim+zim*yre;
      zre:=zretmp;
      zim:=zimtmp;
      yre:=yretmp;
      modz:=zre*zre+zim*zim;
      mody:=yre*yre+yim*yim;
      i:=i+1;
   until (((modz < 1) and (mody < ((1/k)-1))) or ((modz > (2*k+1)*(2*k+1)) and (modz < (k/(k+1))*(k/(k+1))*mody)) or (i = maxiter));
   if ((modz >= (2*k+1)*(2*k+1)) and (modz <= (k/(k+1))*(k/(k+1))*mody)) then
      est_dans_beryl:=false
   else
      est_dans_beryl:=true;
end; { est_dans_beryl : indique si un point est à l'intérieur de l'ensemble ou non 
	Si vous souhaitez calculer la dimension d'un autre ensemble, c'est cette fonction qu'il faut modifier }

function compter_boites(pas, xmin, xmax, ymin, ymax : real) : integer;
var i, nb_boites	 : integer;
   etat_pt, etat_pt_prec : boolean;
   ligne		 : array[integer] of boolean; 
   x, y			 : real;
begin
   nb_boites := 0;
   x := xmin;
   y := ymin;
   i :=0;
   while x < xmax do
   begin
      ligne[i] := est_dans_beryl(u0_r, u0_i, x, y);
      i:=i+1;
      x:=x+pas;
   end;
   while y < ymax do
   begin
      y := y + pas;
      x := xmin;
      etat_pt_prec := est_dans_beryl(u0_r, u0_i, x, y);
      i := 1;
      while x < xmax do
      begin
	 x := x + pas;
	 etat_pt := est_dans_beryl(u0_r, u0_i, x, y);
	 if (not(etat_pt_prec and etat_pt and ligne[i-1] and ligne[i]) and (etat_pt_prec or etat_pt or ligne[i-1] or ligne[i])) then
	    nb_boites := nb_boites + 1;
	 ligne[i-1] := etat_pt_prec;
	 etat_pt_prec := etat_pt;
	 i := i+1;
      end;
      ligne[i-1] := etat_pt;
   end;
   compter_boites := nb_boites;
end; { compter_boites : compte le nombre de boites de largeur « pas » nécessaires pour recouvrir la frontière de Béryl }

begin
   precision := 1;
   assign(sortie, 'data-0.5-1-0');
   rewrite(sortie);
   while precision > precision_min do
   begin
      for j:=0 to nb_mesures-1 do
      begin
	 for i:= 0 to nb_mesures-1 do
	 begin
	    writeln('precision : ', precision, '; ', 3*j+i, '/', nb_mesures*nb_mesures);
	    writeln(sortie, 1/precision, ':', compter_boites(precision, xbas - i*precision/nb_mesures, xhaut, ybas - j*precision/nb_mesures, yhaut));
	 end;
      end;
      precision:=precision/2;
   end;
   close(sortie);
end.

