next up previous contents
Next: Bilag A. Up: Mønsterdannelse i simuleret videofeedback Previous: Appendix A.

Appendix B.

Simulation: Forstørrelse ved varierende vinkel og zoom.

Program ComputerFeedback; {Simulering af VideoFeedback}
{Programmeret april 1995 af Michael Cramer Andersen (og Jesper Petersen).}

Uses  DOS,Crt,BGI256,Pallette,Graph;

Const size = 21; {"Radius" i billedet. size=(bredde-1)/2}
      maxit= 20; {Max antal iterationer.}

type  t = -size .. size;

Type  Row_array = Array[t] of Byte;       {BilledMatrix}
      Row_Prt = ^Row_Array;
      Matrix = Array[t] of Row_Prt;

      Row_array_Tr = Array[t] of Real;    {Transformationsmatrix}
      Row_Prt_Tr = ^Row_Array_Tr;
      Matrix_Tr = Array[t] of Row_Prt_Tr;

Var   B1,B2,B3                : Matrix;   {De to billeder der skiftes imellem.}
      Tr_x, Tr_y              : Matrix_Tr;{Transformationskoordinater.}
      x,y                     : t;        {Koordinater for billedet.}
      Zoom, Beta              : Real;     {Kontrolparametre: zoom, kontrast.}
      Vinkel                  : Integer;  {Vinklen 'kameraet' er drejet.}
      CV, SV                  : Real;     {Cosinus og Sinus til given vinkel.}
      year,month,day,dow, p   : Word;     {Datoangivelse.}
      year_t,month_t,day_t,v_t: String;   {Datoudskrivning.}
      overskrift              : String;   {Overskrift.}
      px,py                   : Integer;  {Fordeling af billeder.}
      frame, v,z              : Integer;  {"Tællere" til fordeling af billeder.}

Procedure InitBilled;
{Initialiserer billederne B1, B2 og B3 samt Transformationerne Tr_x og Tr_y}
begin
   For y:=size downto -size do
   Begin New(B1[Y]); New(B2[Y]); New(B3[Y]); New(Tr_x[Y]); New(Tr_y[Y]); end;
   For y:=size downto -size do For x:=-size to size do
   Begin B1[x]^[y]:=0; B2[x]^[y]:=0; B3[x]^[y]:=0; Tr_x[x]^[y]:=0; Tr_y[x]^[y]:=0; end;
end;

Procedure Trigo(var Vinkel: Integer);
{Forudberegner trigonometriske funktioner af vinklen }
begin
  CV:=cos(Vinkel*pi/180);
  SV:=sin(Vinkel*pi/180);
end;

Procedure Transformation(var Zoom: Real; CV, SV: Real);
{For givet zoom og given vinkel (heltallig) udregnes
koordinater i gl. billede for hvert punkt i nye billede}
var Z: Real;
begin
   Z:=1/Zoom;
   For y:= size downto -size do
   For x:= -size to size do
   begin
      Tr_x[x]^[y]:=round((CV*x-SV*y)*Z);
      Tr_y[x]^[y]:=round((SV*x+CV*y)*Z);
   end;
end;

Procedure Sluk;
{Slukker for billedet.}
begin
  For y:=size downto -size do For x:=-size to size do
  begin B1[x]^[y]:=0; B2[x]^[y]:=0; B3[x]^[y]:=0; end;
end;

Procedure Flamme;
{Indsætter en lodret pinde/bjælke-lyskilde midt i billedet.}
begin
   For x:=-0 to 0 do For y:=-5 to 5 do {11 pixels h¢j og én bred.}
   begin
     B1[x]^[y]:=255;
     B2[x]^[y]:=255;
     B3[x]^[y]:=255;
   end;
end;

Procedure Ramme;
{Ramme omkring billedet.}
begin
   Line(px-size-1,py-size-1,px+size+1,py-size-1); {¢v.vandret}
   Line(px-size-1,py+size+1,px+size+1,py+size+1); {ne.vandret}
   Line(px-size-1,py-size-1,px-size-1,py+size+1); {ve.lodret}
   Line(px+size+1,py-size-1,px+size+1,py+size+1); {h¢.lodret}
end;

Procedure RotB;
{Roterer en vinkel og zoom'er.}
var xg,yg,a,b    : Real;    {Koordinater ved rotationen.}
    xg_v,yg_n    : Integer; {Koordinater til udgangspunkt.}
    A1,A2,A3,A4  : Real;    {Vægtede gennemsnit for 4 pixels bidrag.}

begin
 begin
   For y:= size downto -size do
   For x:= -size to size do
   begin
      If frame=maxit then PutPixel(px+x,py+y,B1[x]^[y]);
      xg:=Tr_x[x]^[y]; yg:=Tr_y[x]^[y]; {Gamle værdier hentes fra "Transformation".}
      If (Abs(xg)>size) or (Abs(yg)>size) then B3[x]^[y]:=0 {udenfor}
      else
      begin
        xg_v:=trunc(Tr_x[x]^[y]);    {Afrundede koord. til ned.-ven. hj¢rne.}
        yg_n:=trunc(Tr_y[x]^[y]);
        a:=xg-xg_v; b:=yg-yg_n;      {Forskydning fra ned.-ven. hj¢rne.}
        A1:=b*(1-a);     A2:=b*a;    {Arealer til vægtet gennemsnit.}
        A3:=(1-b)*(1-a); A4:=(1-b)*a;
        {Find roteret billede med vægtet gennemsnit af 4 pixels bidrag.}
        B3[x]^[y]:=round( A1*B2[xg_v]^[yg_n+1] + A2*B2[xg_v+1]^[yg_n+1]
                   + A3*B2[xg_v]^[yg_n] + A4*B2[xg_v+1]^[yg_n]);
      end;
   end;
   For y:= size downto -size do
   For x:= -size to size do
   begin {Lægger billederne sammen med eftergl¢d L=0,25 (L^2=0,0625), og omrokerer.}
      {Beregn kontrast.}
      B3[x]^[y]:=255*round((1-Beta)*B3[x]^[y]/255+Beta/(1+exp(-30*(B3[x]^[y]/255-0.5))));
      {tjek at intensitet ikke overstiger 255.}
      if round((B3[x]^[y]*0.90) + (B2[x]^[y]*0.25) + (B1[x]^[y]*0.06))>255 then B1[x]^[y]:=255
      else B1[x]^[y]:=round((B3[x]^[y]*0.90) + (B2[x]^[y]*0.25) + (B1[x]^[y]*0.06));
      B2[x]^[y]:=B1[x]^[y];
      B3[x]^[y]:=B2[x]^[y];
   end;
 end;
end;

Procedure Tekster;
begin
   SetColor(255);
   GetDate(year,month,day,dow);
   Str(year:4,year_t); Str(month:1,month_t); Str(day:2,day_t);
   overskrift:='Simulering af Videofeedback: Vinkel/Zoom-unders¢gelse.';
   OutTextXY(1,1,overskrift+' MCA d.'+day_t+'/'+month_t+'/'+year_t);
   OutTextXY(1,33,'Zoom:   1.00  1.05  1.10  1.15  1.20  1.25  1.30  1.35  1.40  1.45  1.50  1.55');
   Bar(1,14,640,24);
   SetColor(0);
   OutTextXY(1,15,'  Min.                                                                    Max.');
   For p:=0 to 255 do
   begin
     SetColor(p);
     SetFillStyle(solidfill,p);
     Bar(65+2*p,15,65+2*p+2,23);
   end;
end;

Begin {Hovedprogram}
   Setgraphmode(2); {Initialiserer SVGA640x480 mode i 256 farver fra Unitten BGI256.}
   Grey256; SH;     {Initialiserer gråskala palette + Sort/Hvid.}
   Tekster;
   InitBilled;
   Beta:=0.90;      {Kontrastparameter. Beta=0: Ingen konrast (lineær),
                     Beta=1: kraftig kontrast.}
   Trigo(Vinkel);
   Zoom:=1; Transformation(Zoom,CV,SV);
   Flamme;          {Startbillede (lodret linie).}
   For v:=0 to 8 do {Dette giver 9 rækker med hver sin vinkel.}
   begin
     For z:=0 to 11 do {Dette giver 12 s¢jler med hver sin zoom-værdi.}
     begin
       px:=60+size+z*(2*size+6); {Position af billede ved}
       py:=50+size+v*(2*size+6); {udskrivning på skærm.}
       Ramme;
       Zoom:=1.00+z/20; Vinkel:=5*v;
       Trigo(Vinkel); Transformation(Zoom,CV,SV); {Forudberegn rotationen.}
       Sluk; Flamme; {Nulstil billeder og start forfra med startbillede.}
       For frame:=1 to maxit do RotB;
     end;
     str(Vinkel:3,v_t); OutTextXY(1,py-4,'V='+v_t);
   end;
   While not keypressed do;
   For y:= size downto -size do
   {T¢m hukommelsen det sted billederne har ligget}
   begin Dispose(B1[y]); Dispose(B2[y]); Dispose(B3[y]);
         Dispose(Tr_x[y]); Dispose(Tr_y[y]);
   end;
 Cleardevice;
 CloseGraph;
End.



Michael Cramer Andersen
1/24/2000