Линза
Материал из DRKB
Реализация 1 - на Паскале.
Если линза на экpане - окpужность (x0, y0, r0), то в точках (x, y), для котоpых
(x-x0)2 + (y-y0)2 <= r02
pисуется точка, котоpая, если бы линзы не было, изобpажалась бы в точке
(x0 + (x-x0)*k1, y0 + (y-y0)*k)
где
k = const1 / ([sqrt]((x-x0)2+(y-y0)2) + const2)
Можно заpанее пpосчитать таблицу смещений - array[-r0..r0, -r0..r0] of Integer.
{$A+,B-,D+,E+,F-,G+,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}
{$M 16384,0,655360}
uses CRT;
const
vx0 = 3;
vy0 = 2;
v0 = vx0;
r0 = 50;
r02 = (r0-v0)*(r0-v0);
d = r02 * 10 div 10;
type
TScreenType = array[0..199, 0..319] of Byte;
TDispType = array[-r0..r0, -r0..r0] of Integer;
var
Screen : TScreenType absolute $a000:$0000;
Buffer1, Buffer2 : ^TScreenType;
Disp : ^TDispType;
x, y, vx, vy,
r2, c : LongInt;
procedure Move(var A, B; Count: Word); assembler;
asm
push ds
mov cx, Count
les di, B
lds si, A
shr cx, 1
jz @zero
rep movsw
@zero:
pop ds
end;
begin
asm
mov ax, $13
int $10
end;
New(Buffer1);
New(Buffer2);
New(Disp);
FillChar(Screen, SizeOf(Screen), 3);
y := 0;
repeat
for x := 0 to 319 do
Screen[y, x] := 11;
Inc(y, 10);
until y > 199;
x := 0;
repeat
for y := 0 to 199 do
Screen[y, x] := 11;
Inc(x, 10);
until x > 319;
Move(Screen, Buffer1^, SizeOf(Screen));
Move(Buffer1^, Screen, 64000);
for y := -r0 to r0 do
begin
for x := -r0 to r0 do
begin
r2 := x * x + y * y;
if r2 > r02 then
Disp^[y, x] := y * 320 + x
else
Disp^[y, x] := (y*(r2+d) div (r02+d))*320 + (x*(r2+d) div (r02+d));
end;
end;
x := r0;
y := r0;
vx := vx0;
vy := vy0;
repeat
asm
mov ax, Integer(y)
mov bx, 320
imul bx
add ax, Integer(x)
mov di, ax
mov dx, -r0*320-r0
les si, Disp
mov ch, 2*r0+1
@next_dy:
mov cl, 2*r0+1
@next_dx:
mov es, Word(Disp+2)
mov bx, es:[si]
mov es, Word(Buffer1+2)
mov al, es:[di+bx]
mov bx, Seg(Screen)
mov es, bx
mov bx, dx
mov es:[di+bx], al
add si, 2
inc dx
dec cl
jnz @next_dx
add dx, 320-(2*r0+1)
dec ch
jnz @next_dy
end;
if ((x + vx) >= r0) and ((x + vx) <= 319 - r0) then
Inc(x, vx)
else
vx := -vx;
if ((y + vy) >= r0) and ((y + vy) <= 199 - r0) then
Inc(y, vy)
else
vy := -vy;
Delay(25);
until Port[$60] = $01;
Dispose(Buffer1);
Dispose(Buffer2);
Dispose(Disp);
asm
mov ax, $03
int $10
end;
end.
Source: http://algolist.manual.ru
ID: 04244