[r]
Trang 1Ch ươ ng 8
Đ h a ồ ọ
Trong chương này s gi i thi u các hàm đ v các đẽ ớ ệ ể ẽ ường và
hình c b n nh đơ ả ư ường tròn, cung elip, hình qu t, đạ ường g yẫ
khúc, hình đa giác, đường th ng, đẳ ường ch nh t, hình ch nh t,ữ ậ ữ ậ
hình h p ch nh t, Ngoài ra còn đ c p t i các v n đ ộ ữ ậ ề ậ ớ ấ ề r t lý thúấ
khác nh : x lý văn b n trên màn hình đ h a, c a s và k thu tư ử ả ồ ọ ử ổ ỹ ậ
t o nh di đ ng Các hàm đ h a đạ ả ộ ồ ọ ược khai báo trong t pệ
graphics.h
§ 1 Khái ni m đ h a ệ ồ ọ
Đ hi u k thu t l p trình đ h a, đ u tiên ph i hi u các y uể ể ỹ ậ ậ ồ ọ ầ ả ể ế
t c b n c a đ h a T trố ơ ả ủ ồ ọ ừ ước đ n nay chúng ta ch y u làmế ủ ế
vi c v i ki u văn b n Nghĩa là màn hình đệ ớ ể ả ược thi t l p đ hi nế ậ ể ể
th 25 dòng, m i dòng có th ch a 80 ký t Trong ki u văn b n,ị ỗ ể ứ ự ể ả
các ký t hi n th trên màn hình đã đự ể ị ược ph n c ng c a máy PCầ ứ ủ
n đ nh tr c và ta không th nào
ấ ị ướ ể thay đ i đổ ược kích thước, ki uể
ch ữ
màn hình đ h a, ta có th x lý đ n t ng ch m đi m (pixel)
trên màn hình và do v y mu n v b t kỳ th gì cũng đậ ố ẽ ấ ứ ược S bàiự
trí và s pixel trên màn hình đố ược g i là đ phân gi i (resolution).ọ ộ ả
Do m i ki u màn hình đ h a có m t cách x lý đ h a riêng nênỗ ể ồ ọ ộ ử ồ ọ
TURBO C cung c p m t t p tin đi u khi n riêng cho t ng ki u đấ ộ ệ ề ể ừ ể ồ
h a B ng 8-1 cho th y các ki u đ h a và các t p tin đi u khi nọ ả ấ ể ồ ọ ệ ề ể
chúng
Ngoài các t p có đuôi BGI ch a chệ ứ ương trình đi u khi n đề ể ồ
h a, TURBO C còn cung c p các t p tin đuôi CHR ch a các Fontọ ấ ệ ứ
ch đ v các ki u ch khác nhau trên màn hình đ h a Đó là cácữ ể ẽ ể ữ ồ ọ
t p:ệ
GOTH.CHR
LITT.CHR
SANS.CHR TRIP.CHR
B ng 8-1 ả Các t p tin đi u khi n đ h a c a TURBO C++ ệ ề ể ồ ọ ủ
Tên t p tin ệ Ki u màn hình đ h a ể ồ ọ
ATT.BGI ATT & T6300 (400 dòng) CGA.BGI IBMCGA, MCGA và các máy t ươ ng thích EGAVGA.BGI IBM EGA, VGA và các máy t ươ ng thích HERC.BGI Hercules monochrome và các máy t ươ ng thích IBM8514.BGI IBM 8514 và các máy t ươ ng thích
PC3270.BGI IBM 3270 PC
Màn hình đ h a g m nhi u đi m nh đồ ọ ồ ề ể ả ượ ắc s p x p trên cácế
đường th ng ngang và d c Đi u này đúng cho t t c các ki uẳ ọ ề ấ ả ể màn hình đ h a c a máy tính Khác bi t ch y u gi a chúng làồ ọ ủ ệ ủ ế ữ kích thước và s các đi m nh Trong ki u CGA (đ phân gi iố ể ả ể ộ ả
th p), đi m nh có kích thấ ể ả ướ ớc l n, chi u ngề ang có 320 đi m nh,ể ả còn theo chi u d c có 200 đi m nh Màn hình VGA có đ phânề ọ ể ả ộ
gi i cao h n: đi m nh nh h n, trên m i hàng có 640 đi m nhả ơ ể ả ỏ ơ ỗ ể ả
và trên m i c t có 480 đi m nh Đi m nh càng nh thì s đi mỗ ộ ể ả ể ả ỏ ố ể
nh trên màn hình càng nhi u và ch t l ng đ h a càng cao
M i ki u đ h a dùng m t h t a đ riêng H t a đ cho mànỗ ể ồ ọ ộ ệ ọ ộ ệ ọ ộ hình VGA là 640 x 480 nh sau :ư
Trang 2
(0,479) (639,479)
Hình 8.1 H t a đ VGAệ ọ ộ
Nh h t a đ này, ta có th tác đ ng hay tham chi u đ n b tờ ệ ọ ộ ể ộ ế ế ấ
kỳ đi m nh nào trên màn hình đ h a.ể ả ồ ọ
N u dùng màn hình CGA thì góc dế ưới ph i có t a đ (319,ả ọ ộ
199) Đ c l p v i ki u đ h a đang s d ng, các hàm getmaxx vàộ ậ ớ ể ồ ọ ử ụ
getmaxy bao gi cũng cho t a đ x và y l n nh t trong ki u đờ ọ ộ ớ ấ ể ồ
h a đang dùng.ọ
M t chộ ương trình đ h a thồ ọ ường g m các ph n sau:ồ ầ
- Kh i đ ng h th ng đ h a.ở ộ ệ ố ồ ọ
- Xác đ nh m u n n (m u màn hình), m u đị ầ ề ầ ầ ường v , m u tô vàẽ ầ
ki u (m u) tô.ể ẫ
- V , tô m u các hình mà ta mong mu n.ẽ ầ ố
- Các thao tác đ h a khác nh cho hi n các dòng ch ồ ọ ư ệ ữ
- Đóng h th ng đ h a đ tr v mode văn b n.ệ ố ồ ọ ể ở ề ả
§ 2 Kh i đ ng h đ h a ở ộ ệ ồ ọ
M c đích c a vi c kh i đ ng h th ng đ h a là xác đ nh ụ ủ ệ ở ộ ệ ố ồ ọ ị thi tế
b đ h a (màn hình) và m t đ h a s s d ng trong chị ồ ọ ố ồ ọ ẽ ử ụ ươ ng
trình Đ làm đi u này ta dùng hàm:ể ề
void initgraph(int *graphdriver, int *graphmode,char
*driverpath);
trong đó: driverpath là đường d n c a th m c ch a các t p tinẫ ủ ư ụ ứ ệ
đi u khi n đ h a, graphdriver, graphmode cho bi t màn hình vàề ể ồ ọ ế
m t đ h a s s d ng trong chố ồ ọ ẽ ử ụ ương trình B ng 8-2 cho th y cácả ấ
giá tr kh dĩ c a graphdriver và graphmode.ị ả ủ
Ví d 1 ụ Gi s máy tính c a ta có màn hình EGA, các t p tinả ử ủ ệ
đ h a ch a trong th m c C: \TC, khi đó ta có th kh i đ ng hồ ọ ứ ư ụ ể ở ộ ệ
th ng đ h a nh sau:ố ồ ọ ư
#include "graphics.h"
main() { int mh=EGA, mode= EGALO;
initgraph(&mh, &mode, "C:\TC");
}
B ng 8-2 ả Các giá tr kh dĩ c a graphdriver, graphmode ị ả ủ
graphdriver graphmode Đ phân gi i ộ ả
Detect (0)
ATT400C1 (1) 320 x 200
Trang 3ATT400C2 (2) 320 x 200 ATT400C3 (3) 320 x 200 ATT400MED (4) 640 x 400 ATT400HI (5) 640 x 400
IBM8514 (6) IBM8514LO (0) 640 x 480, 256 m u ầ
IBM8514HI (1) 1024 x 768, 256 m u ầ
Chú ý 1 B ng 8-2 cho các tên h ng và giá tr c a chúng mà cácả ằ ị ủ
bi n graphdriver, graphmode có th nh n Ch ng h n h ngế ể ậ ẳ ạ ằ
DETECT có giá tr 0, h ng VGA có giá tr 9, h ng VGALO có giáị ằ ị ằ
tr 0 Khi l p trình ta có th dùng tên h ng ho c giá tr tị ậ ể ằ ặ ị ương ngứ
c a chúng Ch ng h n các phép gán trong ví d 1 có th vi t theoủ ẳ ạ ụ ể ế
m t cách khác tộ ương đương nh sau:ư
mh=3;
mode=0;
Chú ý 2 B ng 8.2 cho th y đ phân gi i ph thu c c vào mànả ấ ộ ả ụ ộ ả
hình và mode Ví d trong màn hình EGA n u dùng mode EGALOụ ế
thì đ phân gi i là 640 x 200, hàm getmaxx cho giá tr 639, hàmộ ả ị
getmaxy cho giá tr 199 N u cũng màn hình EGA mà dùng modeị ế
EGAHI thì đ phân gi i là 640x 350, hàm getmaxx cho giá tr 639,ộ ả ị
hàm getmaxy cho giá tr 349.ị
Chú ý 3 N u không bi t chính xác ki u màn hình đang s d ngế ế ể ử ụ
thì ta gán cho bi n graphdriver h ng DETECT hay giá tr 0 Khi đóế ằ ị
k t qu c a hàm initgraph s là:ế ả ủ ẽ
- Ki u c a màn hình đang s d ng để ủ ử ụ ược phát hi n, giá tr sệ ị ố
c a nó đủ ược gán cho bi n graphdriver.ế
- Mode đ h a đ phân gi i cao nh t ng v i màn hình đangồ ọ ở ộ ả ấ ứ ớ
s d ng cũng đử ụ ược phát hi n và giá tr s c a nó đệ ị ố ủ ược gán cho
bi n graphmode.ế
Nh v y vi c dùng h ng s DETECT ch ng nh ng có th kh iư ậ ệ ằ ố ẳ ữ ể ở
đ ng độ ược h th ng đ h a c a màn hình hi n có theo mode cóệ ố ồ ọ ủ ệ
đ phân gi i cao nh t, mà còn giúp ta xác đ nh chính xác ki u mànộ ả ấ ị ể hình đang s d ng.ử ụ
Ví d 2 ụ Chương trình dưới đây xác đ nh ki u màn hình đang sị ể ử
d ng:ụ
#include "graphics.h"
#include "stdio.h"
main() { int mh=0, mode= 0;
initgraph(&mh, &mode, "");
printf("\n Giá tr s c a màn hình là: %d", mh);ị ố ủ closegraph();
}
N u chế ương trình cho k t qu :ế ả Giá tr s c a màn hình là: 3ị ố ủ thì ta có th kh ng đ nh lo i màn hình đang dùng là EGA.ể ẳ ị ạ
Chú ý 4 N u chu i dùng đ xác đ nh driverpath là m t chu iế ỗ ể ị ộ ỗ
r ng (nh trong ví d 2) thì chỗ ư ụ ương trình d ch s tìm các t p đi uị ẽ ệ ề khi n đ h a trên th m c ch ể ồ ọ ư ụ ủ
§ 3 L i đ h a ỗ ồ ọ
Khi kh i đ ng h th ng đ h a n u máy không tìm th y cácở ộ ệ ố ồ ọ ế ấ
chương trình đi u khi n đ h a thì s phát sinh l i đ h a và vi cề ể ồ ọ ẽ ỗ ồ ọ ệ
kh i đ ng coi nh không thành L i đ h a còn phát sinh khi dùở ộ ư ỗ ồ ọ ng các hàm đ ho Trong m i trồ ạ ọ ường h p, hàm graphresult cho bi tợ ế
có l i hay không l i và đó là l i gì B ng 8-3 cho các mã l i màỗ ỗ ỗ ả ỗ hàm này phát hi n đệ ược Ta có th dùng hàm grapherrormsg v iể ớ
mã l i do hàm graphresult tr v đ bi t đỗ ả ề ể ế ược đó là l i gì, ví d :ỗ ụ int maloi;
Trang 4maloi = graphresult();
printf("\nL i đ h a là: %d", grapherrormsg(maloi));ỗ ồ ọ
B ng 8-3 ả Các mã l i c a Graphresult ỗ ủ
H ng ằ Trị L i phát hi n ỗ ệ
grNoInitGraph -1 Ch a kh i đ ng h đ h a ư ở ộ ệ ồ ọ
grNotDetected -2 Không có ph n c ng đ h a ầ ứ ồ ọ
grFileNotFound -3 Không tìm th y trình đi u khi n đ h a ấ ề ể ồ ọ
grInvalidDriver -4 Trình đi u khi n không h p l ề ể ợ ệ
grNoLoadMem -5 Không đ RAM cho đ h a ủ ồ ọ
grNoScanMem -6 V ượ t vùng RAM trong Scan fill
grNoFloodMem -7 V ượ t vùng RAM trong flood fill
grFontNoFound -8 Không tìm th y t p tin Font ấ ậ
grNoFontMem -9 Không đ RAM đ n p Font ủ ể ạ
grInvalidMode -10 Ki u đ h a không h p l cho trình đi u khi n ể ồ ọ ợ ệ ề ể
grError -11 L i đ h a t ng quát ỗ ồ ọ ổ
grIOerror -12 L i đ h a vào ra ỗ ồ ọ
grInvalidFont -13 T p tin Font không h p l ậ ợ ệ
grInvalidFontNum -14 S hi u Font không h p l ố ệ ợ ệ
§ 4 M u và m u ầ ẫ
1 Đ ch n m u n n ta s d ng hàm ể ọ ầ ề ử ụ
void setbkcolor(int color);
2 Đ ch n m u đ ể ọ ầ ườ ng v ta dùng hàm ẽ
void setcolor(int color);
3 Đ ch n m u (ki u) tô và m u tô ta dùng hàm ể ọ ẫ ể ầ
void setfillstyle(int pattern, int color);
Trong c 3 trả ường h p color xác đ nh mã c a m u Các giá trợ ị ủ ầ ị
kh dĩ c a color cho trong b ng 8-4, pattern xác đ nh mã c a m uả ủ ả ị ủ ẫ
tô (xem b ng 8-5).ả
M u tô và m u tô s đẫ ầ ẽ ược s d ng trong các hàm pieslice,ử ụ fillpoly, bar, bar3d và floodfill (xem §5 dưới đây)
4 Ch n gi i m u ọ ả ầ
Đ thay đ i gi i m u đã để ổ ả ầ ược đ nh nghĩa trong b ng 8.4 taị ả dùng hàm
void setpalette(int colornum, int color);
Ví dụ câu l nhệ setpalette(0, Lightcyan);
bi n m u đ u tiên trong b ng m u thành xanh l nh t Các m uế ầ ầ ả ầ ơ ạ ầ khác không b nh hị ả ưởng
B ng 8-4 ả Các giá tr kh dĩ c a color ị ả ủ
Tên h ng ằ Giá tr s ị ố M u hi n th ầ ể ị
LIGHTBLUE 9 Xanh da tr i nh t ờ ạ LIGHTGREEN 10 Xanh lá cây nh t ạ
Trang 5YELLOW 14 Vàng
5 Đ nh n gi i m u hi n hành ta dùng hàm ể ậ ả ầ ệ
void getpalette (struct palettetype *palette);
đây palettetype là ki u đã đ nh nghĩa tr c nh sau:
#define MAXCOLORS 15
struct palettetype
{
unsigned char size;
unsigned char colors[MAXCOLORS+1];
};
đây: size là s l ng m u trong palette, colors là m ng ch a
m u v i ch s m ng ch y t 0 đ n size - 1ầ ớ ỉ ố ả ạ ừ ế
B ng ả 8-5 Các giá tr kh dĩ c a patternị ả ủ
Tên h ng ằ Giá tr s ị ố Mô t ki u tô ả ể
EMPTY_FILL 0 Tô b ng m u n n ằ ầ ề
SOLID_FILL 1 Tô b ng đ ằ ườ ng nét li n ề
SLASH_FILL 4 Tô b ng /// in đ m ằ ậ
BKSLASH_FILL 5 Tô b ng \\\ in đ m ằ ậ
LTBKSLASH_FILL 6 Tô b ng \\\ ằ
HATCH_FILL 7 Tô b ng đ ằ ườ ng g ch bóng nh t ạ ạ
XHATCH_FILL 8 Tô b ng đ ằ ườ ng g ch bóng ch ạ ữ
th p ậ INTERLEAVE_FILL 9 Tô b ng đ ằ ườ ng đ t quãng ứ
WIDE_DOT_FILL 10 Tô b ng d u ch m th a ằ ấ ấ ư
CLOSE_DOT_FILL 11 Tô b ng d u ch m mau ằ ấ ấ
6 Hàm getcolor tr v m u đã xác đ nh trả ề ầ ị ước đó b ng hàmằ setcolor
7 Hàm getbkcolor tr v m u đã xác đ nh trả ề ầ ị ước đó b ng hàmằ setbkcolor
8 Hàm getmaxcolor tr v mã m u c c đ i thu c gi i m u hi nả ề ầ ự ạ ộ ả ầ ệ đang có hi u l c Trên 256 K EGA, hàm getmaxcolor luôn cho giáệ ự
tr 15.ị
§ 5 V và tô m u ẽ ầ
Có th chia các để ường và hình thành b n nhóm chính:ố
- Đường tròn và ellipse
- Đường g p khúc và hình đa giácấ
- Đường th ngẳ
- Hình ch nh tữ ậ
A Đ ườ ng tròn và hình tròn
Nhóm này g m cung tròn, đồ ường tròn, cung ellipse và hình qu tạ
1 Cung tròn Đ v m t cung tròn ta dùng hàmể ẽ ộ
void arc(int x, int y, int gd, int gc, int r);
đây:
ở (x, y) là t a đ c a tâm cung tròn,ọ ộ ủ
r là bán kính
gd là góc đ uầ
gc là góc cu iố
Chú ý: Trong t t c các hàm dấ ả ưới đây, góc tính theo đ và cóộ giá tr t 0 đ n 360.ị ừ ế
2 Đ ườ ng tròn. Đ v m t để ẽ ộ ường tròn ta dùng hàm
void circle(int x, int y, int r);
đây:
ở
Trang 6static i=1; // L nh này th c hi n m t l n khi d ch ệ ự ệ ộ ầ ị
int j;
// Cho nh p nháy b ng cách đ i m u 50 ngôi saoấ ằ ổ ầ
for (j=1;j<=50;++j)
{
putpixel(xx[i],yy[i],random(getmaxcolor()));
++i;
if (i>1000) i=1;
}
}
§ 12 In nh t màn hình đ ho ả ừ ồ ạ
Hàm in_anh dưới đây s in nh trong mi n ch nh t (xt, yt, xd,ẽ ả ề ữ ậ
yd) c a màn hình đ ho ra gi y trên các máy in LQ1070, LQ1170ủ ồ ạ ấ
và FX1050
void in_anh(int dd,int xt,int yt,int xd,int yd);
Tham s dd là đ đ m c a nét in Th c ch t dd là s l n in l i.ố ộ ậ ủ ự ấ ố ầ ạ
Bình thường chon dd=1 N u mu n in rõ h n ta ch n dd b ng 2ế ố ơ ọ ằ
hay 3
Trong hàm in_anh có dùng hàm tao_mau, nó được mô t nhả ư
sau:
int tao_mau(int k,int x,int y);
Hàm này s dò trên k ch m đi m theo chi u d c b t đ u t toẽ ấ ể ề ọ ắ ầ ừ ạ
đ (x,y) trên màn hình đ bi t xem ch m đi m nào đã tô m u.ộ ể ế ấ ể ầ
Hàm s tr v m t giá tr nguyên t o b i các bit 1 ( ng v i đi mẽ ả ề ộ ị ạ ở ứ ớ ể
đã tô m u) và 0 ( ng v i đi m ch a tô m u).ầ ứ ớ ể ư ầ
Hàm in_anh s dùng hàm tao_mau đ duy t trên mi n ch nh tẽ ể ệ ề ữ ậ
(xt,yt,xd,yd) M i l n duy t s nh n đỗ ầ ệ ẽ ậ ược m t m u các ch mộ ẫ ấ
đi m (giá tr nguyên) và m u này để ị ẫ ược in ra gi y.ấ
Dưới đây là n i dung c a 2 hàm nói trên.ộ ủ // in nh ả
#include "stdio.h"
#include "graphics.h"
int tao_mau(int k,int x,int y);
void in_anh(int dd,int xt,int yt,int xd,int yd);
int tao_mau(int k,int x,int y) {
int c=0,i;
for (i=0;i<k;++i)
if (getpixel(x,y+i)) c =c|(128>>i);
return c;
} void in_anh(int dd,int xt,int yt,int xd,int yd) {
//dd - so lan in lai mot dong char c,ch1;
int scot,m,mm,k,dong,cot,i,j,n1,n2;
dong=(yd-yt+1)/6; mm=(yd-yt+1) % 6;
cot=xd-xt+1;
for (i=0;i<=dong;++i) {
if (i<dong) m=6; else m=mm;
if (m>0) { scot=0;
for (j=0;j < cot;++j)
Trang 7if (tao_mau(m,xt+j,yt+i*6)) scot=j+1;
if (scot)
{ n1=scot % 256; n2= scot/256;
for (k=0;k<dd;++k) {
fprintf(stdprn,"%c%c%c%c%c%c",13,27,'*',
0,n1,n2); //LQ for (j=0;j < scot;++j)
{
if (kbhit())//bat phim {
if ((ch1=getch())==0) getch();
if (ch1==27) goto ket;
} c=tao_mau(m,xt+j,yt+i*6);
fprintf(stdprn,"%c",c);
} } } fprintf(stdprn,"%c%c%c",27,'A',m);
fprintf(stdprn,"\n");
}
}
ket: fprintf(stdprn,"%c%c",27,'@');
}
490