program lab3; uses Crt, Graph; type TMatrix = array[0..2,0..2] of Extended; TPoint3D = record {тип 3-вимiрної точки} x, y, z: Extended; c: Word; end; TKamera = record {тип точки спостереження} x, y, z: Extended; f: Extended; al, bet: Extended; a: TMatrix; end; var p: TPoint3D; a, i, x, y, px: integer; kk: TKamera; min, max: array[0..800] of Word; {масиви нижнього i верхнього горизонтiв} procedure SetKamera(var k: TKamera); {встановлення матрицi обертання} begin with k do begin a[0,0] := 1; a[0,1] := 0.5; a[0,2] := 0; a[1,0] := -0.4; a[1,1] := cos(al); a[1,2] := -sin(al); a[2,0] := 0; a[2,1] := -a[1,2]; a[2,2] := a[1,1]; end; end; procedure GetXY(var x, y: integer; var p: TPoint3D; var k: TKamera); var v, l: TPoint3D; {перетворення точок iз користувацьких в екраннi} begin v.x := p.x*k.a[0,0]+p.y*k.a[0,1]+p.z*k.a[0,2]; v.y := p.x*k.a[1,0]+p.y*k.a[1,1]+p.z*k.a[1,2]; v.z := p.x*k.a[2,0]+p.y*k.a[2,1]+p.z*k.a[2,2]; l.x := v.x-k.x; l.y := v.y-k.y; l.z := v.z-k.z; if l.z > 0 then begin x := GetMaxX div 2 + Round(20.0*l.x*k.f/(k.f+l.z)); {встановлення початку координат} y := GetMaxY div 2 - Round(20.0*l.y*k.f/(k.f+l.z)); end else begin x := -1; y := -1; end; end; function f(x, y: Extended): Extended; begin f := 1.5*(cos(-4*pi*x/50)*-3*cos(-6*pi*y/250)); {функцiя лiнiй, якi формують поверхню} end; begin kk.x := 0; kk.y := 0; kk.z := -50; {установка початкових параметрiв системи координат} kk.f := 100; kk.al := 0.4; SetKamera(kk); x := VGA; y := 1; InitGraph(x,y,''); a := 1; SetBkColor(1); repeat SetActivePage(a); ClearDevice; for x := 0 to 800 do begin {зовнiшнiй цикл (виведення чергової лiнiї)} min[x] := GetMaxY; max[x] := 0; end; p.z := 20; repeat p.x := -20; px := 0; repeat p.y := f(p.x,p.z); GetXY(x,y,p,kk); if min[x] > y then begin {сортування точок за їх видимiстю} for i := px to x do begin min[i] := y; if min[i] > max[i] then max[i] := min[i]; end; PutPixel(x,y,15); {виведення верхньої видимої точки фiгури} end else begin if max[x] < y then begin for i := px to x do max[i] := y; PutPixel(x,y,14); {виведення нижньої видимої точки фiгури} end; end; px := x; p.x := p.x+0.16; {на скiльки змiнюється координата х (вiдстань мiж сусiднiми точками)} until p.x > 20; {цикл, який "вiдрiзає" фiгуру справа} p.z := p.z-0.6; {на скiльки змiнюється координата z (вiдстань мiж сусiднiми лiнiями)} until p.z < -20; {цикл, який "вiдрiзає" фiгуру з глибини} SetVisualPage(a); a := 1-a; kk.al := kk.al-0.01; {на скiльки змiнюється кут повороту} SetKamera(kk); {встановлення значень матрицi повороту} until (kk.al < -0.3) or KeyPressed; {цикл поки кут нахилу фiгури не досяг певного значення або не} while KeyPressed do ReadKey; {натиснено будь-яку клавiшу} CloseGraph; end. |