Giáo trình Lập trình nâng cao trên ngôn ngữ Pascal - Chương 6: Đồ họa

ðồhoạtrong Pascal không phải là công cụchuyên dùng ñểthiết kếhình ảnh. Tuy nhiên

nếu biết tận dụng các công cụsẵn có trong Unit Graph chúng ta có thểlàm ñược nhiều việc,

ñặc biệt là vẽ ñồthịcác hàm số. Trong chương này bạn ñọc tiếp cận các khái niệm sau:

 Các thủtục vẽhình ñơn giản

 Các thủtục viết chữtrong chế ñộ ñồhoạ

 Các thủtục tô màu

 Các phương pháp xửlý ảnh Bitmap

 Phương pháp vẽ ñồthịhàm số

pdf23 trang | Chuyên mục: Pascal | Chia sẻ: dkS00TYs | Lượt xem: 2620 | Lượt tải: 1download
Tóm tắt nội dung Giáo trình Lập trình nâng cao trên ngôn ngữ Pascal - Chương 6: Đồ họa, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
bước 1 
Chú ý: khi vẽ hình chuyển ñộng cần phải tạo các các ñiểm dừng ñể khi không muốn 
chuyển ñộng có thể ngắt ngay chương trình. 
Dưới ñây là chương trình vẽ một bầu trời sao, số ngôi sao trên bầu trời là 100 trong ñó 
có 40 ngôi sao nhấp nháy, 20 ngôi sao nhấp nháy nhanh và 20 sao nhấp nháy chậm, các ngôi 
sao ñược phân bổ ngẫu nhiên. Trong chương trình còn thiết kế một ñĩa bay, ñĩa bay có 25 kích 
thước khác nhau, mỗi hình vẽ ñĩa bay ñược cất vào một biến con trỏ P, các biến con trỏ này 
nằm trong một mảng con trỏ. Các ñĩa bay xuất hiện ngẫu nhiên trên bầu trời, chuyển ñộng nhỏ 
dần và biến mất, sau ñó lại hiện lên tại một toạ ñộ nào ñó. Chương trình dừng lại khi bấm một 
phím bất kỳ. 
Với các máy tính có dung lượng bộ nhớ lớn (128 hoặc 256 Mb) chúng ta có thể tăng 
số hình ñĩa bay lên 50 hình khi ñó ñĩa bay sẽ chuyển ñộng mịn màng hơn. 
Ví dụ 6.9 
Program Bautroi_diabay; 
Uses graph,crt; 
Var 
 i,j,gd,gm:integer; a,x,y,xx,yy:word; 
 p: array[1..30] of pointer; 
 m,n :array[1..40] of word; 
 Procedure bautroi(a:word); 
 var i,j:word; m,n :array[1..40] of word; ch:char; 
 Begin 
 for j:= 1 to 5 do 
 Begin 
 for i:= 1 to a do 
 begin 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 159 
 x:=random(639); y:=random(479); 
 if i<=40 then (*chon 40 ngoi sao nhap nhay*) 
 begin 
 m[i]:=x; n[i]:=y; (*ghi toa do sao nhap nhay vao mang*) 
 end; 
 putpixel(x,y,random(15));(*hien sao *) 
 end; 
 end; 
end; 
 Procedure nhapnhay; 
 var i,j:word; k:byte; 
 Begin 
 for i:= 1 to 40 do (*chon 40 ngoi sao nhap nhay*) 
 begin 
 m[i]:=random(639); 
 n[i]:=random(479); (*ghi toa do sao nhap nhay vao mang*) 
 end; 
 setcolor(random(15)); 
 for j:=0 to 3 do 
 For i:=1 to 20 do (*20 sao nhap nhay nhanh*) 
 begin 
 circle(m[i+j],n[i+j],1); 
 delay(5); 
 end; 
 for j:=0 to 3 do 
 For i:=21 to 40 do (*20 sao nhap nhay cham*) 
 begin 
 setcolor(random(4)); 
 circle(m[i+j],n[i+j],1); 
 delay(10); 
 end; 
 End; 
 procedure vedia; 
 Var xx,yy,x,y,x1,y1,x2,y2:integer; p: array[1..30] of pointer; 
 r,i,r1,r2,r3,r4,r5:word; 
 Begin 
 setcolor(14);setbkcolor(0); 
 i:=1; x:= 50; y:= 50; {diem dau tien dia bay xuat hien} 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 160 
 for r:= 25 downto 1 do {chọn 25 ñĩa với các kích thước giảm dần} 
 Begin 
 r1:=round(r/2); 
 r2:=round(r/3); 
 r3:=round(r/5); 
 r4:=2*r2; 
 r5:=round(r/10); 
 Ellipse(x,y,0,360,r,r1); 
 Ellipse(x,y-r3,194,346,r,r2); 
 Line(x+r2,y-r2,x+r4,y-r4); 
 circle(x+r4,y-r4,r5); 
 line(x-r2,y-r2,x-r4,y-r4); 
 circle(x-r4,y-r4,r5); 
 x1:=x-r; 
 y1:=y-r4-r5; 
 x2:=x+r; 
 y2:=y+r1; 
 Getmem(p[i], imagesize(x1,y1,x2,y2));(*xac dinh kich thuoc anh*) 
 getimage(x1,y1,x2,y2,p[i]^); (*cat anh vao bien con tro*) 
 putimage(x1,y1,p[i]^,xorput); (*xoa anh*) 
 i:=i+1; 
 End; 
 i:=1; 
 While not keypressed do 
 Begin (*hien dia bay voi cac kich thuoc khac nhau*) 
 putimage(x,y,p[i]^,xorput); 
 delay(100); 
 xx:=x; yy:=y; 
 x:=x+random(25); 
 y:=y+random(25); 
 putimage(xx,yy,p[i]^,xorput); (*xoa dia bay*) 
 for j:= 1 to 40 do (*tao su nhap nhay cua ngoi sao*) 
 begin 
 setcolor(random(15)); 
 circle(m[j],n[j],1); 
 end; 
 i:=i+1; 
 if i>25 then {da hien het cac hinh dia bay} 
 begin 
 x:=random(500); 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 161 
 y:=random(400); 
 i:=1; 
 end; 
end; 
end; 
BEGIN {than chuong trinh chinh} 
 gd:=detect; a:=100; {a la so ngoi sao tren bau troi} 
 initgraph(gd,gm,'C:\tp\bgi'); 
 if graphresultgrok then halt; 
 bautroi(a); {hien bau troi sao} 
 while not keypressed do 
 begin 
 nhapnhay; {thiet ke cac ngoi sao nhap nhay} 
 vedia; {goi dia bay} 
 end; 
 closegraph; 
END. 
7. ðồ thị hàm số 
Giả thiết hàm y = f(x) xác ñịnh và liên tục trên ñoạn [a,b], cần vẽ ñồ thị hàm trong 
một khu vực nào ñó trên màn hình. Hệ toạ ñộ quen thuộc mà chúng ta sử dụng là hệ xoy với 
gốc toạ ñộ nằm ở góc dưới bên trái, trục x hướng sang phải, trục y hướng lên trên. 
Màn hình máy vi tính tuỳ theo kích thước và chế ñộ làm việc có thể là ma trận ñiểm từ 
640x480 ñến 1024x720. Gốc toạ ñộ của màn hình lại ở góc trên bên trái và trục x hướng theo 
chiều từ trên xuống dưới. ðể thuận tiện cho việc vẽ và quan sát ñồ thị chúng ta cần phải 
chuyển ñổi từ toạ thực (như trong toán học) sang toạ ñộ màn hình. 
Ký hiệu toạ ñộ thực của miền vẽ ñồ thị ñiểm góc dưới trái là xmin, ymin và góc trên 
phải là xmax, ymax. Toạ ñộ màn hình góc trên trái là cmin , dmin, góc dưới phải là cmax, 
dmax. 
Một ñiểm bất kỳ trên ñồ thị có toạ ñộ thực là x, y và toạ ñộ màn hình là c, d. Có thể 
chứng minh rằng: 
c = m*(x - xmin) + cmin 
d = n*(y - ymin) + dmin 
 xmax, ymax 
 xmin, ymin
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 162 
Trong ñó: 
p = (cmax - cmin)/(xmax - xmin) 
q = (dmin - dmax)/(ymax- ymin) 
Hiệu số (dmin - dmax) mang dấu âm cho biết chiều biến thiên của trục thẳng ñứng 
giữa toạ ñộ màn hình và toạ ñộ thực là ngược nhau. 
Khi vẽ ñồ thị trên màn hình chúng ta sẽ dùng các công thức trên ñể chuyển ñổi toạ ñộ 
tính ñược từ thực tế sang toạ ñộ màn hình. 
Phương pháp vẽ ñồ thị là xác ñịnh toạ ñộ từng ñiểm sau ñó nối các ñiểm với nhau 
bằng các ñoạn thẳng. ðể ñồ thị trơn tru thì số ñiểm phải thật nhiều, tuy nhiên chúng ta không 
thể tăng vô hạn số ñiểm. Giả sử chia ñoạn [a,b] thành n ñoạn nhỏ, chúng ta sẽ có n+1 ñiểm 
ñánh số từ 0 ñến n. Khi ñó chiều rộng mỗi ñoạn sẽ là h = (b - a)/n. 
Hoành ñộ của một ñiểm bất kỳ trong toạ ñộ thực: 
xi = a + h*i, 
và tung ñộ tương ứng sẽ là f(xi). 
ðiều cần chú ý khi chọn các toạ ñộ thực và toạ ñộ màn hình là miền trên màn hình 
phải bao kín miền toạ ñộ thực. Muốn vậy chúng ta chọn: 
xmin = a, xmax = b, ymin = min(yi), ymax = max(yi). 
Việc khảo sát hàm số f(x) ñể tìm max và min theo kiểu toán học là không thực tế trong 
Pascal, do vậy có thể thay thế việc tìm min(yi) và max(yi) bằng việc lưu các giá trị f(xi) vào 
một mảng, sau ñó tìm cực trị trong mảng. 
ðể chương trình có thể ứng dụng cho tất cả các hàm số chúng ta sẽ xây dựng một 
chương trình con lấy tên là HAM khai báo hàm và tính giá trị của hàm tại các toạ ñộ xi. Một 
chương trình con lấy tên là TOADO ñể tính các hệ số m, n, và tung ñộ các ñiểm chia (tức là 
giá trị của hàm f(x) tại các toạ ñộ xi). 
Ví dụ 6.10 
Program vedothi; 
 Uses graph; 
 Const n=200; 
 cmin=3; dmin=3;cmax=200; dmax=140;{ve o goc phan tu thu nhat} 
 xmin=-5; xmax=5; 
 Var gd,gm:integer; 
 ymin,ymax,h,m,p,q:real; 
 y:Array[0..n] of real; 
 Function F(x:real) : real; 
 Begin 
 {f:=x*x;} 
 F:=x*x*x-2*x; 
 End; 
 Procedure Toado; 
 Var i:integer; xi,yi:real; 
 Begin 
 h:=(xmax-xmin)/n; 
 For i:= 0 to n do 
 Begin 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 163 
 xi:=xmin+i*h; 
 yi:=f(xi); 
 y[i]:=f(xi); 
 End; 
 ymin:=y[0]; ymax:=-ymin; 
 For i:=1 to n do 
 Begin 
 If ymin>y[i] then ymin:=y[i]; 
 If ymax<y[i] then ymax:=y[i]; 
 End; 
 p:= (cmax-cmin)/(xmax-xmin); 
 q:= (dmin-dmax)/(ymax-ymin); 
 End; 
 Procedure Ve; 
 Var i,c,d:integer; xi:real; 
 Begin 
 c:=cmin; 
 d:= round(q*(y[0]-ymin)+dmax); 
 Moveto(c,d); 
 For i:=1 to n do 
 Begin 
 xi:=xmin+i*h; 
 c:=Round(p*(xi-xmin)+cmin); 
 d:=Round(q*(y[i]-ymin)+dmax); 
 setcolor(red); 
 Lineto(c,d) {noi cac diem do thi} 
 End; 
 setcolor(14); 
 moveto(cmin,dmin); Lineto(cmax,dmin);{ve khung do thi} 
 moveto(cmax,dmin); Lineto(cmax,dmax); 
 moveto(cmax,dmax); Lineto(cmin,dmax); 
 moveto(cmin,dmax); Lineto(cmin,dmin); 
 d:=Round(q*(-ymin)+dmax); 
 if (d>=dmin) and (d<=dmax) then 
 Begin 
 line(cmin,d,cmax,d);{truc hoanh} 
 line(cmax,d,cmax-6,d-3); {dau mui ten} 
 line(cmax,d,cmax-6,d+3); 
 end; 
 c:=Round(p*(-xmin)+cmin); 
 if (c>=cmin) and (c<=cmax) then 
 begin 
 Line(c,dmin,c,dmax); {truc tung} 
 Line(c,dmin,c-3,dmin+6); {dau mui ten} 
 Line(c,dmin,c+3,dmin+6); 
 end; End; 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 164 
 BEGIN 
 gd:=detect; 
 Initgraph(gd,gm,'c:\tp70\bgi'); 
 if graphresultgrok then halt; 
 toado; 
 ve; 
 readln; 
 closegraph; 
 END. 
Với các hàm số cho theo tham số x = x(t), y = y(t), hoặc cho trong toạ ñộ cực r = f(ϕ) 
phương pháp vẽ cũng tương tự, chúng tôi xin dành cho bạn ñọc như là những bài tập ứng 
dụng. 
Trường ðại học Nông nghiệp 1 - Giáo trình Lập trình nâng cao ..............................................................- 165 
Bài tập ứng dụng chương 6 
1. Nhập và cho chạy thử chương trình trong ví dụ 6.9 sau ñó thiết kế thêm một tên lửa. 
Cho tên lửa phóng từ góc dưới bên phải màn hình lên góc trên bên trái. Luồng khói phía ñuôi 
dài bằng 3 lần chiều dài tên lửa. 
2. Cho các ký tự của dòng chữ "Happy Birth Day" hiện ngẫu nhiên và nhấp nháy trên 
màn hình, tiếp ñó cho chúng chuyển ñộng ñan xen và thu dần về tâm (320,240). Cuối cùng 
các ký tự lại từ tâm chạy ra trên một quỹ ñạo tròn và ñã sắp xếp thành dòng chữ hoàn chỉnh. 
3. Chọn kích thước và thiết kế các hình ñơn giản 1, 2, 3, 4 (xem hình vẽ), mỗi hình cất 
vào một biến con trỏ. Cho hiện các hình tại các vị trí tuỳ ý sao cho hình vừa chuyển ñộng vừa 
tự quay, cuối cùng các hình tự ghép với nhau thành một hình vuông ở giữa màn hình 
  
  
   
4. Lập chương trình vè ñồ thị hàm số cho dưới dạng tham số 
x = x(t), y =y(t) 
5. Lập chương trình vè ñồ thị hàm số cho dưới dạng toạ ñộ cực 
r = f(ϕ) 
6. Cho hàm y = f(x) xác ñịnh và liên tục trong khoảng (a,b). Lập chương trình nhập 
dạng một hàm cụ thể. Vẽ ñồ thị hàm sau ñó tính tích phân xác ñịnh 
∫
b
a
dxxf )( 

File đính kèm:

  • pdfGiáo trình Lập trình nâng cao trên ngôn ngữ Pascal - Chương 6_Đồ họa.pdf