1、第第5章章 图形界面与动画设计图形界面与动画设计5.1 基本概念5.2 文本屏幕管理5.3 图形系统初始化与关闭5.4 图形模式屏幕管理5.5 基本图形函数5.6 图形模式下的文本输出5.7 动画设计习题5实验5 图形界面程序设计是比较吸引人的部分,Turbo C为用户提供了功能强大的绘图函数库,本章只介绍最常用的一部分,其余的图形函数及用法可参阅相关书籍。图形函数均在头文件graphics.h中定义,所以在程序中调用这些图形函数时,必须在程序文件的开头写上文件包含命令:#include graphics.h,同时将集成开发环境Options/Linker中的Graphics lib选为on(
2、一般默认为on),只有这样才能正确使用图形函数。5.1 基基 本本 概概 念念5.1.1 图形显示与适配器图形显示与适配器PC机的显示系统一般由显示器和适配器组成。显示器(monitor)是独立于主机的一种外部设备。适配器(adapter)也称显卡,是插在PC主机上的一块电路板。PC机对显示屏幕的所有操作都是通过适配器来实现的。显示器屏幕的坐标是一个倒置的直角坐标系,左上角为(0,0),右下角为最大的(x,y)坐标。显示器上的图形是由很多小圆点组成的,这些小圆点称为像素。像素的大小可以通过设置显示器的分辨率来改变,分辨率越大,像素越小,显示的图像越清晰。计算机中要显示的字符和图形均以数字形式存
3、储在存储器中,而显示器接收的是模拟信号。一般显示器有三条RGB的模拟信号输入线,每条输入线的电压决定颜色的亮度。插在PC机插槽中的适配器,其作用就是将要显示的字符和图形以数字形式存储在其视频存储器VRAM中,再将这些数字信号变成视频模拟信号送往相应的显示器进行显示。也就是说,适配器在主机和显示器之间起到了信息转换和发送的作用。不同的显示器对应的适配器的种类也不用,显示器必须配置正确的适配器才能构成完整的显示系统。下面简单介绍几种常用的适配器。(1)单色显示适配器(MDA):仅显示一种颜色,仅支持8025行的字符显示。(2)彩色图形适配器(CGA):可以产生单色及彩色字符和图形,有两种分辨率:一
4、种为高分辨率(CGAHI),分辨率为640200,背景为黑色,前景色虽然可供选择,但只有一种;另一种为中分辨率(320200),前景色和背景色可供用户选择,但只有4种,分别对应4种显示模型CGAC0、CGAC1、CGAC2和CGAC3。(3)增强型图形适配器(EGA):支持CGA的4色显示方式,分为分辨率为640200的EGALO和分辨率为640350的EGAHI,均可显示16色。(4)视频图形阵列适配器(VGA):除支持CGA、EGA的所有方式外,还增加了640480的高分辨率显示方式(VGAHI)、640350的中分辨率显示方式(VGAMED)和640200的低分辨率显示方式(VGALO)
5、,均可提供16种显示颜色。(5)TVGA:目前主流微机的显示器标准,提供640480、800600和1024768等分辨率,颜色可达256种,在文本方式下可支持25、30、43、60行,132列的字符显示,同时向前兼容。由于Turbo C早于该产品出现,因而不支持TVGA增强的几种显示方式。后来的PVGA、XGA及国内研制的带汉字显示功能的CVGA等都可以看做是VGA的扩展。Turbo C支持的适配器见附录D。5.1.2 显示器的工作原理显示器的工作原理PC机的显示适配器有两种工作模式:一种是图形模式;另外一种是文本模式(默认模式)。其主要差别是显示存储器VRAM中存放的信息不同。在文本模式下
6、,VRAM中存放的是要显示的字符的ASCII码,用它作地址,取出字符发生器ROM中存放的相应字符的图像(字模),变成视频信号显示在屏幕上,如图5.1(a)所示。而在图形模式下,要显示的图形直接存放在VRAM中,VRAM不同地址单元存放的数就表示了屏幕某行某列上的像素及颜色,如图5.1(b)所示。图5.1 VRAM中的存储内容与显示模式因此在使用图形函数绘图之前,必须将显示适配器设置为图形模式,这就是通常所说的“图形模式初始化”。在绘图工作完毕之后,又要回到文本模式,以便进行文本模式下的工作。文本模式下将屏幕称为窗口(window),它是屏幕的活动部分,字符输出或显示在活动窗口中进行。窗口在缺省
7、时就是整个屏幕。窗口可以根据需要指定其大小。图形模式下将屏幕称为视口(viewport),也就是说,图形函数的操作都是在视口上进行的。图形视口与字符窗口具有相同的特性,用户可以在屏幕上定义大小不同的视口。若不定义视口大小,它就是整个屏幕。可以看出,窗口是在字符屏幕下的概念,只有字符才能在窗口中显示出来,这时用户可以访问的最小单位为一个字符。视口是在图形屏幕状态下的概念,文本与图形都可以在视口上显示,用户可访问的最小单位是一个像素(像素这一术语最初用来指显示器上最小的、单独的发光点单元,但现在其含义拓宽为图形显示器上的最小可访问点)。字符和图形状态下,屏幕上的位置都是由它们的行与列所决定的。有一
8、点必须指出:字符状态的左上角坐标为(1,1),但图形状态的左上角坐标为(0,0)。了解字符屏幕和图形函数与窗口和视口的关系是很重要的。例如,字符屏幕光标位置函数gotoxy()将光标移到窗口的(x,y)位置上,这未必就是相对于整个屏幕的坐标。5.2 文本屏幕管理文本屏幕管理下面介绍常用的几类字符屏幕函数的功能用途、操作方法及其例行程序。5.2.1 屏幕操作函数屏幕操作函数编写绘图程序经常要用到对字符屏幕进行操作。例如,在往屏幕上写字符之前,首先要将屏幕清除干净。对这些操作,C语言提供了一系列字符屏幕操作函数来实现。以下函数均包含在相应的头文件conio.h中。(1)函数原型:void text
9、mode(int newmode);Turbo C默认定义的文本窗口为整个屏幕,共有80列、25行的文本单元。规定整个屏幕的左上角坐标为(1,1),右下角坐标为(80,25),并规定沿水平方向为x轴,方向朝右;沿垂直方向为y轴,方向朝下。每个单元包括一个字符和一个属性,字符即ASCII码字符,属性规定该字符的颜色和强度。除了这种默认的80列、25行的文本显示方式外,还可由用户通过函数textmode来显式地设置Turbo C支持的5种文本显示方式。该函数将清除屏幕,以整个屏幕为当前窗口,并移动光标到屏幕左上角。newmode参数的取值见表5.1,它既可以是表中指出的方式代码,又可以是符号常量。
10、LASTMODE方式指上一次设置的文本显示方式,它常用于从图形方式到文本方式的切换。表表5.1 文本显示方式文本显示方式(2)函数原型:void clrscr(void);功能:函数clrscr清除整个当前字符窗口,并且把光标定位于左上角(1,1)处。(3)函数原型:void window(int left,int top,int right,int bottom);功能:在指定位置建立一个字符窗口。参数left、top为窗口左上角坐标;right、bottom为其右下角坐标。若有一个坐标是无效的,则window函数不起作用。一旦该函数调用成功,那么所有定位坐标都是相对于窗口的,而不再相对于整
11、个屏幕。但是建立窗口所用的坐标总是相对整个屏幕的绝对坐标,而不是相对当前窗口的相对坐标。这样用户就可以根据各种需要建立多个互不嵌套的窗口。一个屏幕可以定义多个窗口,但当前窗口只能有一个(因为DOS为单任务操作系统)。当需要用另一窗口时,可将定义该窗口的window函数再调用一次,此时该窗口便成为当前窗口了。(4)函数原型:void gotoxy(int x,int y);功能:函数gotoxy将字屏幕上的光标移到当前窗口指定的位置上。x、y是光标定位的坐标,如果其中一个坐标值无效(如坐标超界),那么光标不会移动。此函数在字符状态(有时称为文本状态)下经常用到。【程序程序5.1】设置2个字符窗口
12、。#includeconio.hborder(int startx,int starty,int endx,int endy)register int i;gotoxy(1,1);for(i=0;i=endx-startx;i+)putch(-);gotoxy(1,endy-starty);for(i=0;i=endx-startx;i+)putch(-);for(i=2;i=endy-starty;i+)gotoxy(1,i);putch(|);gotoxy(endx-startx+1,i);putch(|);main()window(6,8,38,12);border(6,8,38,12)
13、;gotoxy(2,2);printf(window 1);window(8,16,40,24);border(8,16,40,24);gotoxy(3,2);printf(window 2);getch();(5)函数原型:void clreol(void);功能:在当前字符窗口中清除从光标位置到行尾的所有字符,而光标位置保持不变。(6)函数原型:void insline(void);功能:插入一空行到当前光标所在行上,同时光标以下的所有行都向下顺移一行。(7)函数原型:void delline(void);功能:删除当前窗口内光标所在行,同时把该行下面的所有行都上移一行。如果当前窗口小于整
14、个屏幕,那么该函数只影响到窗口内的字符。5.2.2 文本操作函数文本操作函数1.文本输出文本输出我们熟悉的printf()、putc()、puts()、putchar()等输出函数是以整个屏幕为窗口的,它们不受window 设置的限制,因此也就无法用函数控制它们输出的位置。但Turbo C提供了三个文本输出函数,它们受window的控制,窗口内显示光标的位置,就是它们开始输出的位置。当输出行右边超过窗口右边界时,自动移到窗口内的下一行开始输出,当输出到窗口底部边界时,窗口内的内容将自动产生上卷,直到完全输出完为止。这三个函数均受当前光标的控制,每输出一个字符光标,就后移一个字符位置。窗口内文本
15、的输出函数有以下3个:(1)函数原型:int cprintf(,);功能:输出一个格式化的字符串或数值到窗口当前光标处。它与printf()的用法完全一样。区别在于cprintf()的输出受窗口限制,而printf()的输出为整个屏幕。(2)函数原型:int cputs(char*string);功能:输出一个字符串到窗口当前光标处,它与puts()的用法完全一样,只是受窗口大小的限制。(3)函数原型:int putch(int ch);功能:输出一个字符到当前光标处。使用以上几个函数后,当输出超出窗口的右边界时会自动转到下一行的开始处继续输出;当窗口内填满内容但仍没有结束输出时,窗口屏幕将会
16、自动逐行上卷直到输出结束为止。2.文本输入文本输入可直接使用stdio.h 中的getch或getche函数进行文本输入。需要指出的是,getche函数从键盘上获得一个字并在屏幕上显示的时候,如果字符超过了窗口右边界,则会被自动转移到下一行的开始位置。3.文本拷贝文本拷贝(1)函数原型:int movetext(int x1,int y1,int x2,int y2,int x3,int y3);功能:将屏幕左上角为(x1,y1)、右下角为(x2,y2)的矩形内文本拷贝到左上角为(x3,y3)的一个新矩形区内。注意,这里的坐标是以整个屏幕为窗口坐标系的,即屏幕左上角为(1,1)。该函数与开设的
17、窗口无关,且原矩形区文本不变。(2)函数原型:函数原型:int gettext(int x1,int y1,int x2,int y2,void*buffer);功能:将左上角为(x1,y1)、右下角为(x2,y2)的屏幕矩形区内的文本存到由指针buffer指向的一个内存缓冲区内。当操作成功时返回1,不成功时返回0。因为一个在屏幕上显示的字符需占显示存储器VRAM的两个字节,即第一个字节是该字符的ASCII码,第二个字节为属性字节,即表示其显示的前景、背景色及是否闪烁,所以显示的字符所占的由buffer 指向的内存缓冲区的字节总数为:字节总数=矩形内行数每行列数2其中:矩形内行数=y2-y1+
18、1,每行列数=x2-x1+1(每行列数是指矩形内每行的列数)。矩形内文本字符在缓冲区内存放的次序是从左到右,从上到下,每个字符占连续两个字节并依次存放。(3)函数原型:int puttext(int x1,int y1,int x2,int y2,void*buffer);功能:将由gettext()存入内存buffer 中的文字内容拷贝到屏幕上指定的位置。注意:(1)gettext()和puttext()中的坐标是对整个屏幕而言的,即是屏幕的绝对坐标,而不是相对窗口的坐标。(2)movetext()是拷贝而不是移动窗口区域的内容,即使用该函数后,原位置区域的文本内容仍然存在。【程序程序5.2
19、】文本操作示例。#include conio.hborder(int startx,int starty,int endx,int endy)/*输出一个边界*/register int i;gotoxy(startx-1,starty-1);for(i=0;i=endx-startx;i+)putch(-);gotoxy(startx-1,endy+1);for(i=0;i=endx-startx;i+)putch(-);for(i=0;i=endy-starty;i+)gotoxy(startx-1,starty+i);putch(|);gotoxy(endx+1,starty+i);pu
20、tch(|);main()int i;char ch3*10*2;/*定义ch字符串数组作为缓存区*/textbackground(BLUE);textcolor(WHITE);clrscr();/*输出2行文本*/gotoxy(10,10);cprintf(text demo);gotoxy(10,11);cprintf(Press any key to continue);getch();gettext(10,10,20,11,ch);/*将矩形区文本存到ch缓存区*/border(10,10,35,11);getch();movetext(10,10,20,11,40,15);/*将矩形
21、区文本移动到另外一个矩形区*/border(40,15,50,16);getch();puttext(60,10,70,11,ch);/*将ch缓冲区的内容输出到一个矩形区*/border(60,10,70,11);getch();5.2.3 字符属性函数字符属性函数用户可以设置字符显示为高亮度还是低亮度,是否闪烁,以及其背景颜色等。具有这些操作的函数称为字符属性函数。除了仅支持单模式和单色的显示卡外,字符属性函数适用于其余所有的显示卡。以下介绍几种字符属性函数。(1)函数原型:void textcolor(int color);功能:设置字符屏幕下的文本颜色(或字符颜色),还可使字符闪烁。c
22、olor的有效值可取表5.2中的颜色名(即宏名)或数值。在文本模式下,还有一个BLINK值,其宏值为128,表示闪烁。textcolor函数执行后,只影响其后输出的字符颜色,而不改变已经在当前屏幕上的其他字符颜色。显然,如果需要输出的字符闪烁,只要将函数中的参数color取为BLINK即可。如果要使字符带颜色闪烁,就必须将所选的颜色值与128作“或”运算或进行相加。如:textcolor(BLINK);/*输出的字符闪烁*/printf(hello);textcolor(RED|BLINK);/*输出为红色同时闪烁,或写为textcolor(BLINK+RED);*/(2)函数原型:void
23、textbackground(int bcolor);功能:设置字符屏幕下文本的背景颜色。参数bcolor的有效值取表5.2中的07。调用该函数只影响其后输出的字符背景颜色,而不改变当前显示在屏幕上的字符背景颜色。(3)函数原型:void textattr(int attr);功能:可同时设置文本字符的颜色和背景色。其中参数attr的值表示颜色编码,每位的具体含义如图5.2所示。图5.2 attr值的含义该字节的低四位表示字符颜色,46位表示背景颜色,第7位设置字符是否闪烁。比如要将文本字符设置成蓝底白字,定义方法如下:textattr(BLUE+(WHITE4);若再要求字符闪烁,定义变为:
24、textattr(128+BLUE+(WHITE4);【程序程序5.3】闪烁字符。#include conio.hmain()textbackground(GREEN);textcolor(YELLOW);clrscr();cprintf(Hi,how do you do!);textcolor(BLINK);/*输出的字符闪烁*/gotoxy(20,20);cprintf(hello);textcolor(RED|BLINK);/*输出为红色同时闪烁*/gotoxy(50,50);cprintf(nwu);getch();注意:(1)对于背景色只有07共8种颜色,取大于7的数,则该数代表的颜
25、色与将该数对7取余后的值对应的颜色相同。(2)用textbackground()和textcolor()设置了窗口的背景与字符颜色后,在没有用clrscr()清除窗口之前,颜色不会改变,直到使用了函数clrscr(),整个窗口和随后输出到窗口中的文本字符才会变成新颜色。(3)用textattr()函数设置文本字符颜色和背景颜色时,背景颜色应左移4位,才能使之移到正确位置。【程序程序5.4】定义多个文本窗口。#include#include main()int i;textbackground(BLUE);clrscr();/*清屏后,背景颜色才能发生变化*/for(i=1;i8;i+)wind
26、ow(10+i*5,5+i,30+i*5,15+i);/*定义文本窗口*/textbackground(i);/*定义该窗口背景色*/clrscr();window(10+3*5,5+3,30+3*5,15+3);/*让第3个窗口为当前窗口*/getch();5.2.4 屏幕状态函数屏幕状态函数有时需要知道当前屏幕的显示方式,比如当前窗口的坐标、当前光标的位置、文本的显示属性等,C 提供了一些函数来获取这些信息。(1)函数原型:void gettextinfo(struct text_info*f);功能:获取当前屏幕的显示方式。这里的text_info 是在conio.h 头文件中定义的一个
27、结构,该结构的定义是:structtext_info(unsigned char winleft;/*当前窗口左上角x 坐标*/unsigned char wintop;/*当前窗口左上角y 坐标*/unsigned char winright;/*当前窗口右下角x 坐标*/unsigned char winbottom;/*当前窗口右下角y 坐标*/unsigned char attributes;/*文本属性*/unsigned char normattr;/*通常属性*/unsigned char currmode;/*当前文本方式*/unsigned char screenheight
28、;/*屏高*/unsigned char screenwidth;/*屏宽*/unsigned char curx;/*当前光标的x值*/unsigned char cury;/*当前光标的y值*/;通过下面两个函数可直接获取当前光标位置:(2)函数原型:int wherex(void);功能:返回当前窗口中光标处的横坐标。(3)函数原型:int wherey(void);功能:返回当前窗口中光标处的纵坐标。例如:int xpos,ypos;xpos=wherex();ypos=wherey();【程序程序5.5】获取当前屏幕属性。#include main()struct text_info
29、 current;textbackground(BLUE);/*设置屏幕背景颜色*/clrscr();window(1,1,60,20);textbackground(YELLOW);/*设置第一个窗口背景色*/clrscr();window(62,1,79,10);/*设置第二个窗口背景色*/textbackground(GREEN);clrscr();window(1,1,60,20);/*使第一个窗口成为当前窗口*/cputs(Current information of windowrn);gettextinfo(¤t);cprintf(Left corner of win
30、dow is%d,%drn,current.winleft,current.wintop);cprintf(Right corner of window is%d,%drn,current.winright,current.winbottom);cprintf(Text window attribute is%drn,current.attribute);cprintf(Text window normal attribute is%drn,current.normattr);cprintf(Current video mode is%drn,current.currmode);cprintf
31、(Window height and width is%d,%drn,current.screenheight,current.screenwidth);cprintf(Row cursor pos is%d,Column pos is%drn,current.cury,current.curx);getch();执行结果如图5.3所示。图5.3 执行结果5.3 图形系统初始化与关闭图形系统初始化与关闭5.3.1 图形系统初始化图形系统初始化图形模式初始化是通过函数initgraph()来完成的。其函数原型为:void initgraph(int*gdriver,int*gmode,char*
32、path);功能:通过从磁盘上装入一个图形驱动程序来初始化图形系统,并将系统设置为图形模式。各参数的含义分别为:gdriver用来指定要装入的图形驱动程序,是一个枚举变量,在graphics.h中,即:enum graphics_driverDETECT,CGA,MCGA,EGA,EGA64,EGAMONO,IBM8514,HERC,ATT400,VGA,PC3270;图形驱动程序由Turbo C出版商提供,文件扩展名为.BGI。根据不同的图形适配器有不同的图形驱动程序。例如对于EGA、VGA,图形适配器就调用驱动程序 EGAVGA.BGI。gmode用来设置图形显示模式。不同的图形驱动程序有
33、不同的图形显示模式,即使是在同一个图形驱动程序下,也可能会有几种图形显示模式。图形显示模式决定了显示的分辨率、可同时显示的颜色的多少、调色板的设置方式以及存储图形的页数。path是一个字符串,用来指明图形驱动程序所在的路径。如果驱动程序就在用户当前目录下,则该参数可以为空字符串,否则应给出具体的路径名。以上介绍了initgraph函数中的 3个参数的含义。注意,前2个参数实际上是整型指针,调用时应加上地址运算符“”。(图形驱动器模式的符号常数及数值见附录D。)【程序程序5.6】使用图形初始化函数设置VGA高分辨率图形模式。#include main()int gdriver,gmode;gdr
34、iver=VGA;gmode=VGAHI;initgraph(&gdriver,&gmode,c:tc);bar3d(100,100,300,250,50,1);/*画一长方体*/getch();/*这一句很重要,否则在关闭图形模式后,绘制的图形将消失*/closegraph();/*关闭图形模式*/有时编程者并不知道所用的图形显示适配器的种类,或者需要将编写的程序用于不同图形驱动器,为此,Turbo C提供了一个自动检测显示器硬件的函数,其调用格式为:void detectgraph(int*gdriver,*gmode);其中,gdriver和gmode的意义与initgraph函数中的相
35、同。【程序程序5.7】用函数进行硬件测试后再进行图形模式初始化。#include main()int gdriver,gmode;detectgraph(&gdriver,&gmode);/*自动测试硬件*/printf(the graphics driver is%d,mode is%dn,gdriver,gmode);/*输出测试结果*/getch();initgraph(&gdriver,&gmode,c:tc);/*根据测试结果初始化图形模型*/bar3d(10,10,130,250,20,1);getch();closegraph();程序5.7先对图形显示器自动检测,然后再用图形初
36、始化函数进行初始化设置。Turbo C提供了一种更简单的方法,即在gdriver=DETECT语句后再使用initgraph()函数就行了。此时,系统自动检测图形适配器的最高分辨率模式,并装入相应的图形驱动程序。采用这种方法后,初始化图形模式变得更加简单,见程序5.8。【程序程序5.8】自动检测并初始化图形模式。#include main()int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,c:tc);bar3d(50,50,150,30,1);getch();closegraph();使用DETECT模式,由系统自动对硬件进行检测,并把图形
37、显示模式设置为检测到的驱动程序的最高分辨率。5.3.2 独立图形运行程序的建立独立图形运行程序的建立用initgraph函数直接进行的图形初始化程序,在编译和连接时并没有将相应的驱动程序(*.BGI)装入到执行程序中,只有当程序执行到intitgraph()语句时,才从该函数中第三个形式参数char*path中所规定的路径中去找相应的驱动程序。若没有驱动程序,则在C:TC中去找,如C:TC中仍没有或TC不存在,将会出现错误提示:BGI Error:Graphics not initialized(use initgraph)因此,为了使用方便,应该建立一个不需要驱动程序就能独立运行的可执行图形
38、程序,其步骤为(这里以EGA、VGA显示器为例):(1)在C:TC子目录下输入命令:BGIOBJ EGAVGA。此命令将驱动程序EGAVGA.BGI转换成EGAVGA.OBJ的目标文件。(2)在C:TC子目录下输入命令:TLIB LIBGRAPHICS.LIB+EGAVGA。此命令的意思是将EGAVGA.OBJ的目标模块装到GRAPHICS.LIB库文件中。(3)在程序中调用initgraph函数之前加上一句:registerbgidriver(EGAVGA_driver);该函数告诉连接程序在连接时把EGAVGA的驱动程序装入到用户的执行程序中。经过上面的处理后,编译、连接后的执行程序可在任
39、何目录或其他兼容机上运行。【程序程序5.9】独立图形运行程序的建立。#include main()int gdriver=DETECT,gmode;registerbgidriver(EGAVGA_driver):/*建立独立图形运行程序*/initgraph(&gdriver,&gmode,c:tc);bar3d(50,50,250,150,20,1);getch();closegraph();该程序经编译、连接后产生的执行程序可独立运行。如不初始化成EGA或CGA分辨率,而想初始化为CGA分辨率,则只需要将上述步骤和程序中有EGAVGA的地方用CGA代替即可。5.3.3 关闭图形模式关闭图
40、形模式 在绘图结束后,要回到文本模式,以进行其他工作,这时应关闭图形模式。关闭图形模式的函数原型为:void closegraph(void);功能:释放所有图形系统分配的存储区,恢复到调用initgraph()之前的状态。5.4 图形模式屏幕管理图形模式屏幕管理C提供了多个函数用于对屏幕和视图区等进行控制管理。5.4.1 设置视图区设置视图区在图形模式下,在屏幕上定义一个视图区(视图区相当于一个用于绘图的窗口)时,视图区的位置用屏幕绝对坐标定义,并且可以把视图区设置为剪裁和不剪裁两种状态。函数原型:void setviewport(int xl,int y1,int x2,int y2,in
41、t c);其中:(x1,y1)为视图区的左上角坐标,(x2,y2)为视图区的右下角坐标,c为裁剪状态参数。当c1时,超出视图区的图形部分会被自动裁剪掉;当c0时,对超出视图区的图形不作裁剪处理。注意:(1)视图区建立以后,所有的图形输出坐标都是相对于当前视图区的,即视图区左上角为(0,0)点,而与图形在屏幕上的位置无关。(2)使用图视口设置函数setviewport,可以在屏上设置不同的图视口窗口,甚至多个窗口可以部分重叠,但是只有最后一次设置的窗口才是当前窗口,后面的图形操作都视为在此窗口中进行。若不清除那些窗口的内容,则它们仍在屏上保持,当要对它们中的某一个进行处理时,可再一次设置那个窗口
42、一次,这样它就又变成当前窗口了。5.4.2 清除视图区清除视图区函数原型:void clearviewport();功能:清除掉当前的视图区,将当前点位置设置于屏幕左上角(0,0)点处。执行后,原先设置的视图区将不复存在。5.4.3 清屏清屏函数原型:void cleardevice();功能:立即清除全屏幕内容,并将当前点位置设置为原点(0,0),但是不改变其他的图形系统设置,如线型、填充模式等;如果设置了视图区,则视图区的设置不变,当前点位置仍设置在视图区的左上角。【程序程序5.10】视图区管理。#include main()int gdriver=DETECT,gmode,i;initg
43、raph(&gdriver,&gmode,c:tc);setviewport(0,0,200,200,1);for(i=0;i100;i+)cleardevice();rectangle(0,0,100+i,100+i);sleep(10000);cleardevice();clearviewport();setviewport(200,200,400,400,0);for(i=0;i100;i+)cleardevice();circle(100,100,50);sleep(10000);getch();closegraph();5.5 基本图形函数基本图形函数绘图函数是进行图形操作的基础。用
44、像素点几乎可以画出任何图形,但效率太低。为此C提供了大量的基本绘图函数,以方便使用图形设计。在使用绘图函数时,要随时注意画图的“当前点位置”,它是绘图的起始位置。也就是说,图形总是从当前点开始画。画完一个图形后,有时当前点的位置不变,仍在原来的位置;有时则要把当前点移到新的位置。此外,为了从指定位置开始作图,有时需要先改变当前点位置,然后再作图。在调用绘图函数的时候要注意这些问题。基本图形函数包括画点、线以及其他一些基本图形的函数。5.5.1 图形属性控制图形属性控制图形的属性控制包括控制颜色和线型。颜色有背景色和前景色之分。背景色指屏幕的颜色(即绘图时的底色),前景色指绘图时图形线条所用的颜
45、色。任何绘图函数都是在当前的颜色(包括背景色和前景色)和线型状态下进行绘图的。前面所举的例子没有提到当前的颜色和线型,是因为用了系统的默认值(系统的默认值是:背景色为黑色,前景色为白色,线型为一点宽实线)。如果绘制时要使用系统默认值以外的颜色和线型,则应利用图形属性控制函数另行设置。1.颜色设置颜色设置设置背景色:void setbkcolor(int color);设置作图色:void setcolor(int color);color值如表5.2所示。【程序程序5.11】有关颜色设置的使用。#include main()int gdriver=DETECT,gmode,i;initgrap
46、h(&gdriver,&gmode,);/*图形初始化*/setbkcolor(GREEN);/*设置图形背景*/for(i=0;i=15;i+)setcolor(i);/*设置不同作图色*/circle(320,240,20+i*10);/*画半径不同的圆*/delay(100);/*延迟100ms*/for(i=0;i=15;i+)setbkcolor(i);/*设置不同背景色*/cleardevice();circle(320,240,20+i*10);delay(100);getch();closegraph();注意:使用setbkcolor()设置背景色时,它对整个屏幕背景起作用,
47、而不是只改变当前视口内的背景;在用setcolor()设置前景色时,它对当前视口起作用。若下一次设置视口时没有设置颜色,那么上次在另一视口内设置的颜色在本次设置的视口内仍起作用。2.线型设置线型设置在没有对线型进行设定之前,使用其默认值,即一点宽的实线。但C也提供了可以改变线型的函数。线型包括宽度和形状。其中宽度只有两种选择:一点宽和三点宽(见表5.3),而线的形状则有五种(见表5.4)。表表5.3 有关线宽有关线宽(thickness)表表5.4 有关线的形状有关线的形状(linestyle)设置线型函数:void setlinestyle(int linestyle,unsigned up
48、attern,int thickness);其中,linestyle是线的形状,见表5.4;thickness是线的宽度,见表5.3;对于upattern,只有linestyle选USERBIT_LINE 时才有意义(选其他线型时,uppattern取0即可)。此时uppattern的16位二进制数的每一位代表一个像素,如果该位为1,则该像素打开,否则该像素关闭。5.5.2 画点类函数画点类函数1.画点函数画点函数函数原型:void putpixel(int x,int y,int color);功能:在坐标(x,y)处画一个颜色为color的像素。在图形模式下,是按像素来定义坐标的。对于VG
49、A适配器,它的最高分辨率为640480,其中640为整个屏幕从左到右所有像素的个数,480为整个屏幕从上到下所有像素的个数。屏幕的左上角坐标为(0,0),右下角坐标为(639,479),水平方向从左到右为x轴正向,垂直方向从上到下为y轴正向。TURBO C的图形函数都是相对于图形屏幕坐标,即像素来说的。对于颜色color的值可从表5.2中获得。对应于函数putpixel()的一个函数是:int getpixel(int x,int y);功能:获得当前点(x,y)的颜色值,获得的颜色值作为返回值传回。【程序程序5.12】采用点函数来画线。#include main()int gdriver=D
50、ETECT,gmode,i;initgraph(&gdriver,&gmode,c:tc);for(i=0;i100;i+)putpixel(100+i,100+i,WHITE);getch();closegraph();2.有关点位置的其他函数有关点位置的其他函数(1)函数原型:int getmaxx();功能:返回x轴的最大值。(2)函数原型:int getmaxy();功能:返回y轴的最大值。(3)函数原型:int getx();功能:返回当前点在x轴的位置。(4)函数原型:int gety();功能:返回当前点在y轴的位置。(5)函数原型:void moveto(int x,int y