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.