计算机图形学实验指导书Word文档下载推荐.docx
《计算机图形学实验指导书Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验指导书Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
在图形方式下,屏幕上每个像素的显示位置用点坐标系来描述。
在该坐标系中,屏幕的左上角为坐标原点O(0,0),水平向为x轴,自左向右;
垂直方向为y轴,自上向下。
如图1-1所示。
分辨率不同,水平方向和垂直方向上的点数也不一样,即其maxx、maxy的数值不同。
在TurboC中,坐标数据有两种形式给出:
一种是绝对坐标;
另一种是相对坐标。
绝对坐标的参考点是坐标的原点O(0,0),x和y的值只能取规定范围内的正整数,其坐标值在整个屏幕范围内确定。
相对坐标是相对于“当前点”的坐标,所以其参考点不是坐标系的原点,而是当前点。
要相对坐标中,x和y的取值是相对于当前点在X方向和Y方向上的增量,这个增量可以是正的,也可以是负的,所以x和y的值可以是正整数,也可以是负整数。
此外,把在一个窗口范围内确定的坐标也称为
相对坐标。
二、C语言中的基本绘图函数及其用法
1、绘图函数
在用绘图函数作图时,有的绘图函数坐标是相对于坐标原点,用绝对坐标。
有的绘图函数用相对坐标,这时要随时注意图形的“当前点位置”,它是绘图的起始位置。
也就是说,图形总是从当前点开始画图。
画完一个图形后,有的当前点不变,仍在原来的位置;
而有时会移到新的位置。
1)直线类绘图函数
用直线类函数绘制直线图形,可以用两种坐标:
几个常用的函数:
①点的绝对定位函数moveto(x,y)
②点的相对定位函数moverel(deltayx,deltay)
它们不绘制图形,只改变当前点的位置,接着用绘图函数绘图。
③指定两个绝对点绘直线函数:
line(x1,y1,x2,y2)
该函数不改变当前点的位置。
④从当前点到指定的绝对点绘直线函数:
lineto(x,y)
该函数画线的同时,将当前点的位置移到(x,y)。
⑤从当前点到指定的相对点绘直线函数:
linerel(dx,dy)
该函数画线的同时,将当前点的位置移到(x+dx,y+dy)。
设当前坐标为(x,y)则
linerel(dx,dy)与lineto(x+dx,y+dy)等价。
⑥读取当前点的位置x,y函数分别为:
getx(void),gety(void)
⑦读取x,y轴的最大值函数分别为:
getmaxx(void),getmaxy(void)
2)多边形类绘图函数
1画矩形函数
rectangle(x1,y1,x2,y2);
2画多边形函数:
drawpoly(n,*polypoints)
其中参数,n为多边形数;
*polypoints指向一个整形数组,共有2n个整数组成,每对整数给出了一个多边形顶点(x,y)坐标。
2、图形属性的设置
图形属性的设置包括绘制该图形所用的颜色和线型。
颜色又分为背景色和前景色:
背景色指的是屏幕的颜色,即绘图时的底色;
前景是指绘图时图形线条所用的颜色。
背景色和前景色的设置,只对设置后所绘制的颜色和线型有作用,对已经绘制的图形无作用。
1)设置前景色
设置前景颜色所用的函数setcolor。
其调用格式为:
setcolor(color);
其中color为一个整型数值,代表所取的颜色。
2)设置背景色
设置背景颜色所用的函数sebktcolor。
setbkcolor(color);
3)设置线型
设置当前绘图所用的线型和线宽,用函数setlinestyle。
线型和线宽的设置仅限于对直线类图形有效。
setlinestyle(sty,pat,b);
sty:
整型值,用来定义所画直线的类型;
pat用户定义线型使用;
b整型值,用来定义定义所画直线的线宽。
在屏幕上绘制出各种简单的几何图形,要求设置不同的线形和颜色。
3、填充
填空是指用指定的模式和颜色来填空一个指定的封闭区域。
1)设置当前的填充模式和颜色
设置填充模式和颜色,用函数setfillstyle,其调用格式为:
setfillstyle(pattern,color);
2)实施填充
对于指定的一块有界的封闭区域进行填充操作,用函数floodfill,其调用格式为:
floodfill(x,y,,bcolor);
参数(x,y)指位于填充区域内任意一点的坐标,该点作为填充的起始点,参数bcolor作为填充区域的边界颜色。
如果起始点在封闭区域内,则区域内部被填充;
如果起始点在封闭区域外,则区域外部被填充。
同学们可以自行验证。
3)其它填充函数
以下几个填充函数,均须事先由setfillstyle函数指定当前的填充模式和颜色。
①绘制并填充实椭圆函数:
fillellipse(x,y,rx,ry);
②绘制并填充实椭圆扇区函数:
sector(x,y,angs,ange,rx,ry)
③绘制并填充多边形函数:
fillpoly(nps,*pxy)
4、屏幕管理
TurboC2.0提供了11个函数,用于对屏幕和视区进行管理。
1)设置视图区
在图形方式下,可用函数setviewport在屏幕上定义一个视图区。
视图区相当于一个用于绘图的窗口。
视图区的位置和大小用屏幕的绝对坐标定义,并且可把视图区设置为裁剪和不裁剪两种状态。
函数setviewport的调用格式为:
setviewport(x1,y1,x2,y2,c);
参数x1,y1:
为视图区矩形的左上角顶点坐标;
x2,y2:
为视图区矩形的右下角顶点坐标。
c为裁剪状态参数。
c=1,超出视图区的图形部分被自动裁剪掉;
c=0时,对超出部分不作裁剪处理。
应注意:
视图区建立以后,所有的图形输出坐标都是相对于当前视图区的,即视图区左上角点为坐标(0,0)点,而与视图区和图形在屏幕上的位置无关。
在默认情况下,整个屏幕为一个视图区。
2)清除视图区
清除视图区用函数clearviewport。
它的作用是清除掉当前视图区,将当前点的位置设置于屏幕左上角(0,0)点。
调用格式为:
clearviewport();
3)清屏
清屏的函数为cleardevice();
实验一直线的生成算法
一、实验目的
几种直线生成算法的比较,特别掌握用Bresenham直线生成算法。
二、基本要求
用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。
三、算法提示
1、有关直线生成算法有:
DDA(数值微分)直线算法、直线Bresenham生成算法。
直线Bresenham生成算法思想如下(第一象限,且斜率k<
1的情况图2-1a中的1a):
1)画点(x1,y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-dx,i=1;
2)求直线下一点位置xi+1=xi+1如果Pi>
0,则yi+1=yi+1,否则yi+1=yi;
3)画点(xi+1,yi+1);
4)求下一个误差Pi+1点,如果Pi>
0,则Pi+1=Pi+2dy-2dx,否则Pi+1=Pi+2dy;
5)i=i+1,如果i<
dx+1则转步骤2,否则结束操作。
Bresenham生成算法的优点如下;
1)不必计算直线的斜率,因此不做除法。
2)不用浮点数,只用整数。
3)只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。
Bresenham算法的速度很快,并适于用硬件实现。
对于图2-1a中的2a,只需将xi+1=xi+1改为xi+1=xi-1。
四、参考源程序
1、数值微分法生成斜率小于90的直线
/*DDAline数值微分法生成斜率小于90的直线*/
#include<
math.h>
#include"
display.h"
main()
{
intxo,yo,xa,ya,i,j;
intdx,dy,c;
floatddx,ddy,x,y;
Initialize();
printf("
inputstartx,y(x=0-640,y=0-480)\n"
);
scanf("
%d,%d"
&
xo,&
yo);
/*输入直线的两个点*/
xa:
%d--639"
xo);
%d"
xa);
ya:
0..%d"
yo);
ya);
redlineissystem,yellowiscreate\n"
if(xa>
=xo&
&
xa<
=639&
ya>
=0&
ya<
=yo)
/*数值微分法生成直线算法*/
outtextxy(xo,yo+5,"
o"
outtextxy(xa,ya-10,"
a"
dx=xa-xo;
dy=yo-ya;
if(dx>
dy)c=dx;
elsec=dy;
ddx=dx*1.0/c;
ddy=dy*1.0/c;
x=xo*1.0;
y=yo*1.0;
setcolor(12);
line(xo,yo,xa,ya);
getch();
while(c>
=0)
{i=round(x);
j=round(y);
putpixel(i,j,14);
x=x+ddx;
y=y-ddy;
c=c-1;
}
elseprintf("
dataerror"
closegraph();
intround(ff)
floatff;
{intk;
if((ff-(int)ff)>
0.5)k=(int)ff+1;
elsek=(int)ff;
k=(int)ff;
return(k);
实验二Bezier曲线的生成算法
1、复习Bezier曲线参数表示法。
2、编程实现用二次Bezier曲线绘制。
3、编程实现用三次Bezier曲线绘制和分段光滑Bezier曲线图形的绘制。
1、编程实现在屏幕上绘制出两次Bezie曲线的几何图形和特征多边形图形,对于直线和曲线设置不同的线形和颜色。
2、现在屏幕上绘制出三次Bezie曲线的几何图形和特征多边形图形,对于直线和曲线设置不同的线形和颜色。
3、编程实现用分段三次Bezier曲线绘制光滑Bezier曲线图形。
1、二次Bezier曲线的计算公式为:
P(t)=(P0-2P1+P2)t2+(-2P0+2P1)t+P0
X(t)=(X0-2X1+X2)t2+(-2X0+2X1)t+X0
Y(t)=(Y0-2Y1+Y2)t2+(-2Y0+2Y1)t+Y0
其中P0、P1、P2为三个已知的点,坐标分别为(X0、Y0)、(X1、Y1)、(X1、Y2)。
2、三次Bezier曲线的计算公式为:
P(t)=(-P0+3P1-3P2+P3)t3+(3P0-6P1+3P2)t2+(-3P0+3P1)t+P0
X(t)=(-X0+3X1-3X2+X3)t3+(3X0-6X1+3X2)t2+(-3X0+3X1)t+X0
Y(t)=(-Y0+3Y1-3Y2+Y3)t3+(3Y0-6Y1+3Y2)t2+(-3Y0+3Y1)t+Y0
其中P0、P1、P2、P3为四个已知的点,坐标分别为(X0、Y0)、(X1、Y1)、(X1、Y2)、(X3、Y3)。
3、程序设计方法
根据Bezier曲线的定义,输入Bezier曲线的特征多边形(例如三次Bezier曲线输入四个型值点),然后把t从0~1分成n等分,按相应的Bezier曲线公式计算出Bezier曲线上的点,用绘直线段的方法依次这些点连接起来,就得到Bezier曲线。
如果要画多段Bezier曲线,可设置一些变量存放Bezier曲线的条数,按条数依次绘制出来即可。
四、上机作业题
1、编程绘制三次Bezier曲线。
2、改变已知点的坐标值,曲线形状有什么变化?
五、参考实例源程序
1、绘制二次Bezier曲线的源程序
/*二次Bezier曲线一般算法*/
voidBezier_2(intcolor,doublep[3][2])
{doublet,xt,yt;
intrate=200,x,y;
setcolor(color);
moveto(p[0][0],p[0][1]);
for(t=0;
t<
=1;
t+=1.0/rate)
{yt=1-t;
xt=p[0][0]*yt*yt+p[1][0]*2*yt*t+p[2][0]*t*t;
yt=p[0][1]*yt*yt+p[1][1]*2*yt*t+p[2][1]*t*t;
x=(int)(xt);
y=(int)(yt);
lineto(x,y);
}
voidmain(void)
{staticdoublep[3][2]={50,400,340,20,635,420};
constN0=3;
/*特征顶点个数*/
inti;
/*SetsystemintoGraphicsmode*/
setcolor(WHITE);
for(i=1;
i<
N0;
i++)lineto(p[i][0],p[i][1]);
Bezier_2(LIGHTRED,p);
while(getch()!
=ESC);
/*按ESC键退出*/
/*Returnthesystemtotextmode*/
实验三制动画程序
1、复习实现动画的几种编程方法,比较不同方法的差别。
2、综合运用所学知识绘制复杂性图形(包括前景图和背景图)。
3、学会用多图形页功能设计动画程序。
4、学会用位图像函数设计动画程序。
1、发挥你的想象能力,利用重画技术设计一个动画程序。
2、利用多图形页功能设计一个动画程序。
3、用位图像函数设计一个动画程序。
三、几种常见动画的程序设计思想
1、利用重画技术设计动画程序
在屏幕上绘制一幅图形,用delay函数廷时一段时间,及cleardevice函数清屏,在屏幕上的新位置绘制另一幅图形。
再廷时一段时间,这样不断重复,能使整个屏幕产生动起来的效果。
2、利用多图形页功能设计动画程序
对于支持多个图形页功能的图形卡来说,可以用setactivepage函数把指定图形页设成活动页,用setvisualpage函数把指定图形页设成显示页(可见页)。
活动页可以是当前显示页,也可以是非显示页,但当前的运行程序只能在活动页上绘制。
所以,当用setactivepage函数选定某一页为活动页后,其后所有的图形函数的输出都是针对该页的。
因为存在有多个图形页,所以在程序中,可以把一个页设置成显示页,显示这一页的图形;
而在同时把另一页设置成活动页,程序在活动页上绘图。
当活动页上绘完图后,再互换这两个页的设置。
这就相当于在“后头”绘图,整个绘图过程在后头完成;
然后拿到前头支显示,在前头显示的是绘制完整的图形画面,如此重复。
这样画面的连续性就会有所改善。
函数setactivepage和函数setvisualpage的用法为:
setvisualpage(intpagenum)setvisualpage(intpagenum)
其中参数pagenum为页号。
对于支持两个图形页的图形卡,页号取0和1。
系统默认值取0。
3、用位图像函数设计动画程序
TurboC中有两个函数getimage和putimage,是用于存取和输出屏幕位图图像信息的。
其中,getimage函数的功能是将屏幕上指定区域中的一个位图图像取下并存到内存中;
putimage函数的功能是将内存中的位图图像按指定的方式输出到屏幕上的指定位置上。
这两个函数的调用方法为:
3)getimage的调用方法
getimage(x1,yt,xr,yb,*bitmap);
其中参数x1,yt,xr,yb为整型变量,指定位图所在的矩形区域的对角点坐标。
*bitmap内存中存放位图信息的地址。
4)putimage的调用方法
putimage(x,y,*bitmap,op);
其中参数x,y为整型变量,指定图像在屏幕上输出位置的定位点坐标。
op为位图图像的输出方式,见表9-1。
符号常量
数值
说明
Op
COPY_PUT
XOR_PUT
OR_PUT
AND_PUT
NOT_PUT
1
2
3
4
拷贝
异或
或
与
拷贝源图像的非
1、发挥你的想象能力,利用多图形页功能设计一个动画程序。
2、发挥你的想象能力,用位图像函数设计一个动画程序。
五、实例程序:
以下实例程序在TurboC下调试通过
1、用重画技术为实现汽车从左向右运行,同时天空的月亮从右向左运行
/*cglrmxam0509.c*/
graphics.h"
conio.h"
#defineTIME4500
/*ThefunctiontopaintMOON"
*/
voidmoon(intx,inty,intr)
{
arc(x,y,-120,120,r);
arc(x-0.5*r,y,-90,90,0.87*r);
setfillstyle(SOLID_FILL,WHITE);
floodfill(x+0.5*r,y,WHITE);
return;
/*ThefunctiontopaintCAR"
voidcar(intdx,intcolor,intnu,int*p)
for(i=0;
2*nu;
i+=2)
*(p+i)=*(p+i)+dx;
setfillstyle(SOLID_FILL,color);
fillpoly(nu,p);
setfillstyle(SOLID_FILL,DARKGRAY);
fillellipse(*p+15,350,10,10);
fillellipse(*p+65,350,10,10);
intgdriver=DETECT,gmode,errorcode;
intpcar[9][2]={5,350,90,350,90,335,70,335,65,320,25,320,20,335,
5,335,5,350};
introad[5][2]={0,360,0,479,639,479,639,360,0,360};
initgraph(&
gdriver,&
gmode,"
E:
\\TC"
cleardevice();
setbkcolor(LIGHTBLUE);
setfillstyle(SOLID_FILL,GREEN);
fillpoly(5,road);
moon(480,120,50);
car(5,RED,9,pcar);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,4);
outtextxy(40,40,"
PRESSANYKEYTOSTART"
54;
i++)
moon(480-6*i,120,50);
car(10,RED,9,pcar);
delay(TIME);
outtextxy(100,400,"
PRESSANYKEYTORETURN"
}
2、用多图形页功能实现实例程序1的功能。
/*cglrmxam05010.c*/
#inclu