null计算机图形学计算机图形学C语言图形程序
基础第三章C语言图形程序设计基础
第三章C语言图形程序设计基础
3.1屏幕显示模式和坐标系
1.文本模式:
DEF在屏模上只能显示文本的显示模式
历史原因
Turbo C的默认的显示模式是文本模式。
2.图形模式和点坐标
图形模式:
DEF在屏幕上显示图形的方式,称为图形模式。
点坐标:屏幕是由像素点组成的,在图形模式下,屏幕上每个像素的显示位置用点坐标来描述。null例:一个分辨率为800*600的分辨率的显示屏(800列,600行)在图形模式下,以屏幕的左上角为坐标原点(0,0)水平方向为x轴,垂直方向为y轴null3.图形系统的初始化
一个简单的图形程序
#include “graphics.h” // 图形函数库
#include “stdio.h” //标准输入输出函数库
#include “conio.h” //控制台输入输出
main()
{
int gdriver,gmode;
detectgraph(&gdriver,&gmode) ;
if(gdriver<0)
exit(1) ;
initgraph(&gdriver,&gmode,"C:\\TURBOC2") ;
初始化图形系统null bar3d(100,200,300,400,10,1) ;
getch();
closegraph();
}
如何实现图形模式初始化?
initgraph(int *gdriver,int *gmode,char *path)
作用:初始化图形系统,从磁盘装入一个
图形驱动程序并设置图形显示模式。图形程序关闭图形系统nullVoid far detectgraph(int *gdriver,int *gmode)
作用:硬件检测,该函数用来检测图形适配器的类型。
关闭图形系统
Void far closegraph()
作用:关闭图形系统,释放图形驱动程序所占的内存空间,使系统返回到文本模式。
null3.2常用绘图函数简介
1.图形视口函数
-setviewport(left,top,right,bottom,clip)
Clip:如果clip=1则超出视口的图形自动剪裁
例: setviewport(100,100,300,300,1)
-clearviewport()
作用:清除图形视口中的图形
-getviewsetting(struct * info)
作用:返回当前视口的绝对坐标及剪裁标志。
问题:info该如何定义?nullmain()[运行viewport.c]
{ struct viewporttype info;
int gdriver=DETECT ,gmode;
initgraph(&gdriver,&gmode,"C:\\tc3\\BGI");
setcolor(4);//红色
setviewport(100,100,200,200,1);//将
clip=0结果如何?
circle(60,60,60);
getviewsettings(&info);
rectangle(0,0,info.right-info.left,info.bottom- info.top);
getch();
clearviewport();
getch(); closegraph();
}问题1:程序运行结果?如果该为circle(50,50,20)结果如何?如果将circle(60,60,60)前移一行结果?null2屏幕位置函数
-getmaxx()
作用:返回当前图形模式下最大x坐标
-getmaxy()
作用:返回当前图形模式下最大x坐标
Getx()
作用:返回图形模式下当前位置的x坐标
Gety()
作用:返回图形模式下当前位置的x坐标
null- moveto(int x ,int y)
作用:将当前位置移到(x,y)
例:moveto(10,20)
- moverel(int deltax,int deltay)
作用:相对移动函数
说明:deltax和deltay。表示相对移动位置
问题:刚才使用moveto(10,20)将光标定位在(10,20)上,即CP=(10,20)。如果现在调用 moverel(-5,10)光标将在何处?
null 3.直线和线型函数
-line(int x1,int y1,int x2,int y2)
作用:-在指定的两点之间画直线
说明:当前光标依然在(x1,y1)
lineto(int x,int y)
-作用:从当前光标位置到(x,y)之间画一条直线
-linerel(int deltax,int deltay)
作用:从当前坐标以相对增量方式画直线
问题2:如果 CP(10,20) ; linerel(70,80)
应在哪两点之间画直线?null阅读程序,写出程序运行结果
例:#include "graphics.h"
#include "stdio.h"
main()
{
int cp_x, cp_y;
int gdriver=DETECT ,gmode; initgraph(&gdriver,&gmode,"C:\\TURBOC2");
moveto(5,10);
line(5,10,100,50);
cp_x=getx();
cp_y=gety();
nullprintf("the cp_x cp_y are %d %d",cp_x,cp_y);
printf("\n") ; //回车
getch() ;
moveto(100,50);
lineto(100,100);
cp_x=getx();
cp_y=gety();
printf("the cp_x cp_y is %d %d",cp_x,cp_y) ;//
getch();
linerel(50,50);
getch();
}
null-setlinestyle(int style, int pattern ,int width)
作用:设置线型特征(P65)
style参数:用来定义所画直线的类型
Width参数:用来指定所画直线的粗细
pattern参数:只有style=4(用户自定义)可用来表示用户字定义的线型。一般情况pattern=0
例:Setlinestyle(DOTTEN-LINE , 0 , 1)null线性代码说明
线宽null例:setlinestyle(SOLID-LINE , 0, 1)
setlinestyle(4 , 0xAAAA, 1)
1100 1100 1100 1100
1111 1111 1111 1111
pattern参数是16位二进制码,1:有像素用前景色点显示;0:没有像素用背景色点表示。
nullvoid draw_line()
{int i;
for(i=0;i<4;i++)
{ setlinestyle(i,0,NORM_WIDTH);
line(40,10*(i+1),100,10*(i+1));
setlinestyle(i,0,THICK_WIDTH);
line(40,10*(i+1),100,10*(i+1));
}
setlinestyle(4,0x99cc,THICK_WIDTH);
line(40,50,100,50) ;
setlinestyle (4,0xABCD,THICK_WIDTH);
line(40,60,100,60) ;
}
null-Setwritemode(int mode)
作用:设置画线的输出模式
mode=COPY_PUT(0)
新画的线将覆盖屏幕上原有的图像
mode=XOR_PUT(1)
新画的线与旧线作异或,然后再向屏幕输出null例:
Midx=getmaxx()/2
Midy=getmay()/2
Setwritemode(XOR_PUT)
Line(0,midy,midx,midy)
Line(midx/2,midy,midx*3/2,midy)
Setwritemode(COPY_PUT)
Line(0,midy/2,midx,midy/2);
Line(midx/2,midy/2,midx*3/2,midy/2)
null程序设计:
利用C语言设计一程序实现下图所示的二维平面时钟的绘制。设计出一个时针分针
能够协调旋转的的时钟[new_clock]
-Setwritemode(int mode)
作用:设置画线的输出模式
如果mode=COPY_PUT(0)
新画的线将覆盖屏幕上原有的图像
mode=XOR_PUT(1)
新画的线与旧线作异或,然后再向屏幕输出
设计出一个时针分针
能够协调旋转的的时钟[new_clock]
-Setwritemode(int mode)
作用:设置画线的输出模式
如果mode=COPY_PUT(0)
新画的线将覆盖屏幕上原有的图像
mode=XOR_PUT(1)
新画的线与旧线作异或,然后再向屏幕输出
null setwritemode(XOR_PUT); /* 设置写模式为异或 */
th1=0, th2=0,
while(!kbhit()) { /*判断是否按下某键*/
setcolor(RED) ;
line(x,y,x+0.8*radius*cos(th1),y-0.8*radius*sin(th1));(分针)
setcolor(BLUE);
line(x,y,x+0.6*radius*cos(th2),y-0.6*radius*sin(th2) );(时针)
delay(1000); setcolor(RED) ;
line(x,y,x+ 0.8*radius*cos(th1), y-0.8*radius*sin(th1) ) ;
setcolor(BLUE);
line(x,y,x+0.6*radius*cos(th2), y-0.6*radius*sin(th2) ) ;
th1 += 2*PI/(60*60); th2+-= 2*PI/(12*60*60);
if (th1<=0) th1+=2*PI;
if (th2<=0) th2+=2*PI;
}null例:抛物线的绘制
1.数学模型的分析
标准方程:
Y=X2/(4p)
曲线以F(0,p)为焦点,曲线以Y轴为对称轴,其X的取值范围是任意的。null由此,可将上式离散化
其中:i=-m,-(m-1),……0,1,……m;
dx:曲线沿x方向的等距离。null2.图形绘制范围
X的定义域为整个定义域
实际上X的取值范围
后图形区域大小限制
设图形区域:长X=L,高:Y=H(0,0)Y=X2/(4p)null曲线1的X的取值范围
x1<=x<=x2
x1 =-L/2,
x2=L/2
曲线2 x的范围
X1<=X<=X2
X1=-sqrt(H/2 *4p)
X2=sqrt(H/2*4p)Y=X2/(4p)null X=sqr(2p*H)null(1)将[x1,x2] 进行n等分
(n为偶数)
(2)每等分的大小为dx
dx= |x2-x1|/n
m=n/2
(3)已知离散点的中点是(0,0)点则
离散点依次是
-m,-(m-1), …,0,1,2,…(m-1),m
nullFor(i= -m ;i<=m;i++)
x=i*dx
y=(i*dx)*(i*dx)/(4*p)
数学坐标
(i*dx, (i*dx)*(i*dx)/(4*p))
是否就此结束了?
坐标转换坐标转换(Xc,Yc)(0,0) X’+Y’+X+Y+(x,y)null流程图: Y=X2/4p 计算数学坐标转换为屏幕
坐标输出null圆弧类函数
-arc(int x,int y,int startangle,int endangle,int radius)
作用:画圆弧
例:arc(100,100,0,360,50)
arc(100,100,0,180,30)
circle(int x,int y,int radius)
作用:画圆
-ellipse(int x,int y,int start,int end ,int xradius,int yradius)
作用:画椭圆
说明:以(x,y)为圆心,长半轴为xradius ,短半轴为yradius
起始角度为start ,终止角度为endnull-Pieslice(int x,int y int startangle,int endangle,int radius)
作用:画扇形
例:void draw_slice
{int start,end;
start=0,end=45;
For (i=0 ;i< 8;i++)
{setfillstyle(SOLID_FILL,i);
pieslice(260,200,start,end,100);
start+=45;
end+=45;
}
Getch();
}
null5多边形类函数
rectangle(int left,int top,int right,int bottom)
作用:画矩形
例: rectangle(200,100,500,400)
drawpoly(int numpoints, int *polypoints)
作用:画多边形
说明:用当前画笔颜色画一个多边形,多边形的点数为numpoints,*polypoints指向一个整型数组,共有numpoints*2个整数,每一对整数给出了一个多边形顶点(x,y)的坐标。
例:int matrix[10]={10,20,20,60,30,50,20,40,15,20}
Drawpoly(5,matrix)null注意:划封闭的多边形,定点数目必须等于n+1
且最后一点的坐标必须等于第一个点的坐标
例:
main()
{static int polypoints1[8]
={100,100,200,100,200,200,100,200}
Static int polypoints2[10]= ={100,100,200,100,200,200,100,200,100,100}
drawpoly(4,polypoints1);
Drawpoly(5,polypoints2);
}
null6图形颜色的设置
void far setbkcolor(int color)
-设置当前背景颜色 (p60表3.3)
例: setbkcolor(BLACK)
void far setcolor(int color)
-设置当前画笔颜色
例:setcolor(GREEN)
null例:在浅红色的背景色画布上画一黄色的圆。
#include “graphics.h”
#include “conio.h”
void main( )
{
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode, “c:\\TC” );
setbkcolor(LIGHTRED);
setcolor(YELLOW);
circle(100,100,50);
getch();
closegraph() ;
}nullnull7图形的填充[柱状统计图、圆饼图]
SOLID_FILLnull-Setfillstyle ( int pattern, int color)
作用:设置当前的填充模式和填充颜色p(67)
填充模式代号
null例:setfillstyle(4,RED)
Bar(100,200,150,300)
null-Floodfill(int x,int y,int border)
作用:蔓延填充,以(x,y)为填充起点,border指定填充区域边界所使用的颜色
例:setcolor(4) ;
circle (100,100,80);
setfillstyle(SLASHFILL,2)
floodfill(100,100,4)
null//(周二上到这里)
8填充类画图函数:
Bar(int left,int top,int right,int bottom)
作用:画出一个指定左上上角和右下角的实心条形。
Bar3d(int left,int top,int right,int bottom,int depth,int topflag)
作用:画一三维矩形条,使用setfillstyle()设置填充颜色和填充模式。Depth 给出矩形条的深度。Topflag=0时不加顶盖,非零时加一顶盖
null例:
setfillstyle(SOLID_FILL,GREEN);
Bar(60,80,220,160)
Setfillstyle(SOLID_FILL,RED);
Bar3d(260,180,360,240,20,1)
null-fillpoly(int numpoints, int *polypoints)
作用:画一顶点数为numpoints的多边形,多边形的顶点坐标存放在数组polypoints[]中,用
Setfillstyle ()设置填充模式
null图形模式下文本的处理
null9.图形模式下文本的处理
-outtext(char*textstring)
作用:将当前位置上输出一字符串,
参数textstring为文本字符串
例:outtext(“hello wellcom to study CG”)
-outtexxy(int x,int y,char *textstring)
作用:在指定位置(x,y)输出一字符串
例:outtext(100,150, “I am a teacher”)null-Settextstyle(int font ,int direction,int charize)
作用:设置文本当前字体,文本显示方向
以及字符的大小。
说明font:文本字体参数; direction: 文本显示方向参数
charize: 字体大小参数(1-10)
例:main(){
int driver =DETECT,mode;
initgraph(&driver,&mode,"c:\\turboc");
outtextxy(100,100,"normal") ;
settextstyle(GOTHIC_FONT,HORIZ_DIR,5);
outtextxy(100,200,"gothic");
getch(); closegraph();
}null程序设计:画出下图的饼状图[p_new_pie]
某公司上半年产品销售状况是:计算机50%、打印机20%、绘图机10%图形扫描仪5%、打印纸10%、硬盘销售5%。试画出下图所示的饼状图。分析:
Percent[5]
Text[5]
Fillstyle[5]
null饼图流程图:[pie]10象素函数10象素函数-putpixel(int x,int y,int color)
作用:在图形模式下,屏幕上显示一个象素点
例:putpixel(6,8,RED)
-getpixel(int x,int y)
作用:返回一个象素点色彩值
例:color=getpixel(8,6)null10图形存取处理
原理:把屏幕上某个区域的信息存入缓存区,然后再另一个区域将图像重新显示。
(这是图形动画的基础)
[car]
-检测内存
-imagesize(int x1,int y1,int x2,int y2);
函数作用:获得屏幕保存左上角为(x1,y1),右上角为(x2,y2)的矩形屏幕区域所需的内存字节数。
例: unsigned size;
size=imagesize(520,220,630,270)nullvoid * bitmap
bitmap =malloc(size)
作用:分配存储图像的内存
-getimage(int x1,int y1,int x2,int y2,void *bitmap)
作用:将指定屏幕(x1,y1)和(x2,y2)区域的图形拷贝到内存中。屏幕区域保存在bitmap指定的数组中
null例:unsigned size; //屏幕区域的大小
size=imagesize(10,10,100,100) ;
//获得屏幕区域的大小并且将 获得的值放入变量size中
w=malloc(size);
//分配大小为size的内存空间,指针w指向该数组
getimage(10,10,100,100,w);
//获取屏幕上左上角为
(10,10)和右上角为(100,100)的屏幕区域,并将其保存在数组w中null-putimage(int x,int y, void *bitmap, int op)
作用:将使用getimage函数保存起来的图形重新送回到屏幕上制定的位置。
(x,y)指定图形显示位置的左上角
bitmap 用来保存由getimage()获得的图形指针
Op 整型数图形复制到屏幕上的显示模式
[pthree_mode_CAR]
null一辆停止的车的程序代码
void main()
{ void *w;存放图片的变量
int i;
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
setbkcolor(GREEN) ; /*设置背景色*/
setcolor(4) ; /*设置前景色*/
bar3d(520,245,550,260,8,1) ;
bar3d(550,230,600,260,8,1) ; /*画车身*/
circle(535,260,8) ;
circle(575,260,8) ; /*画车轮*/nullw=malloc(imagesize(520,220,630,270));
/*检测图形区域所占内存区*/
getimage(520,220,630,270,w) ;
/*将图形存入内存 */
getch();
putimage(520,220,w,XOR_PUT) ;
/*在原图形的位置异或显示图形,在原图的位置上异或显示图形就相当于消除图像
putimage(200,350,w,COPY_PUT) ;
/*将保存起来的图形在别的位置上复制显示
getch();
closegraph();
}
坐标转换坐标转换(Xc,Yc)(0,0) X’+Y’+X+Y+(x,y)