Giáo trình Lý thuyết đồ họa
Tóm tắt Giáo trình Lý thuyết đồ họa: ...inP nãúu x X1 PRight = > laûi Ngæåüc0 maxP nãúu x X1 PBelow = < laûi Ngæåüc0 minP nãúu y Y1 PAbove = > laûi Ngæåüc0 maxP nãúu y Y1 • Xét ñoạn thẳng AB, ta có các trường hợp sau: i/ Nếu Mã(A) = Mã(B) = 0000 thì AB ∈ D ⇒ ClipD(F) = AB ii/ Nếu ...1 ,P2,...,PL Các ñiểm Pi , i=0,1,...,L ñược gọi là các ñiểm kiểm soát hay các ñiểm Bezier. ða giác tạo bởi các ñiểm kiểm soát này gọi là ña giác kiểm soát hay ña giác Bezier. 6.1.2. Dạng Bernstein của các ñường cong Bezier ðường cong Bezier dựa trên (L+1) ñiểm kiểm soát P0 ,P1 , ...,PL ñược ...ñến Zmax. Ta sẽ thực hiện ánh xạ các giá trị ñộ sâu tính ñược của các ñiểm trên ña Chương VII. Khử ñường và mặt khuất 95 giác sang ñoạn 0..4294967294. Biết rằng ñộ sâu Zmin ứng với 0 và Zmax ứng với 4294967294. (ñộ sâu 4294967295 làm giá trị mặc ñịnh cho các ñiểm nền + Z_Buffer: là ma t...
truoc:=j+1; if j=n then truoc:=1; sau:=j-1; if j=1 then sau:=n; if i=P[j].x then begin if (i>min(P[sau].x,P[truoc].x))and (i<max(P[sau].x,P[truoc].x)) then begin inc(m); z[m]:=P[j].y; end else begin inc(m); z[m]:=P[j].y; inc(m); z[m]:=P[j].y; end; end; if (i>min(P[j].x,P[truoc].x))and (i<max(P[truoc].x,P[j].x)) then begin inc(m); r:=(P[truoc].y-P[j].y)/(P[truoc].x-P[j].x); z[m]:=P[j].y+trunc(r*(i-P[j].x)); end; end; for j:=1 to m-1 do for k:=j+1 to m do if z[j]>z[k] then begin tg:=z[j];z[j]:=z[k];z[k]:=tg; end; setcolor(mau2); For k:=1 to m-1 do if k mod 20 then line(i,z[k],i,z[k+1]); end; Phụ lục. Một số chương trỡnh minh họa 124 End; Procedure ThietLapDoHoa; var Gd,Gm:Integer; Begin Gd:=0; InitGraph(Gd,Gm,’C:\BP\BGI’); End; Begin CLRSCR; NhapDuLieu(a,n); minx:=a[1].x; maxx:=minx; miny:=a[1].y; maxy:=miny; for i:=1 to n do begin if minx>a[i].x then minx:=a[i].x; if miny>a[i].y then miny:=a[i].y; if maxx<a[i].x then maxx:=a[i].x; if maxy<a[i].x then maxy:=a[i].y; end; ThietLapDoHoa; vedagiac(a,n); Tomau(a,n); readln; closegraph; end. 2. Thuật toỏn tụ loang (ðệ qui) uses crt, graph; Type ToaDo=record x,y:integer; End; Mang=array[0..30] of ToaDo; Var a:Mang; x,y,n,Gd,Gm:Integer; procedure NhapDaGiac(Var n:integer); var i:integer; begin clrscr; write('Nhap vao so dinh cua mot da giac n= '); readln(n); for i:=1 to n do begin writeln('Toa do dinh thu',i,'la:'); write('a[',i,'].x='); readln(a[i].x); Phụ lục. Một số chương trỡnh minh họa 125 write('a[',i,'].y='); readln(a[i].y); end; Write('Nhap x= '); Readln(x); Write('Nhap y= '); Readln(y); end; Procedure VeDaGiac(n,color:integer); var i,j:byte; begin SetColor(Color); for i:=1 to n do begin if i=n then j:=1 else j:=i+1; line(a[i].x,a[i].y,a[j].x,a[j].y); end; end; Function Max(a,b:integer):integer; Begin if a<b then Max:=b else Max:=a; End; Function Min(a,b:integer):integer; Begin if a<b then Min:=a else Min:=b; End; Function KiemTra(x,y:Integer;a:Mang):Boolean; var dem,i,j,s:Integer; Begin dem:=0; for i:=1 to n do { Tim so giao diem } begin if i=n then j:=1 else j:=i+1; if i=1 then s:=n else s:=i-1; if x=a[i].x then begin if y<a[i].y then if (x<=Min(a[s].x ,a[j].x)) OR (x>=Max(a[s].x,a[j].x)) then dem:=dem+2 else dem:=dem+1; end else if (x>Min(a[i].x,a[j].x))and(x<Max(a[j].x,a[i].x)) then if y<=Min(a[i].y,a[j].y) then dem:=dem+1 else if y <= (x-a[j].x)*(a[i].y-a[j].y)/(a[i].x- a[j].x)+a[j].y then dem:=dem+1; end; if dem mod 2=1 then KiemTra:=True else KiemTra:=False; Phụ lục. Một số chương trỡnh minh họa 126 End; Procedure ToLoang(x,y:Integer;color:Byte); Begin if KiemTra(x,y,a) and (GetPixel(x,y)color) then Begin PutPixel(x,y,color); ToLoang(x+1,y,color); ToLoang(x-1,y,color); ToLoang(x,y+1,color); ToLoang(x,y-1,color); End; End; BEGIN Nhapdagiac(n); Gd:=Detect; InitGraph(Gd,Gm,'D:\TP\BGI'); Vedagiac(n,4); Toloang(x,y,14); readln; closegraph; END. 3. Thuật toỏn tụ loang (Khử ủệ qui) Uses crt, graph; Type ToaDo=record x,y:integer; End; DANHSACH=^DS; DS=Record Data:ToaDo; Next:DANHSACH; End; Mang=array[0..30] of ToaDo; Var Stack:DanhSach; a:Mang; x,y,n,Gd,Gm:Integer; Procedure KhoiTaoStack; Begin Stack:=Nil; End; Procedure PUSHStack(a:ToaDo;Var Stack:DanhSach); { Nhap vao dau danh sach } Var p:DanhSach; Begin new(p); p^.Data:=a; p^.next:=nil; p^.next:=Stack; Phụ lục. Một số chương trỡnh minh họa 127 Stack:=p; End; Procedure POPStack(Var Stack:DanhSach;var x,y:Integer); { Lay ra o dau danh sach } Var p:DanhSach; Begin If Stacknil then Begin p:=Stack; Stack:=Stack^.next; x:=p^.Data.x; y:=p^.Data.y; Dispose(p); End; End; procedure NhapDaGiac(Var n:integer;var a:Mang); var i:integer; begin clrscr; write('Nhap vao so dinh cua mot da giac n= '); readln(n); for i:=1 to n do begin writeln('Toa do dinh thu',i,'la:'); write('a[',i,'].x='); readln(a[i].x); write('a[',i,'].y='); readln(a[i].y); end; Write('Nhap x= '); Readln(x); Write('Nhap y= '); Readln(y); end; Procedure VeDaGiac(n,color:integer); var i,j:byte; begin SetColor(Color); for i:=1 to n do begin if i=n then j:=1 else j:=i+1; line(a[i].x,a[i].y,a[j].x,a[j].y); end; end; Function Max(a,b:integer):integer; Begin if a<b then Max:=b else Max:=a; End; Phụ lục. Một số chương trỡnh minh họa 128 Function Min(a,b:integer):integer; Begin if a<b then Min:=a else Min:=b; End; Function KiemTra(x,y:Integer;a:Mang):Boolean; var dem,i,j,s:Integer; Begin dem:=0; for i:=1 to n do { Tim so giao diem } begin if i=n then j:=1 else j:=i+1; if i=1 then s:=n else s:=i-1; if x=a[i].x then begin if y<a[i].y then if (x<=Min(a[s].x ,a[j].x))OR (x>=Max(a[s].x,a[j].x)) then dem:=dem+2 else dem:=dem+1; end else if (x>Min(a[i].x,a[j].x)) and (x<Max(a[j].x,a[i].x)) then if y<=Min(a[i].y,a[j].y) then dem:=dem+1 else if y <= (x-a[j].x)*(a[i].y-a[j].y)/ (a[i].x-a[j].x)+a[j].y then dem:=dem+1; end; KiemTra:=dem mod 2=1; End; Procedure ToLoang(x,y:Integer;color:Byte); Var B,C:ToaDo; Begin if KiemTra(x,y,a) and (GetPixel(x,y)color) then Begin PutPixel(x,y,color); B.x:=x+1; B.y:=y; PUSHStack(B,Stack); B.x:=x-1; B.y:=y; PUSHStack(B,Stack); B.x:=x; B.y:=y+1; PUSHStack(B,Stack); B.x:=x; B.y:=y-1; PUSHStack(B,Stack); End; While Stacknil do Begin POPStack(Stack,B.x,B.y); if KiemTra(B.x,B.y,a) and Phụ lục. Một số chương trỡnh minh họa 129 GetPixel(B.x,B.y)color) then Begin PutPixel(B.x,B.y,color); C.x:=B.x+1; C.y:=B.y; if KiemTra(C.x,C.y,a) and (GetPixel(C.x,C.y)color) then PUSHStack(C,Stack); C.x:=B.x-1; C.y:=B.y; if KiemTra(C.x,C.y,a) and (GetPixel(C.x,C.y)color) then PUSHStack(C,Stack); C.x:=B.x; C.y:=B.y+1; if KiemTra(C.x,C.y,a) and (GetPixel(C.x,C.y)color) then PUSHStack(C,Stack); C.x:=B.x; C.y:=B.y-1; if KiemTra(C.x,C.y,a) and (GetPixel(C.x,C.y)color) then PUSHStack(C,Stack); End; End; End; BEGIN KhoiTaoStack; Nhapdagiac(n,a); Gd:=Detect; InitGraph(Gd,Gm,'D:\TP\BGI'); Vedagiac(n,4); Toloang(x,y,14); readln; closegraph; END. II. CÁC THUẬT TOÁN XẫN HèNH 1. Thuật toỏn Cohen Sutherland Uses crt,graph; Const LEFT=1; RIGHT=2; BELOW=4; ABOVE=8; Type ToaDo2D=record x,y:integer; end; var Tren,Duoi,A,B:ToaDo2D; gd,gm:Integer; ch:char; Phụ lục. Một số chương trỡnh minh họa 130 procedure NhapDinhHCN; begin Tren.x:=100; Tren.y:=100; Duoi.x:=450; Duoi.y:=350; randomize; a.x:=random(GetMaxx); a.y:=random(GetMaxY); b.x:=random(GetMaxx); b.y:=random(GetMaxY); end; PROCEDURE VeHCN; begin line(Tren.x,Tren.y,Duoi.x,Tren.y); line(Duoi.x,Tren.y,Duoi.x,Duoi.y); line(Duoi.x,Duoi.y,Tren.x,Duoi.y); line(Tren.x,Duoi.y,Tren.x,Tren.y); setwritemode(xorput); line(a.x,a.y,b.x,b.y); ch:=readkey; line(a.x,a.y,b.x,b.y); setwritemode(orput); end; FUNCTION MA(P:ToaDo2D):Byte; var s:Byte; BEGIN s:=0; if P.x<Tren.x then s:=s OR Left; if P.x>Duoi.x then s:=s OR Right; if P.y<Tren.y then s:=s OR Above; if P.y>Duoi.y then s:=s OR Below; Ma:=s; end; Procedure Swap(Var A,B:ToaDo2D); var t:ToaDo2D; Begin t:=a; a:=b; b:=t; End; Procedure Clipping(A,B,Tren,Duoi:ToaDo2D); Var stop,draw:Boolean; m:Real; Begin stop:=False; draw:=False; While not stop do Begin Phụ lục. Một số chương trỡnh minh họa 131 If (Ma(A)=0)and(Ma(B)=0) then Begin stop:=True; draw:=True; End else If (Ma(A) and Ma(B)0) then stop:=True else Begin If (Ma(A)and Ma(B)=0)and (Ma(A)0)or(Ma(B)0)) then Begin if Ma(A)=0 then Swap(A,B); {A luon nam ngoai} if A.x=B.x then Begin if Ma(A) and ABOVE0 then A.y:=Tren.y else A.y:=Duoi.y; if Ma(B)0 then Begin if Ma(B) and ABOVE0 then B.y:=Tren.y; if Ma(B) and BELOW0 then B.y:=Duoi.y; End; stop:=True; draw:=True; End else {AxBx} Begin m:=(B.y-A.y)/(B.x-A.x); If Ma(A) and LEFT0 then Begin A.y:=round((Tren.x - A.x)*m + A.y); A.x:=Tren.x; End else If Ma(A) and RIGHT0 then Begin A.y:=round((Duoi.x - A.x)*m + A.y); A.x:=Duoi.x; End else If Ma(A) and ABOVE0 then Begin A.x:=round((Tren.y - A.y)/m + A.x); A.y:=Tren.y; End else If Ma(A) and BELOW0 then Begin A.x:=round((Duoi.y - A.y)/m +A.x); A.y:=Duoi.y; Phụ lục. Một số chương trỡnh minh họa 132 End; End; End; End; End; setcolor(14); If draw then Line(A.x,A.y,B.x,B.y); setcolor(15); End; BEGIN gd:=detect; Initgraph(gd,gm,'D:\TP\BGI'); repeat NhapDinhHCN; VeHCN; Clipping(A,B,Tren,Duoi); until ch=#27; closegraph; END. 2. Thuật toỏn chia nhị phõn Uses crt,graph; type ToaDo2D=record x,y:integer; end; var Tren,Duoi,A,B:ToaDo2D; gd,gm:Integer; procedure NhapDinhHCN; begin Tren.x:=100; Tren.y:=100; Duoi.x:=300; Duoi.y:=200; a.x:=352; a.y:=122; b.x:=22; b.y:=23; end; PROCEDURE VeHCN; begin line(Tren.x,Tren.y,Duoi.x,Tren.y); line(Duoi.x,Tren.y,Duoi.x,Duoi.y); line(Duoi.x,Duoi.y,Tren.x,Duoi.y); line(Tren.x,Duoi.y,Tren.x,Tren.y); setwritemode(xorput); line(a.x,a.y,b.x,b.y); readln; Phụ lục. Một số chương trỡnh minh họa 133 line(a.x,a.y,b.x,b.y); end; FUNCTION MA(P:ToaDo2D):Byte; var s:Byte; BEGIN s:=0; if P.x<Tren.x then s:=s OR Left; if P.x>Duoi.x then s:=s OR Right; if P.y<Tren.y then s:=s OR Above; if P.y>Duoi.y then s:=s OR Below; Ma:=s; end; PROCEDURE XuLyATrongBNgoai(A,B:ToaDo2D); Var C,D,M:ToaDo2D; begin c:=a;d:=b; While abs(C.x-D.x)+abs(C.y-D.y)>2 do begin M.x:=round((C.x+D.x)/2); M.y:=round((C.y+D.y)/2); if ma(M)0 then D:=M else C:=M; end; line(A.x,A.y,C.x,C.y); end; PROCEDURE Clipping(A,B,Tren,Duoi:ToaDo2D); Var C,D,M:ToaDo2D; Begin if (ma(a)=0) and (ma(b)=0) then line(a.x,a.y,b.x,b.y); if (ma(a)=0) and (ma(b)0) then XulyATrongBNgoai(A,B); if (ma(a)0) and (ma(b)=0) then XulyATrongBNgoai(B,A); if (ma(A)0) and (ma(B)0) and ((ma(A) and ma(B))=0) then begin C:=A; D:=B; M.x:=(C.x+D.x)div 2; M.y:=(C.y+D.y)div 2; while (ma(M)0)and(abs(C.x-D.x)+abs(C.y-D.y)>2) do begin if (ma(C) and ma(M))0 then C:=M else D:=M; M.x:=(C.x+D.x)div 2; M.y:=(C.y+D.y)div 2; end; if ma(M)=0 then begin XulyATrongBNgoai(M,A); XulyATrongBNgoai(M,B); end; Phụ lục. Một số chương trỡnh minh họa 134 end; End; BEGIN NhapDinhHCN; gd:=detect; Initgraph(gd,gm,'D:\TP\BGI'); VeHCN; Clipping(A,B,Tren,Duoi); readln; closegraph; END. 3. Thuật toỏn Liang-Barsky Uses crt,graph; var PTop,PBottom,A,B:PointType; gd,gm:Integer; procedure NhapDinhHCN; var i:integer; begin writeln('Nhap toa do dinh tren trai cua HCN:'); write('x1=');readln(PTop.x); write('y1=');readln(PTop.y); writeln('Nhap toa do dinh duoi phai cua HCN:'); write('x2=');readln(PBottom.x); write('y2=');readln(PBottom.y); writeln('Nhap toa do dinh thu nhat cua duong thang:'); write('a.x=');readln(a.x); write('a.y=');readln(a.y); writeln('Nhap toa do dinh thu hai cua duong thang:'); write('b.x='); readln(b.x); write('b.y='); readln(b.y); end; PROCEDURE VeHCN; begin line(PTop.x,PTop.y,PBottom.x,PTop.y); line(PBottom.x,PTop.y,PBottom.x,PBottom.y); line(PBottom.x,PBottom.y,PTop.x,PBottom.y); line(PTop.x,PBottom.y,PTop.x,PTop.y); setwritemode(xorput); line(a.x,a.y,b.x,b.y); readln; line(a.x,a.y,b.x,b.y); end; Function Clip(p,q:real; Var u1,u2:real):Boolean; Var r:real; Begin Clip:=True; Phụ lục. Một số chương trỡnh minh họa 135 If p<0 then Begin r:=q/p; If r>u2 then Clip:=False else If r>u1 then u1:=r; End else If p>0 then Begin r:=q/p; If r<u1 then Clip:=False else If r<u2 then u2:=r; End else If q<0 then Clip:=False; End; Procedure LiangBaskyClip(p1,p2,PTop,PBottom:PointType); Var u1,u2,dx,dy:real; Begin u1:=0; u2:=1; dx:=p2.x - p1.x; If Clip(-dx,p1.x - PTop.x,u1,u2) then If Clip(dx,PBottom.x - p1.x,u1,u2) then Begin dy:=P2.y - P1.y; If Clip(-dy,p1.y - PTop.y,u1,u2) then If Clip(dy,PBottom.y - p1.y,u1,u2) then Begin If u2<1 then Begin p2.x:=p1.x + Round(u2*dx); p2.y:=p1.y + Round(u2*dy); End; If u1>0 then Begin p1.x:=p1.x + Round(u1*dx); p1.y:=p1.y + Round(u1*dy); End; Line(p1.x,p1.y,p2.x,p2.y); End; End; End; BEGIN clrscr; NhapDinhHCN; gd:=detect; Initgraph(gd,gm,'D:\TP\BGI'); VeHCN; LiangBaskyClip(a,b,PTop,PBottom); readln; closegraph; Phụ lục. Một số chương trỡnh minh họa 136 END. III. VẼ CÁC ðỐI TƯỢNG 3D 1. Vẽ mặt yờn ngựa USES crt, graph, DOHOA3d ; {Su dung Unit DoHoa3D} VAR u,uMin, uMax,du : real; v,vMin, vMax, dv : real; a1,a2,b1,b2,c1,c2,d : integer; PROCEDURE Nhap_tham_so; BEGIN projection := Phoicanh; rho := 50; de := 2000; theta := 40; phi := 20; uMin := -1; uMax := 1 ; vMin := -1 ; vMax:= 1 ; du := 0.095; dv := 0.09; a1:= 0; a2:=0; b1:= 0; b2:=0; c1:= 0; c2:=0; d := 1; END; FUNCTION fx(u,v:real): real; BEGIN fx:=a1*cos(u) + b1*cos(v) + c1*cos(u)*cos(v) + d*u; END; FUNCTION fy(u,v:real): real; BEGIN fy:=a1*cos(u) + b1*sin(v) + c2*cos(u)*sin(v) + d*v ; END ; FUNCTION fz(u,v:real): real; BEGIN fz := a2*sin(u) +b2*sin(v) + d*u*u - d*v*v ; END ; PROCEDURE ho_duong_cong_u ; VAR P :ToaDo3D; BEGIN u := uMin; {Mat cat U ban dau} WHILE u<=uMax DO BEGIN v :=vMin; {Mat cat V ban dau} P.x :=fx(u,v); P.y :=fy(u,v); P.z :=fz(u,v); DiDen(P); {Move to point (x,y,z) ban dau} WHILE v <= vMax DO {Thay doi mat cat V} Phụ lục. Một số chương trỡnh minh họa 137 BEGIN P.x :=fx(u,v); P.y :=fy(u,v); P.z := fz(u,v); VeDen(P); {Ve den diem (x,y,z) moi} v := v+dv; {tang gia tri mat cat V} END; u:=u+du; {tang gia tri mat cat U} END; END; PROCEDURE ho_duong_cong_v ; VAR P :ToaDo3D; BEGIN v := vMin; {Mat cat V ban dau} WHILE v<=vMax DO BEGIN u :=vMin; {Mat cat U ban dau} P.x :=fx(u,v); P.y :=fy(u,v); P.z :=fz(u,v); DiDen(P); WHILE u <= uMax DO BEGIN P.x :=fx(u,v); P.y :=fy(u,v); P.z := fz(u,v); VeDen(P); u := u+du; {tang gia tri mat cat U} END; v :=v+dv; {tang gia tri mat cat V} END; {of while v} END; PROCEDURE DEMO; BEGIN nhap_tham_so; REPEAT XoaManHinh; KhoiTaoPhepChieu; ho_duong_cong_u ; ho_duong_cong_v ; DieuKhienQuay; UNTIL upcase(ch) = char(27); END; BEGIN { Main program } ThietLapDoHoa; demo; CloseGraph; Phụ lục. Một số chương trỡnh minh họa 138 END. 2. Vẽ cỏc ủối tượng WireFrame uses crt,Graph,DoHoa3D; Const MaxDinh=50; MaxCanh=100; Type WireFrame=Record SoDinh:0..MaxDinh; Dinh:Array[1..MaxDinh] of ToaDo3D; SoCanh:0..MaxCanh; Canh:Array[1..MaxCanh,1..2] of 1..MaxDinh; End; Var a:WireFrame; Procedure KhoiTaoBien; Begin Rho:=5; Theta:=20; Phi:=20; De:=3; End; Procedure DocFile(FileName:String; Var WF:WireFrame); var f:Text; x,i:Integer; Begin assign(f,FileName); Reset(f); With WF do Begin read(f,x); SoDinh:=x; read(f,x); SoCanh:=x; For i:=1 to SoDinh do {Doc so dinh} Begin read(f,x); Dinh[i].x:=x; read(f,x); Dinh[i].y:=x; read(f,x); Dinh[i].z:=x; End; For i:=1 to SoCanh do {Doc so Canh} Begin read(f,x); Canh[i,1]:=x; read(f,x); Canh[i,2]:=x; End; End; Close(f); End; Procedure VeWireFrame(WF:WireFrame); Var i:Byte; d1,d2:ToaDo3D; Begin Phụ lục. Một số chương trỡnh minh họa 139 With WF do Begin for i:=1 to SoCanh do Begin d1:=Dinh[Canh[i,1]]; d2:=Dinh[Canh[i,2]]; DiDen(d1); VeDen(d2); End; End; End; Begin DocFile('bacdien.txt',a); Projection:=SongSong{PhoiCanh}; ThietLapDoHoa; KhoiTaoBien; repeat KhoiTaoPhepChieu; VeWireFrame(a); DieuKhienQuay; until ch=#27; CloseGraph; End. 3. Khử mặt khuất theo giải thuật BackFace Uses crt,graph,DoHoa3D; Const MaxSoDinh=50; MaxSoMat =30; MaxDinh =10; Type TapDinh=Array[1..MaxSoDinh] of ToaDo3D; TapMat=Array[1..MaxSoMat,0..MaxDinh] of Integer; FaceModel=Record SoDinh:Integer; Dinh:TapDinh; SoMat:Integer; Mat:TapMat; End; Var Hinh:FaceModel; O:ToaDo3D; Procedure KhoiTao; Begin Projection:=Phoicanh; Rho:=1500; Theta:=20; Phi:=15; DE:=3000; End; Procedure VectorNhin(Dinh1,Dinh2,Dinh3:Integer; Var v:toaDo3D); Phụ lục. Một số chương trỡnh minh họa 140 Begin With hinh do Begin v.x:=O.x - Dinh[Dinh1].x; v.y:=O.y - Dinh[Dinh1].y; v.z:=O.z - Dinh[Dinh1].z; end; End; Procedure VectorChuan(Dinh1,Dinh2,Dinh3:Integer; Var N:ToaDo3D); Var P,Q:ToaDo3D; Begin With hinh do Begin P.x:=Dinh[Dinh2].x - Dinh[Dinh1].x; P.y:=Dinh[Dinh2].y - Dinh[Dinh1].y; P.z:=Dinh[Dinh2].z - Dinh[Dinh1].z; Q.x:=Dinh[Dinh3].x - Dinh[Dinh1].x; Q.y:=Dinh[Dinh3].y - Dinh[Dinh1].y; Q.z:=Dinh[Dinh3].z - Dinh[Dinh1].z; N.x:=P.y*Q.z - Q.y*P.z; N.y:=P.z*Q.x - Q.z*P.x; N.z:=P.x*Q.y - Q.x*P.y; End; End; Function TichVoHuong(v,n:ToaDo3D):Real; Begin TichVoHuong:=v.x*N.x + v.y*N.y + v.z*N.z; End; Procedure ToaDoQuanSat; Begin KhoiTaoPhepChieu; O.x:= Rho*Aux7; O.y:= Rho*Aux8; O.z:= Rho*Aux2; End; Procedure DocFile(FileName:String; Var WF:FaceModel); var f:Text; x,i,j:Integer; Begin assign(f,FileName); Reset(f); With WF do Begin read(f,x); SoDinh:=x; read(f,x); SoMat:=x; For i:=1 to SoDinh do {Doc so dinh} Phụ lục. Một số chương trỡnh minh họa 141 Begin read(f,x); Dinh[i].x:=x; read(f,x); Dinh[i].y:=x; read(f,x); Dinh[i].z:=x; End; For i:=1 to SoMat do {Doc so Mat} Begin read(f,x); read(f,x); Mat[i,0]:=x; For j:=1 to Mat[i,0] do Begin read(f,x); Mat[i,j]:=x; End; End; End; Close(f); End; Procedure VeMat(f:Integer); Var SoCanh,i,j:Integer; P,P0:ToaDo3D; Begin With hinh do Begin SoCanh:=Mat[f,0]; For i:=1 to SoCanh do Begin j:=Mat[f,i]; P.x:=Dinh[j].x; P.y:=Dinh[j].y; P.z:=Dinh[j].z; If i=1 Then Begin DiDen(P); P0.x:=P.x; P0.y:=P.y; P0.z:=P.z; End Else VeDen(P); End; VeDen(P0); End; End; Procedure VeVatThe(Hinh:FaceModel); Var f,Dinh1,Dinh2,Dinh3:Integer; v,n:ToaDo3D; Begin With hinh do Begin For f:=1 to SoMat do Begin Dinh1:=Mat[f,1]; Dinh2:=Mat[f,2]; Dinh3:=Mat[f,3]; VectorNhin(Dinh1,Dinh2,Dinh3,v); Phụ lục. Một số chương trỡnh minh họa 142 VectorChuan(Dinh1,Dinh2,Dinh3,N); If TichVoHuong(v,n)>0 Then Begin SetLineStyle(SolidLN,0,NormWidth); VeMat(f); End Else Begin SetLineStyle(DottedLN,0,NormWidth); VeMat(f); End; End; End; End; PROCEDURE DieuKhien; BEGIN ToaDoQuanSat; VeVatThe(Hinh); Repeat DieuKhienQuay; ToaDoQuanSat; VeVatThe(Hinh); Until ch=#27; END; BEGIN { Chuong Trinh Chinh } DocFile('Batdien.txt',Hinh); ThietLapDoHoa; KhoiTao; DieuKhien; CloseGraph; END.
File đính kèm:
- giao_trinh_ly_thuyet_do_hoa.pdf