1. Trang chủ
  2. » Công Nghệ Thông Tin

Đồ họa máy tính - Chương 2 doc

35 352 3

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Chương 2: Công cụ đồ họa của Turbo Pascal (TP)
Trường học Đại học Sư phạm Hà Nội
Chuyên ngành Đồ họa máy tính
Thể loại Chương
Năm xuất bản N/A
Thành phố Hà Nội
Định dạng
Số trang 35
Dung lượng 1,8 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

- Đặt chúng ở cùng 1 thư mục nếu không thì phải lập đường dẫn cho GRAPH.TPU tại Option/Directory/Unit directory và cho EGAVGA.BGI bằng InitGraph - Đặt lệnh khởi tạo chế độ đồ họa InitGra

Trang 1

Chương II: Công cụ đồ họa của Turbo Pascal (TP)

CGA IBM CGA , chỉ hiển thị được 4 màu

EGAVGA.BGI VGA và đại đa số các card màn hình

hiện nay

Có 16 màu Độ phân giải 640 * 480

2 Phải làm gì để khởi tạo chế độ đồ họa ?

Chúng ta sẽ lập trình đồ họa bằng TP Muốn vậy cần phải:

- Có các file: EGAVGA.BGI, GRAPH.TPU (thư viện chứa các lệnh vẽ đồ họa) và các file cơ bản của TP

- Đặt chúng ở cùng 1 thư mục (nếu không thì phải lập đường dẫn cho GRAPH.TPU tại Option/Directory/Unit directory và cho EGAVGA.BGI bằng InitGraph)

- Đặt lệnh khởi tạo chế độ đồ họa (InitGraph) vào trong chương trình

Ví dụ: Cách đơn giản và hay dùng nhất để khởi tạo đồ họa

Chúng ta sẽ chỉ dùng loại mạnh nhất này

xâu rỗng hằng đ/n

sẵn

Trang 2

- Luôn luôn khởi tạo được chế độ mạnh nhất VGA (16 màu, độ phân giải 640 * 480) Trong các phần tiếp theo ta luôn giả thiết rằng chế độ đồ họa là VGA

Chỉ để tham khảo: bảng các loại graphics card và chế độ đồ họa tương ứng

3 Hệ trục tọa độ màn hình

Trong chế độ đồ họa, chúng ta phải làm việc với một hệ trục tọa độ khác thường:

1) Trục tung Oy quay xuống dưới (hệ trục Decac nghịch)

2) các giá trị tọa độ phải là các số nguyên

3) Nếu tọa độ vượt ra ngoài khoảng (0,639) đối với hoành độ và (0,479) đối với tung

độ, thì những gì ta vẽ sẽ không hiển thị trên màn hình

Giải thích:

1) Do cấu tạo của màn hình, ta phải chấp nhận

2) Màn hình chia thành nhiều ô vuông nhỏ (pixel) sắp xếp theo từng dòng và cột như hình vẽ

3) Giả sử ta vẽ đoạn thẳng AB, thì chỉ có đoạn CD nằm trong màn hình được hiển thị

Trang 3

Chú ý: chúng ta không cần nhớ 2 giá trị 640 và 480 vì TP đã có 2 hàm GetMaxX và GetMaxY, chúng trả lại giá trị lớn nhất của hoành độ và tung độ đối với mode đồ họa hiện thời: GetMaxX = 639 ; GetMaxY = 479 ;

Trang 4

10 LightGreen Xanh lá cây nhạt

PutPixel(x,y,c); /* x,y : integer ; c: word (kiểu số nguyên dương) */

Vẽ 1 điểm ảnh tại tọa độ (x,y) với màu c,

/* Gặp readkey chương trình sẽ dừng lại để ta quan sát màn hình Xem xong ta bấm phím bất kỳ để qua lệnh này */

CloseGraph;

End

VNhững hằng, biến nào trong chương trình trên có thể được thay bằng những giá trị tương đương mà không làm thay đổi chương trình ?

VViết chương trình tô một phần tư màn hình (phía trên bên phải) bằng màu xanh da trời

VChương trình trên lấp kín màn hình bằng cách tô theo dòng hay cột ?

Trang 5

Ví dụ: vẽ lưới điểm nhấp nháy

VHàm GetPixel làm chức năng gì trong ví dụ trên ?

VThử thay đổi giá trị tham số của hàm delay() và random() và quan sát kết quả

Ví dụ: Vẽ bầu trời sao đơn giản

Trang 6

VHãy giải thích ý nghĩa của tx,ty,d ?

VNếu gán d:=0.5 thì kết quả thay đổi ra sao ?

VVì sao phải có dấu trừ trong tham số thứ 2 của PutPixel ? Nếu bỏ dấu trừ đi thì kết quả ra sao ?

VHãy vẽ đồ thị hàm số y = x2 – 2x +1 trong khoảng [-3,3]

VHãy vẽ đồ thị hàm số y = sin 2x trong khoảng [-2π, 2π]

6 Vẽ đoạn thẳng

Line(x1,y1,x2,y2) /* x1,x2,y1,y2: integer */

Vẽ đoạn thẳng nối (x1,y1) với (x2,y2) bằng màu vẽ hiện thời ấn định bởi lệnh SetColor gần nhất Nếu không có lệnh SetColor nào thì màu vẽ mặc định luôn là màu Trắng (white) Trước lệnh vẽ đoạn thẳng ta nên đặt màu vẽ cho lệnh Line bằng lệnh

SetColor (c); /* c: word */

VHãy vẽ thêm 2 trục tọa độ cho ví dụ mẫu vẽ đồ thị hàm sin ở mục trên

VHãy làm lại ví dụ “Tô toàn màn hình bằng màu đỏ” nhưng dùng lệnh Line thay cho PutPixel

VHãy tô kín hình chữ nhật (50,50,100,100) bằng cách dùng lệnh Line

VVẽ và lấp đầy một hình bình hành bằng các đoạn thẳng xiên như hình (a) Có thể lấp đầy bằng các đoạn thẳng nằm ngang như hình (b) được không ?

50,50

100,100

Trang 7

VBiết rằng trên màn hình màu đen chỉ có 1 tam giác màu trắng có vị trí và hình dạng bất

kỳ Hãy đếm xem có bao nhiêu điểm ảnh nằm bên trong tam giác đó (không tính các cạnh) ?

VHãy vẽ lại đồ thị hàm y = sin(x) nhưng thay vì chấm từng điểm ảnh như ở ví dụ trên thì

ta nối điểm ảnh này với pixel tiếp theo

Ngoài ra còn có 2 lệnh vẽ đoạn thẳng khác

LineTo(x,y) /* x,y: integer */

LineRel(dx,dy) /* x1,x2,y1,y2: integer */

Lệnh LineTo(x,y) vẽ đoạn thẳng nối CP hiện thời (xem khái niệm CP ở phần sau) với điểm (x,y), nói cách khác

Trang 8

CopyPut 0 Vẽ hình mới đè lên hình cũ (chế độ vẽ bình thường)

XorPut 1 Màu của từng pixel sẽ được Xor với màu cũ

Trong chế độ XorPut, giá trị màu vẽ và màu nền được nhị phân hóa, sau đó làm phép Xor với nhau để ra màu hiển thị

Xor 0 1

0 0 1

1 1 0

Lệnh SetWriteMode có tác động tới các lệnh vẽ đường như: Line, LineTo, LineRel,

Rectangle, DrawPoly và không tác động tới các lệnh vẽ đường tròn, elip

Ví dụ: Minh họa chế độ xorput

SetFillStyle(1,Brown); /* đặt chế độ tô đặc với màu tô là nâu */

Bar(100,100,200,200); /* Vẽ hình vuông màu nâu */

VSau lệnh Readkey thứ nhất chương trình dừng lại, lúc đó trên màn hình có gì ?

VSau lệnh Readkey thứ 2 chương trình dừng lại, lúc đó trên màn hình có gì ? Tại sao ?

Trang 9

Chế độ XorPut đặc biệt hay được dùng để vẽ hình chuyển động vì dù hình mới là gì thì sau

2 lần vẽ đè với XorPut hình cũ cũng sẽ được khôi phục nguyên trạng (vẽ hình chuyển động không để lại vết)

VGiải thích nhận định trên

8 Cửa sổ ViewPort của TP

ViewPort (của đồ họa Pascal) là 1 vùng hình chữ nhật trên màn hình Để thiết lập ViewPort

ta dùng lệnh:

SetViewPort(x1,y1,x2,y2,clip);

x1,x2,y1,y2: tọa độ của ViewPort; clip = true (không cho phép vẽ ra ngoài) hoặc false Chú ý là sau khi đã thiết lập ViewPort thì gốc tọa độ được tự động chuyển về (x1,y1)

Xóa nội dung bên trong ViewPort: ClearViewPort;

Loại bỏ hẳn ViewPort, trở về chế độ làm việc toàn màn hình: ClearDevice; Lệnh này cũng

dùng để xóa màn hình và đưa CP về (0,0)

9 Con trỏ trong chế độ đồ họa (CP: Current Pointer)

Ta không nhìn thấy CP trên màn hình, nhưng TP luôn theo dõi vị trí của CP bằng cặp hàm

GetX, GetY: trả lại tọa độ hiện thời của CP

Moveto(x,y): di chuyển CP tới (x,y)

MoveRel(dx,dy): di chuyển CP tới vị trí mới cách vị trí cũ 1 độ chênh là (dx,dy)

ViewPort: clip=off ViewPort: clip=on

Trang 10

Lệnh có liên quan đến CP:

- LineTo(x,y): vẽ đoạn thẳng nối từ CP đến (x,y), đồng thời chuyển CP đến đó

- LineRel(dx,dy): vẽ đoạn thẳng nối từ CP đến vị trí mới có độ chênh là (dx,dy) và

kéo CP tới đó

10 Vẽ hình chữ nhật

Vẽ hình chữ nhật có đỉnh trên bên trái là (x1,y1), đỉnh dưới phải (x2,y2) và các cạnh song song với 2 trục:

Rectangle(x1,y1,x2,y2); /* x1,y1,x2,y2: integer */

Để vẽ và tô hình chữ nhật đặc ta dùng Bar(x1,y1,x2,y2); /* x1,y1,x2,y2: integer */

màu tô và mẫu tô phải được thiết lập từ trước bằng lệnh

LtSlashFill 3 Tô sọc chéo thưa

Slashfill 4 Tô sọc chéo dày

UserFill 12 người lập trình tự định nghĩa bằng lệnh SetFillPattern()

Lệnh SetFillStyle() đặt mẫu tô cho các lệnh tô hình kín như:

Trang 11

if j<>7 then {ô dưới cùng của một cột}

if mau=white then mau:= black else mau:=white; {2}

Trang 12

VHãy vẽ một hình vuông ở tâm màn hình, cho nó từ từ phình to ra đến khi chạm rìa màn hình thì dừng lại Sau đó co lại để trở về kích thước ban đầu

11 Đa giác

Vẽ đa giác

DrawPoly(n,P);

n: số đỉnh đa giác +1

P: tham số chứa tọa độ các đỉnh của đa giác

Tô đa giác bằng lệnh sau:

FillPoly(n,P); /* n và P như trên Chú ý là n không cần cộng 1*/

Xem các ví dụ sau để hiểu rõ

Ví dụ: Vẽ các ngũ giác ngẫu nhiên

Trang 13

Ví dụ: Vẽ và tô các ngũ giác ngẫu nhiên

Trang 14

End

Chú ý quan sát ta thấy, với các đa giác lõm lệnh FillPoly tính toán tất cả các chỗ tự cắt và sau đó tô riêng từng phần Màu tô và mẫu tô xác định bởi SetFillStyle Dưới đây là 1 ngũ giác lõm với các cạnh tự cắt được tô bởi FillPoly

12 Tô màu miền kín

FloodFill(x,y,color); /* x,y : integer; c: word */

Vùng cần tô được nhận dạng nhờ 2 yếu tố:

- đường biên khép kín có màu color

- điểm (x,y) là một điểm bất kỳ nằm bên trong vùng cần tô

Màu tô và mẫu tô được ấn định bởi SetFillStyle

Ví dụ: VẼ LÁ CỜ ĐỎ SAO VÀNG

uses crt,graph;

var gd, gm, i, goc, r : integer;

p : array[1 5,1 2] of integer; { toạ độ các đỉnh ngôi sao }

BEGIN

gd := 0; initgraph(gd,gm,'');

goc := 18; r := 100;

for i := 1 to 5 do begin

p[i,1] := round(r*cos(goc*pi/180)); { hoành độ của đỉnh thứ i }

p[i,2] := - round(r*sin(goc*pi/180)); { tung độ của đỉnh thứ i }

goc := goc + 2*72;

end;

(x,y)

(x,y)

Trang 15

VLệnh FillPoly ở trên tô màu một ngũ giác, đó là ngũ giác nào ?

VGiải thích các lệnh: goc := 18; goc := goc + 2*72;

VVì sao không vẽ và tô đa giác 10 đỉnh (123456789-10) ? thay vào đó ví dụ trên vẽ đa giác nào ?

13 Vẽ cung, đường tròn

Vẽ cung tròn: Arc(x,y, g1,g2,r);

x,y: integer - tọa độ tâm đường tròn

g1,g2: word – góc bắt đầu và góc cuối

của cung tròn (tính bằng độ)

r: word – bán kính

Để vẽ hình quạt tròn, đầu tiên ta vẽ cung tròn, sau đó gọi thủ tục

GetArcCoords(VAR ArcCoords: ArcCoodsType);

để lấy tọa độ 2 đầu mút (A,B) của cung.Cuối cùng ta vẽ hai đoạn thẳng nối chúng với tâm O của đường tròn

Với kiểu ArcCoodsType được định nghĩa như sau:

Trang 16

VCải tiến chương trình trên để vẽ đầu cá đóng - mở miệng liên tục

VViết chương trình vẽ hình trăng lưỡi liềm và khuyên

Vẽ đường tròn tâm (x,y) bán kính r :

Circle(x,y,r); /* x,y: integer; r: word */

Vẽ cung elip tâm (x,y), bán trục lớn xr, bán trục bé yr, góc bắt đầu và góc kết thúc là g1,g2

Ellipse(x,y,g1,g2,xr,yr)

Trang 17

Vẽ và tô hình quạt tròn:

PieSlice(x,y, g1,g2, r);

Ý nghĩa các tham số giống như lệnh Arc

Để tô màu ellip, cũng như đường tròn, ta dùng thủ tục:

FillEllipse(x,y,xr,yr); {x,y:integer; xr,yr: word}

Để tô một cung ellip ta gọi thủ tục

Sector(x,y,StAngle,EndAngle,xr,yr); {x,y: integer; StAngle,EndAngle, xr,yr: word}

Ví dụ: VẼ BÓNG CHUYỂN ĐỘNG KIỂU BẬT TƯỜNG

Trang 18

if (x>=640-r) or (x<r) then dx:=-dx; {nếu chạm cạnh trái/phải thì đổi hướng}

if (y>=480-r) or (y<r) then dy:=-dy; {nếu chạm cạnh trên/dưới thì đổi hướng}

x := x + dx; y := y + dy; {cập nhật toạ độ}

until keypressed; {có phím nhấn thì dừng}

END

VVị trí xuất phát, kích thước bóng là gì ? biến nào quy định hướng xuất phát của bóng ?

VChương trình trên dùng kỹ thuật gì để vẽ hình chuyển động ?

{Vẽ kim giây chuyển động}

x:=a; y:=b-r; line(a,b,x,y);

Trang 19

VÝ nghĩa các biến a,b,x,y, r, d là gì ?

VChương trình trên dùng kỹ thuật gì để vẽ kim giây chuyển động ?

VNếu là vẽ kim phút thì phải sửa chương trình trên như thế nào ?

VHãy vẽ đồng hồ với 2 kim cùng chuyển động: kim giây và kim 1/10 giây

14 Viết chữ

OutText(s); {s: string}

OutTextXY(x,y,s); {x,y:integer; s: string}

Lệnh OutText(s) hiển thị xâu ký tự s tại vị trí CP, không di chuyển CP Lệnh OutTextXY hiển thị xâu ký tự s tại vị trí (x,y)

Các phông chữ (font) khác nhau nằm trên các file *.CHR, nên để chúng tại cùng vị trí với file *.BGI Chọn kiểu font chữ bằng lệnh sau:

SetTextStyle(Font, Direction, Size);

Tên font Giá trị số

Trang 20

Để lưu một hình vào bộ nhớ, ta phải lưu cả diện tích hình chữ nhật bao nó

Để tính toán kích thước vùng nhớ cần dùng để chứa hình, ta gọi hàm

ImageSize(x1,y1,x2,y2) ; {x1,y1,x2,y2: integer }

với (x1,y1,x2,y2) là tọa độ hình chữ nhật bao quanh hình cần lưu trữ Chú ý là TP không cho phép lưu trữ một hình có diện tích quá lớn

Sau đó, ta xin trình dịch cấp phát vùng nhớ này bằng cách gọi thủ tục

GetMem(p: pointer, n: word) ;

Thủ tục này xin cấp phát 1 vùng nhớ n byte (n phải được dự trù trước bằng cách gọi hàm ImageSize), rồi lưu địa chỉ vùng nhớ đó vào con trỏ p Chú ý: sau khi dùng xong nên giải

A B C

Memory

(x1,y1)

(x2,y2)

Trang 21

phóng vùng nhớ này bằng FreeMem(p,n); nếu không sau vài lần gọi GetMem sẽ cạn dung

lượng nhớ

Bước tiếp theo, ta dùng thủ tục

GetImage(x1,y1,x2,y2, p) ; {x1,y1,x2,y2: integer ; p: pointer}

để sao chép các điểm ảnh trên màn hình nằm trong phạm vi hình chữ nhật (x1,y1,x2,y2) vào vùng nhớ xác định bởi con trỏ p;

Khi cần thiết, ta dán ảnh đang lưu trong bộ nhớ ra màn hình bằng thủ tục

PutImage(x,y,p,mode); {x,y: integer; p: pointer; mode: word}

Lệnh này sẽ copy ảnh đang lưu trong bộ nhớ xác định bởi p vào vị trí (x,y) theo kiểu mode Tham số mode nhận các giá trị như sau

CopyPut 0 Vẽ hình mới đè lên hình cũ

XorPut 1 Màu của từng pixel sẽ được Xor với màu cũ

Trang 22

x:=50; y:=50; canh:=100; {ảnh cần lưu là 1 hình vuông cạnh dài 100 pixel}

Rectangle(x,y,x+canh,y+canh); {vẽ đường bao quanh phạm vi ảnh cần lưu}

VGiải thích ý nghĩa của các biến: canh,x,y Tác dụng của 2 lệnh SetViewPort trong

chương trình trên là gì ? thử thay đổi giá trị tham số cuối cùng (tham số boolean) của chúng

và quan sát kết quả

VNếu thay CopyPut bằng XorPut trong lệnh PutImage(x+dx,y,p^,CopyPut); thì có gì thay đổi không ? Vì sao ?

16 Nhận biết phím được ấn

Trong khi chương trình đang chạy, người dùng có thể ấn các phím để điều khiển (ví

dụ trong các game sử dụng bàn phím để điều khiển hành động của nhân vật) Để nhận biết phím nào được ấn, một trong những kỹ thuật TP hay sử dụng là dùng hàm Readkey Đối với những phím đặc biệt như các phím mũi tên, lần đọc bằng Readkey thứ nhất sẽ trả lại giá trị

0 để ta nhận biết đó là phím mở rộng, lần Readkey thứ hai mới đọc ra mã quét mở rộng của chúng phím đó Đối với phím bình thường (như Esc, các phím chữ cái ) thì chỉ cần một lần đọc bằng Readkey

Ví dụ: Hộp chuyển động theo sự điều khiển của người dùng

{Hộp vuông dịch chuyển theo phím mũi tên mà người dùng bấm}

Trang 23

VGiải thích ý nghĩa của các biến: canh, ch, x,y

VChương trình trên dùng kỹ thuật gì để vẽ hộp chuyển động ?

VChương trình trên quy định phím nào là phím kết thúc chương trình ? Hãy viết lại chương trình để nó coi phím chữ a là phím kết thúc (mã ASCII của chữ a là 65)

VQuan sát ta thấy nếu hộp di chuyển ra ngoài màn hình thì nó biến mất Hãy sửa chương trình để nó không thể chạy vượt ra khỏi phạm vi màn hình (dừng lại khi ra đến mép, hoặc chạm vào mép và bắt đầu chạy ngược lại)

17 Các kỹ thuật đồ họa cơ bản và minh họa

Trang 24

Ví dụ: VẼ BÁNH XE LĂN (1)

uses crt,graph;

var gd,gm,x,y,dx,da,r,a : integer;

procedure banhxe(x,y,r,c,n,a : integer); {vẽ bánh xe có n nan hoa với màu c}

var goc,dx,dy,i : integer; {a là góc của nan hoa đầu tiên}

begin

SetColor(c); goc := a;

circle(x,y,r);

for i := 1 to n do begin

dx := round(r* cos(goc * pi/180)); {dx, dy là toạ độ tương đối của đầu nan hoa}

dy :=-round(r* sin(goc * pi/180));

x := 30; y := 200; dx := 3; a := 30; r := 30; {dx là chiều dài 1 bước tiến của bánh xe}

da:=round(dx/r*180/pi); {da là góc quay của nan hoa tương ứngvới bước tiến dx}

repeat

banhxe(x,y,r,yellow,12,a); {vẽ bánh xe}

delay(40);

banhxe(x,y,r,black,12,a); {vẽ bánh xe với màu nền để xoá}

if (x>=640-r) then x := r; {nếu bánh xe đến mép bên phải thì quay lại bên trái}

Trang 25

VTrong Procedure banhxe(), dx,dy là tọa độ tương đối của đầu nan hoa trong hệ tọa độ nào ? (gốc tọa độ ở đâu ? trục Oy hướng nào ?)

VTrong procedure banhxe, 360 div n là góc gì ? tại sao có dấu trừ trong lệnh dy

:=-round(r* sin(goc * pi/180)); tọa độ tâm bánh xe ở đâu ?

VTại sao phải gán da:=round(dx/r*180/pi); thay vào đó, nếu gán những giá trị cụ thể như 3,6,9 độ cho góc quay da thì kết quả ra sao ?

VHãy sửa chương trình để bánh xe lăn ngược lại mỗi khi chạm đến 2 biên trái/phải

VHãy dùng kỹ thuật XorPut để xóa bánh xe trong procedure banhxe

Ngày đăng: 22/07/2014, 09:20

HÌNH ẢNH LIÊN QUAN

4. Bảng màu - Đồ họa máy tính - Chương 2 doc
4. Bảng màu (Trang 3)

TỪ KHÓA LIÊN QUAN