Giáo trình C - Chương 6: Đồ họa trong C
Mục đích của các hàm đồ hoạ theo kiểu văn bản là tạo ra các cửa sổ . Cửa sổ là
vubgf hình chữ nhật trên màn hình dùng để giới hạn vùng xuất dữ liệu . Nếu ta soạn thảo
văn bản trong cửa sổ thì con nháy chỉ di chuyển trong phạm vi của cửa sổ chứ không phải
toàn bộ màn hình . Ta xét một ch-ơng trình tạo ra cửa sổ và điền đầy vào đó dòng “ Xin
chao “
Ch-ơng trình 6-1 :
#include <conio.h>
#include <dos.h>
#define left 10
#define top 8
#define right 52
#define bot 21
void main()
{
int i;
clrscr();
window(left,top,right,bot);
textcolor(RED);
textbackground(GREEN);
for (i=0;i<100;i++)
{
cputs(" Xin chao "); delay(100);
}
gotoxy(15,8);
cputs("Ket thuc");
getche();
}
oài viewport hay không . Nếu clip 0 thì không thấy đ−ợc hình bên ngoài viewport . Để xoá một viewport ta dùng hàm void far clearviewport(void) Ch−ơng trình 6-12 : #include #include void main() { int gd,gm,i; int left=0,top=0,right=150,bot=150; int x1=0,y1=0,x2=199,y2=199; int x=100,y=100; int clip=1; int r=90; gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); setviewport(left,top,right,bot,clip); setcolor(RED); rectangle(left,top,right,bot); line(x1,y1,x2,y2); circle(x,y,r); getch(); closegraph(); } 8. Vẽ theo toạ độ t−ơng đối : Trong C ta có thể dùng toạ độ t−ơng đối so với điểm hiện hành CP-current point . Để vẽ đ−ờng thẳng ta dùng hàm void far lineto(int x, int y) . Hàm này vẽ đ−ờng thẳng từ điểm CP đến điểm mới có toạ độ là x,y . Hàm void far linerel(int dx , int dy) vẽ đ−ờng thẳng từ CP(xc,yc) đến điểm có toạ độ (xc+dx,yc+dy) . Th−ờng ta hay kết hợp với hàm void far moveto(int x, int y) để di chuyển điểm hiện hành tới điểm mới có toạ độ (x,y) Ch−ơng trình 6-13 : Vẽ một bàn cờ #include #include #define max 160 #define grid 20 #define size 18 void main() { int gd,gm,i,j; void square(int ); 70 gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); for (i=0;i<max;i+=grid) for (j=0;j<max;j+=grid) { moveto(j,i); square(size); } getch(); closegraph(); } void square(int side) { linerel(side,0); linerel(0,side); linerel(-side,0); linerel(0,-side); } 9. Điểm ảnh : Để đặt một điểm ảnh lên màn hình ta dùng hàm : void far putpixel(int x , in y, int color) Ch−ơng trình 6-14 : Lập ch−ơng trình vẽ hình sin bằng putpixel #include #include #include void main() { int gd,gm,x,y; double g,sg; gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); line (1,100,200,100); for (x=0;x<200;x++) { g=((double)x/200)*(2*3.14159); sg=sin(g); y=100-100*sg; putpixel(x,y,RED); } getch(); closegraph(); } Để xác định màu của một điểm ta dùng hàm int getpixel(int x,int y) 10 . ảnh bit và làm ảnh chuyển động : Để cất gữi một hình ảnh vào bộ nhớ ta dùng hàm : void far getimage(int left , int top , int right , int bot , void far * addbuf) 71 left , top , right , bot - các góc của hình chữ nhật chứa ảnh addbuf - địa chỉ bộ nhớ dùng chứa ảnh Hàm này cần biết kích th−ớc của hình . Kích th−ớc này đ−ợc xác định theo hàm : unsigned far imagesize(int left , int top , int right , int bot) Giá trị của hàm đ−ợc truyền cho hàm malloc() để cấp phát bộ nhớ . Con trỏ do hàm malloc() trả về đ−ợc truyền cho hàm putimage để khôi phục lại hình đã cất . Cú pháp của putimage() là : void far putimage(int left , int top , void far * addbuf,int putop) left,top là góc trên trái của vùng sẽ đ−a ảnh ra addbuf - địa chỉ bộ nhớ dùng chứa ảnh putop là các đ−a ảnh ra . Các hằng putop là : Trị Hằng ý nghĩa 0 COPY_PUT Thay hình cũ bằng hình mới 1 XOR_PUT XOR hình cũ bằng hình mới 2 OR_PUT OR hình cũ bằng hình mới 3 AND_PUT AND hình cũ bằng hình mới 5 NOT_PUT Thay hình cũ bằng đảo hình mới Ch−ơng trình 6-15 : Lập ch−ơng trình thể hiện quả bóng dội #include #include #include #define left 0 #define top 0 #define right 639 #define bottom 479 #define r 8 void main() { int gd,gm,x,y; int dx,dy,oldx,oldy; void far *buf; unsigned size; gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); rectangle(left,top,right,bottom); x=y=r+10; setcolor(LIGHTGREEN); setfillstyle(SOLID_FILL,LIGHTGREEN); circle(x,y,r); floodfill(x,y,LIGHTGREEN); size=imagesize(x-r,y-r,x+r,y+r); buf=malloc(size); getimage(x-r,y-r,x+r,y+r,buf); dx=1; dy=1; 72 while (!kbhit()) { putimage(x-r,y-r,buf,COPY_PUT); delay(5); oldx=x; oldy=y; x=x+dx; y=y+dy; if (x=right-r-2) dx=-dx; if (y=bottom-r-2) dy=-dy; putimage(oldx-r,oldy-r,buf,XOR_PUT); delay(5); } closegraph(); } Đ4. Văn bản trong đồ hoạ 1. Các fonts : Để chọn fonts chữ ta dùng hàm : void far settextstyle(int font , int direction , int charsize) Các fonts chứa trong các tập tin trong bảng sau Trị Hằng Tập tin 0 DEFAULT_FONT Cài sẵn 1 TRIPLEX_FONT trip.chr 2 SMALL_FONT litt.chr 3 SANSERIF_FONT sans.chr 4 GOTHIC_FONT goth.chr 5 SCRIPT_FONT scrip.chr 6 SIMPLEX_FONT simp.chr 7 TRIPLEX_SCR_FONT tscr.chr 8 COMPLEX_FONT lcom.chr 9 EUROPEAN_FONT euro.chr 10 BOLD_FONT bold.chr Đối direction có thể nhận một trong hai trị : 0 (HORIZ_DIR) - từ trái sang phải 1 (VERT_DIR) - từ trên xuống d−ới Khi đối charsize có trị là 1 , kích th−ớc chữ là nhỏ nhất . Khi kích th−ớc là 2 , chữ sẽ tăng gấp đôi v.v. Để in chuỗi ra màn hình trong chế độ đồ hoạ ta dùng các hàm : void far outtext( char far * string); void far outtextxy(int x , int y , char far *string); Ch−ơng trình 6-16 : Dùng hàm settextstyle() để viết chữ #include #include 73 #define FONTSIZE 4 void main() { int gd,gm; gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); settextstyle(GOTHIC_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,0,"Gothic"); settextstyle(TRIPLEX_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,40,"Triplex"); settextstyle(SMALL_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,80,"Small"); settextstyle(SANS_SERIF_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,100,"Sanserif"); settextstyle(DEFAULT_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,160,"Default"); settextstyle(EUROPEAN_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,200,"Euro"); settextstyle(BOLD_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,240,"Bold"); settextstyle(COMPLEX_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,300,"Complex"); settextstyle(SCRIPT_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,340,"Script"); settextstyle(SIMPLEX_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,370,"Simplex"); settextstyle(TRIPLEX_SCR_FONT,HORIZ_DIR,FONTSIZE); outtextxy(0,420,"Triplex script"); getch(); closegraph(); } 2. Justify và định kích th−ớc văn bản : Hàm định vị trí văn bản là ; void far settextjustify(int horiz , int vert); Đối horiz nhận các biến trong bảng sau Trị Hằng ý nghĩa 0 LEFT_TEXT CP nằm bên trái văn bản 1 CENTER_TEXT CP nằm bên chính giữa văn bản 2 RIGHT_TEXT CP nằm bên phải văn bản Đối vert nhận một trong các giá trị sau : Trị Hằng ý nghĩa 0 BOTTOM_TEXT CP nằm ở đáy văn bản 1 CENTER_TEXT CP nằm bên chính giữa văn bản 2 TOP_TEXT CP nằm ở đỉnh văn bản 74 Ch−ơng trình 6-17 : #include #include #define cl 150 #define lead 40 #define fontsize 3 void main() { int gd,gm,i; gd=DETECT; clrscr(); initgraph(&gd,&gm,"c:\\bc\\bgi"); settextstyle(TRIPLEX_FONT,HORIZ_DIR,fontsize); line(cl,0,cl,200); for (i=0;i<lead*5;i+=lead) line(0,i,300,i); moveto(cl,0); outtext("Default"); moveto(cl,lead); settextjustify(LEFT_TEXT,TOP_TEXT); outtext("Left-top"); moveto(cl,lead*2); settextjustify(RIGHT_TEXT,TOP_TEXT); outtext("Right-top"); moveto(cl,lead*3); settextjustify(CENTER_TEXT,TOP_TEXT); outtext("Center-top"); moveto(cl,lead*4); settextjustify(CENTER_TEXT,BOTTOM_TEXT); outtext("Center-bottom"); getch(); closegraph(); } Để thay đổi kích th−ớc và tỉ lệ chữ ta dùng hàm : void far setusercharsize(int multx , int divx , int multy , int divy); multx - nhân chiều rộng của kí tự divx - chia chiều rộng của kí tự multy - nhân chiều cao của kí tự divx - chia chiều cao của kí tự Ch−ơng trình 6-18 : Tạo một đồ thị có ghi chú #include #include #include #define n 12 #define bwidth 20 #define sep 24 #define shft 30 #define left 5 75 #define depth 6 #define topflag 1 #define bot 300 #define top 5 #define ticks 10 #define twidth 10 #define maxdata 100 #define xtitle 40 #define ytitle 40 #define font SANS_SERIF_FONT #define di (bwidth+sep) #define width (((n+1)*di)) #define pbt ((float)(bot-top)) #define ppd ((float)(bot-top)/maxdata) void main() { int gd,gm,i; float a,b,c,d; int data[n]={41,47,54,62,63,59,75,83,89,96,55,2}; char month[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul", "Aug","Sep","Oct","Nov","Dec"}; char string[40]; clrscr(); gd=DETECT; initgraph(&gd,&gm,"c:\\bc\\bgi"); rectangle(left,top,left+width,bot); setusercharsize(4,3,4,3); settextstyle(font,HORIZ_DIR,0); moveto(xtitle,ytitle); outtext("1998 Sales"); setusercharsize(2,3,2,2); settextstyle(font,HORIZ_DIR,0); for (i=0;i<ticks;i++) { line(left,bot-i*pbt/10,left+twidth,bot-i*pbt/10); line(left+width-twidth,bot-i*pbt/10,left+width,bot-i*pbt/10); moveto(left+width+sep,bot-(i+1)*pbt/10); itoa(i*(maxdata/ticks),string,10); outtext(string); } setusercharsize(2,3,2,2); settextstyle(font,VERT_DIR,0); for (i=0;i<n;i++) { setfillstyle(SOLID_FILL,i); bar3d(left+shft+i*di,bot-data[i]*ppd,left+shft+i*di+bwidth,bot,depth,topflag); moveto(left+i*di+bwidth-1,bot+5); outtext(month[i]); } 76 getch(); closegraph(); } Đ5. Ví dụ kết thúc Ch−ơng trình 6-19 : Lập ch−ơng trình vẽ một mặt Mallbrot #include #include #include #define ymax 400 #define xmax 400 #define maxcount 16 void main() { int gd,gm; int x,y,count; float xscale,yscale; float left,top,xside,yside,zx,zy,cx,cy,tempx; clrscr(); gd=DETECT; initgraph(&gd,&gm,"c:\\bc\\bgi"); left=-2.0; top=1.25; xside=2.5; yside=-2.5; xscale=xside/xmax; yscale=yside/ymax; rectangle(0,0,xmax+1,ymax+1); for (y=1;y<=ymax;y++) { for (x=1;x<=xmax;x++) { cx=x*xscale+left; cy=y*yscale+top; zx=zy=0; count=0; while((zx*zx+zy*zy<4) && (count<maxcount)) { tempx=zx*zx-zy*zy+cx; zy=2*zx*zy+cy; zx=tempx; count++; } putpixel(x,y,count); if (kbhit()) exit(0); } 77 } getch(); closegraph(); }
File đính kèm:
- Giao_Trinh_C_Chuong6.pdf