计算机图形学实验指导书.docx
《计算机图形学实验指导书.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验指导书.docx(20页珍藏版)》请在冰豆网上搜索。
计算机图形学实验指导书
《计算机图形学》
实验指导书
主讲:
宋春花
教材:
计算机图形学
适应专业:
软件工程
总学时:
40学时
实验学时:
10
2011-5-20
前言
随着计算机科学与技术的迅猛发展,特别是大规模集成电路和超大规模集成电路技术的飞速发展,计算机已经成为一种高速、费用低的生成图形的有效工具。
计算机图形学作为利用计算机生成图形的技术,已经越来越广泛地在各个领域得到应用。
随着计算机图形学应用领域的拓宽和应用水平的提高,人们越来越重视对该项技术的研究和利用。
当今,计算机图形学已经成为了计算机科学技术领域的一个重要研究方向,并被广泛的应用于科学计算、工程设计、医药、工业、艺术、娱乐业、广告业、教育与培训、商业和政府部门等。
鉴于计算机图形学的重要性和应用的广泛性,计算机科学与技术专业将其设置为专业必选的选修课。
它主要是研究用计算机及其图形设备来输入、表示、变换、运算和输出图形的原理、算法及系统。
通过对本课程的学习,使学生对计算机图形学有一个完整的了解,并为进行计算机图形学应用和研究打下扎实基础。
由于本课程实践性较强,计划中安排10学时实验。
通过实验,使学生更加深入的理解计算机图形系统的工作机理和基本图形生成和处理算法。
在实验过程中,能够培养学生的自学能力、团队协作能力、解决问题能力、软件开发能力等多种能力。
培养学生的算法设计能力和编程能力,能够应用计算机来解决在科学研究、工程设计与制造中有关图形处理的能力;在图形学理论与算法方面的科研能力;应用高级绘图软件及对其进行二次开发的能力,并具有开发大型通用或专用绘图软件的能力。
为学生毕业设计、和毕业后从事计算机绘图、计算机辅助设计、图形生成、图像处理等打下基础。
培养学生的算法设计能力和编程能力,
目录
一、实验目的和要求1
二、实验环境2
三、实验项目3
实验1二维基本图形生成的算法实现3
实验2图形的裁剪8
实验3几何图形变换13
实验4BEZIER曲线和B样条曲线的绘制17
实验5基于OPENGL的实体建模19
第四章参考文献21
一、实验目的和要求
《计算机图形学》是计算机专业本科生的一门理论性、技术性、应用性较强的专业课程。
实验目的是:
通过上机实践,让学生更好地了解和掌握计算机图形学的基本图形生成的各种算法、对各种算法加以比较,同时在实践中发现问题、解决问题,给学生以新的启迪,培养学生的创新能力和实际动手能力。
实验要求:
1、采用VC++程序开发环境和OpenGL图形库进行课程实验,通过实验掌握基本图元-直线和圆弧生成算法;掌握曲线和曲面的基本绘制方法;掌握图形变换算法;掌握规则和不规则实体的建模技术;掌握真实感绘图技术;能够综合利用上述技术,进行一定复杂虚拟场景的设计。
为后续的课程奠定良好的基础。
2、上机实验前,要求完成实验报告的实验目的、理论基础、算法设计及源程序初稿。
实验程序调试过程中,可以互相讨论、检查程序中存在的问题。
实验完成之后,应思考算法与源程序的评价与改进及对结果的影响等分析,提交实验源程序和实验报告。
并要求用正规的实验报告纸和封面装订整齐,按时上交。
二、实验环境
实验环境要求:
硬件:
普通PC386以上微机;
软件:
操作系统:
Windows98/2000;
开发语言:
TurboC、VisualC++6.0、OpenGl,或其它学生掌握的高级语言。
三、实验项目
为加强学生对计算机图形学理论知识的进一步理解,本实验设计了五次实验,实验内容力求理论性和实用性的紧密结合。
实验一、二、三、四为基础性实验,通过编程实现图形生成及处理变换的各种基本算法,从而使学生进一步理解和牢固掌握图形学中重要的理论知识,同时使用当前流行的图形和游戏开发工具OPENGL,实现相应的功能,让学生理解图形理论的实际应用;实验五为应用性实验,采用OPENGL对规则实体和不规则实体进行建模。
该实验旨在提高学生的综合动手能力和创新能力,为以后从事图形、游戏及软件开发工作打下良好的基础。
实验一:
二维基本图形生成的算法实现
实验二:
图形的裁剪
实验三:
几何图形变换实验
实验四:
BEZIER曲线和B样条曲线的绘制
实验五:
采用OPENGL进行实体建模
实验一、二维基本图形生成的算法实现
实验目的
1、通过实验,进一步理解和掌握DDA和中点算法,Bresenham算法;
2、掌握DDA和中点算法,中点算法,Bresenham算法算法生成直线段的基本过程。
掌握中点画圆的算法。
3、通过编程,会在VC++环境下完成用DDA、中点算法实现直线段的绘制和中点算法实现圆的绘制。
实验属性
该实验为验证性实验。
实验学时
2学时,必做实验。
实验内容
1、用DDA算法或中点(Besenham)算法实现直线段的绘制。
2、用中点(Besenham)算法实现椭圆或圆的绘制。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用VC++语言编写源程序;
3、编辑源程序并进行调试;
4、进行运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
原理分析
DDA算法分析
假设直线的起点坐标为P1(x1,y1),终点坐标为P2(x2,y2),x方向的增量为△x=x2-x1;y方向上增量为△y=y2-y1,直线的斜率为k=△y/△x
当△x>△y时,让x从x1到x2变化,每步递增1,那么,x的变化可以表示为xi+1=xi+1,y的变化可以表示为yi+1=yi+k
用上式可求得图中直线P1P2和y
向网格线的交点,但显示时要用舍入
找到最靠近交点处的象素点耒表示。
当△x<△y时,让y递增1,x作
相应变化。
综合考虑,按照从(x1,y1)到(x2,y2)方向不同,分8个象限。
对于方向在第1a象限内的直线而言,取增量值Dx=1,Dy=m。
对于方向在第1b象限内的直线而言,取增量值Dy=1,Dx=1/m。
直线Bresenham算法分析
设直线从起点(x1,y1)到终点(x2,y2)。
直线可表示为:
方程y=mx+b,其中
b=y1-m*x1,m=(y2-y1)/(x2-x1)=dy/dx;
此处的讨论先将直线方向限于1a象限,在这种情况
下,当直线光栅化时,x每次都增加1个单元,
即xi+1=xi+1而y的相应增加值应当小于1。
为了光栅化,yi+1只可能选择右图中两种位置之一。
yi+1的位置选择yi+1=yi或者yi+1=yi+1,选择的原则是看精确
值y与yi及yi+1的距离d1及d2的大小而定。
计算公式为
y=m(xi+1)+b
(1)
d1=y-yi
(2)
d2=yi+1-y(3)
如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。
将式
(1)、
(2)、(3)代入d1-d2,再用dx乘等式两边,并以Pi=(d1-d2)dx代入上述等式,得Pi=2xidy-2yidx+2dy+(2b-1)dx
d1-d2是用以判断符号的误差。
由于在1a象限,dx总大于0,所
以Pi仍旧可以用作判断符号的误差。
Pi+1为
Pi+1=Pi+2dy-2(yi+1-yi)dx
求误差的初值P1,可将x1、y1和b代入式(2.4)中的xi、yi而得到
P1=2dy-dx
综述上面的推导,第1a象限内的直线Bresenham算法思想如下:
⒈画点(x1,y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-
dx,i=1;
⒉求直线的下一点位置xi+1=xi+1
如果Pi>0,则yi+1=yi+1,否则yi+1=yi;
⒊画点(xi+1,yi+1);
⒋求下一个误差Pi+1,如果Pi>0,则Pi+1=Pi+2dy-2dx,否则
Pi+1=Pi+2dy;
⒌i=i+1;如果i附注说明:
有关的源码:
DDA算法:
voidCmyView:
:
OnDdaline()
{
CDC*pDC=GetDC();//获得设备指针
intxa=,ya=,xb=,yb=,c=RGB(255,0,0);
intx,y;
floatdx,dy,k;
dx=(float)(xb-xa),dy=(float)(yb-ya);
k=dy/dx;
y=ya;
if(abs(k)>1)
{
for(x=xa;x<=xb;x++)
{pDC->SetPixel(x,int(y+0.5),c);
y=y+k;
}
else
{
for(y=ya;y<=yb;y++){
pDC->SetPixel(int(x+0.5),y,c);
x=x+1/k;
}
ReleaseDC(pDC);
}
//中点生成直线算法
voidCmyView:
:
OnMidPointline()
{
CDC*pDC=GetDC();//获得设备指针
intxa=,ya=,xb=,yb=,c=RGB(255,0,0);
floata,b,d1,d2,d,x,y;
a=ya-yb,b=xb-xa,d=2*a+b;
d1=2*a,d2=2*a+b;
x=xa,y=ya;
pDC->SetPixel(x,y,c);
while(x{
if(d<0){x++,y++,d+=d2;}
else{x++,d+=d1;}
pDC->SetPixel(x,y,c);
}
ReleaseDC(pDC);
}
//Bresenham直线算法
voidCmyView:
:
OnBresenhamline()
{
CDC*pDC=GetDC();//获得设备指针
intx1=,y1=,x2=,y2=,c=RGB(255,0,0);
ints1,s2,interchange;
floatx,y,deltax,deltay,f,temp;
x=x1;
y=y1;
deltax=abs(x2-x1);
dletay=abs(y2-y1);
if(x2-x1>=0)s1=1;elses1=-1;
if(y2-y1>=0)s2=1;elses2=-1;
if(deltay>deltax){
temp=deltax;
deltax=deltay;
deltay=temp;
interchange=1;}
elseinterchage=0;
f=2*deltay-deltax;
pDC->SetPixel(x,y,c);
for(i=1;i<=deltax;i++)
{
if(f>=0){
if(interchange==1)x+=s1;
elsey+=s2;
pDC->SetPixel(x,y,c);
f=f-2*deltax;
}
else{
if(interchange==1)y+=s2;
elsex+=s1;
f=f+2*deltay;
}
}
ReleaseDC(pDC);
}
圆的Bresenham算法
设圆的半径为r。
先考虑圆心在(0,0),并从x=0、y=r,开始的顺时针方向的1/8圆周的生成过程。
在这种情况下,
x每步增加1,从x=0开始,到x=y结束。
即有
xi+1=xi+1
相应的yi+1则在两种可能中选择:
yi+1=yi或者yi+1=yi-1
选择的原则是考察精确值y是靠近yi还是
靠近yi-1(如右图),
计算式为
y2=r2-(xi+1)2
d1=yi2-y2=yi2-r2+(xi+1)2
d2=y2-(yi-1)2=r2-(xi+1)2-(yi-1)2
令pi=d1-d2,并代入d1、d2,则有
pi=2(xi+1)2+yi2+(yi-1)2-2r2
pi称为误差。
如果pi<0则yi+1=yi,否则yi+1=yi-1。
pi的递归式为
pi+1=pi+4xi+6+2(yi2+1-yi2)-2(yi+1-yi)
pi的初值由上式代入xi=0,yi=r而得
p1=3-2r
根据上面的推导,圆周生成算法思想如下:
⒈求误差初值,p1=3-2r,i=1,画点(0,r);
⒉求下一个光栅位置,其中xi+1=xi+1,如果pi<0则yi+1=yi,否则yi+1=yi-1;
⒊画点(xi+1,yi+1);
⒋计算下一个误差,如果pi<0则pi+1=pi+4xi+6,否则pi+1=pi+4(xi-yi)+10;
⒌i=i+1,如果x=y则结束,否则返回步骤2。
附注说明:
有关的源码:
中点画圆算法:
voidCMyView:
:
OnMidpointCircle()
{
CDC*pDC=GetDC();
intxc=,yc=,r=,c=0;
intx,y;
floatd;
x=0,y=r,d=1.25-r;
描点(x,y)以及其他七个对称点;
while(x<=y)
{if(d<0)d+=2*x+3;
else{d+=2*(x-y)-5;y--;}
x++;
描点(x,y)以及其他七个对称点;
}
}
Bresenham画圆算法:
voidCMyView:
:
OnBresenhmaCircle()
{
CDC*pDC=GetDC();
intxc=,yc=,r=,c=0;
intx=0,y=r,p=3-2*r;
while(x{
描点(x,y)以及其他七个对称点;
if(p<0)p+=4*x+6;
else{p+=4*(x-y)+10;y--;}
x++;
}
if(x==y)
描点(x,y)以及其他七个对称点;
}
实验二、图形的裁剪
实验目的
1、通过实验,进一步理解和掌握Cohen_Sutherland裁剪算法;
2、掌握用Cohen_Sutherland裁剪算法裁减多边形的基本过程
3、通过编程,会在VC++环境下用Sutherland_Hogman算法编程实现用矩形窗口对多边形的裁剪。
实验属性
该实验为验证性实验。
实验学时
2学时,必做实验
实验内容
用Cohen_Sutherland算法编程实现用矩形窗口对直线的裁剪。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用VC++语言编写源程序;
3、编辑源程序并进行调试;
4、进行运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
原理分析
Cohen-Sutherland直线剪裁算法
以区域编码为基础,将窗口及其周围的,8个方向以4bit的二进制数进行编码。
右图所示的编码方法将窗口及其邻域
分为5个区域:
⑴内域:
区域(0000)。
⑵上域:
区域(1001,1000,1010)。
⑶下域:
区域(0101,0100,0110)。
⑷左域:
区域(1001,0001,0101)。
⑸右域:
区域(1010,0010,0110)。
当线段的两个端点的编码的逻辑“与”非零时,线段为显然不可见的,对某线段的两个端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右;
该算法的思想是:
对于每条线段P1P2分为三种情况处理。
(1)若P1P2完全在窗口内,则显示该线段P1P2简称“取”之。
(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。
(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。
其中一段完全在窗口外,可弃之。
然后对另一段重复上述处理。
裁剪一条线段时,先求出P1P2所在的区号code1,code2。
若code1=0,且code2=0,则线段P1P2在窗口内,应取之。
若按位与运算code1&code2≠0,则说明两个端点同在窗口的上方、下方、左方或右方。
可判断线段完全在窗口外,可弃之。
否则,按第三种情况处理。
求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段在窗口外,可弃之。
在对另一段重复上述处理。
在实现本算法时,不必把线段与每条窗口边界依次求交,只要按顺序检测到端点的编码不为0,才把线段与对应的窗口边界求交。
附注说明:
1、有关的源码:
Cohen-Sutherland裁减算法
#defineLEFT1
#defineRIGHT2
#defineBOTTOM4
#defineTOP8
intencode(floatx,floaty)
{intc=0;
if(x if(x>XR)c|=RIGHT;
if(x if(x retrunc;}
void CS_LineClip(x1,y1,x2,y2,XL,XR,YB,YT)
//floatx1,y1,x2,y2,XL,XR,YB,YT;(x1,y1)(x2,y2)为线段的端点坐标,其他四个参数定义窗口的边界
{intcode1,code2,code;
code1=encode(x1,y1); code2=encode(x2,y2);
while(code1!
=0||code2!
=0)
{if(code1&code2!
=0)return;
code=code1;
if(code1==0)code=code2;
if(LEFT&code!
=0){x=XL;
y=y1+(y2-y1)*(XL-x1)/(x2-x1);}
elseif(RIGHT&code!
=0)
{x=XR; y=y1+(y2-y1)*(XR-x1)/(x2-x1);}
elseif(BOTTOM&code!
=0)
{y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1);}
elseif(TOP&code!
=0)
{y=YT; x=x1+(x2-x1)*(YT-y1)/(y2-y1);}
if(code==code1)
{ x1=x;y1=y;code1=encode(x,y);}
else{x2=x;y2=y;code2=encode(x,y);}
}
displayline(x1,y1,x2,y2);
}
实验三、几何图形变换实验
实验目的
1、通过实验,运用计算机图形学的知识、原理和算法;
2、掌握二维和三维图形几何变换;
3、通过使用VC++编程环境实现图形几何变换;
实验属性
该实验为验证性实验。
实验学时
2学时,必做实验
实验内容
1、在VC++编程环境下建立二维平面图形(长方形)实现其缩放、平移、旋转几何变换;
2、在VC++编程环境下建立三维立方体,实现缩放、平移、旋转等几何变换,。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用VC++语言编写源程序;
3、编辑源程序并进行调试;
4、进行特殊模式的运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
基础知识及原理
二维变换矩阵
二维几何变换包括平移、旋转和变比3种基本变换,变换公式都可以表示为3×3的变换矩阵和齐次坐标相乘的形式。
分别为:
1平移的矩阵运算表示:
2旋转的矩阵运算表示为:
[x′ y′ 1]=[x y 1]
3变比的矩阵运算表示为:
[x′ y′ 1]=[x y 1]
、
三维变换矩阵
三维几何变换包括平移、旋转和变比。
三维几何变换可以表示为公式,或三维齐次坐标和4×4变换矩阵的乘积。
下面分别以公式,矩阵乘积和简记符号来描述三维几何变换。
并记变换前物体的坐标为x,y,z;变换后物体的坐标为x′,y′,z′。
一、平移
设Tx,Ty,Tz是物体在三个坐标方向上的移动量,则有公式:
x′=x+Tx
y′=y+Ty
z′=z+Tz
矩阵运算表达为:
[x′y′z′1]=[xyz1]
二、旋转
旋转分为三种基本旋转:
绕z轴旋转,绕x轴旋转,绕y轴旋转。
在下述旋转变换公式中,设旋转的参考点在所绕的轴上,绕轴转θ角,方向是从轴所指处往原点看的逆时针方向(见下图形)。
绕z轴旋转
绕x轴旋转
1绕z轴旋转的公式为:
x′=xcosθ-ysinθ
y′=xsinθ+ycosθ
z′=z
矩阵运算的表达为:
[x′y′z1]=[xyz1]
2绕x轴旋转的公式为:
x′=x
y′=ycosθ-zsinθ
z′=ysinθ+zcosθ
矩阵运算的表达为:
[x′y′z′1]=[xyz1]
3绕y轴旋转的公式为:
x′=zsinθ+xcosθ
y′=y
z′=zcosθ-xsinθ
矩阵的运算表达式为:
[x′y′z′1]=[xyz1]
实验四、BEZIER曲线和B样条曲线的绘制
实验目的
1、通过实验,进一步理解和掌握生成BEZIER曲线的算法;
2、掌握BEZIER曲线的基本生成过程;
3、通过编程,会在VC++环境下编程实现三次BEZIER曲线的绘制;
4、通过实验,进一步理解和掌握生成B样条曲线的算法;
5、掌握B样条曲线的基本生成过程;
6、通过编程,会在VC++环境下编程实现三次B样条曲线的绘制。
实验属性
该实验为验证性实验。
实验学时
2学时,必做实验
实验内容
1、编程实现三次BEZIER曲线的绘制;
2、编程实现三次B样条曲线的绘制。
实验步骤
1、算法、原理清晰,有详细的设计步骤;
2、依据算法、步骤或程序流程图,用VC++语言编写源程序;
3、编辑源程序并进行调试;
4、进行特殊模式的运行测试,并结合情况进行调整;
5、对运行结果进行保存与分析;
6、打印源程序或把源程序以文件的形式提交;
7、按格式书写实验报告。
实验五、采用OPENGL进行实体建模
实验目的
1、学习三维图形软件包OPENGL在VC++环境下应用的方法;
2、掌握OPENGL语法规则;
3、通过实验,掌握规则对象和不规则对象的建模方法;
4、通过编程,会在VC++环境下采用OPENGL编程实现规则对象和不规则对象(对象自选)模型的绘制。
实验属性
该实验为应用性实验。
实验学时
2学时,必做实验
实验内容
1、编程实现规则对象模型的绘制;