计算机图形课程设计报告.docx
《计算机图形课程设计报告.docx》由会员分享,可在线阅读,更多相关《计算机图形课程设计报告.docx(19页珍藏版)》请在冰豆网上搜索。
计算机图形课程设计报告
课程设计报告
课程名称:
计算机图形学
任课教师:
姓名:
学号:
1.引言
1.1.课程设计项目
创建旋转体总结报告
1.2.编写背景
1.概述
计算机图形学(ComputerGraphics,简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。
简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。
2.主要组成
图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。
从构成要素上看,图形主要分为两类,一类是几何要素在构图中具有突出作用的图形,如工程图、等高线地图、曲面的线框图等,另一类非几何要素在构图中具有突出作用的图形,如明暗图、晕渲图、真实感图形等。
3.主要目的
计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目的真实感图形。
为此,必须建立图形所描述的场景的几何表示,再用某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。
所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关系。
事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实体造型技术作为其主要的研究内容。
同时,真实感图形计算的结果是以数字图像的方式提供的,计算机图形学也就和图像处理有着密切的关系。
4.概念区分
图形与图像两个概念间的区别越来越模糊,但还是有区别的:
图像纯指计算机内以位图形式存在的灰度信息,而图形含有几何属性,或者说更强调场景的几何表示,是由场景的几何模型和景物的物理属性共同组成的。
#####
5.研究内容
计算机图形学的研究内容非常广泛,如图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。
1.3.相关概念
OpenGl
用于编写计算机图形学的程序的编译工具。
OpenGL是行业领域中最为广泛接纳的2D/3D图形API,其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。
OpenGL是独立于视窗操作系统或其它操作系统的,亦是网络透明的。
在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL™帮助程序员实现在PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。
旋转体
一条平面曲线绕着它所在的平面内的一条定直线旋转所形成的曲面叫作旋转面;封闭的旋转面围成的几何体。
3.旋转矩阵
在乘以一个向量的时候有改变向量的方向但不改变大小的效果的矩阵。
旋转矩阵不包括反演,它可以把右手坐标系改变成左手坐标系或反之。
所有旋转加上反演形成了正交矩阵的集合。
旋转变换
简称旋转.欧氏几何中的一种重要变换.即在欧氏平面上(欧氏空间中),让每一点P绕一固定点(固定轴线)旋转一个定角,变成另一点P′,如此产生的变换称为平面上(空间中)的旋转变换.。
变换矩阵
在线性代数中,线性变换能够用矩阵表示。
如果T是一个把R映射到R的线性变换,且x是一个具有n个元素的列向量,
,那么我们把m×n的矩阵A,称为T的变换矩阵。
#####
3D坐标系
三维笛卡儿坐标系是在二维笛卡儿坐标系的基础上根据右手定则增加第三维坐标(即Z轴)而形成的。
2D坐标系
在同一个平面上互相垂直且有公共原点的两条数轴构成平面直角坐标系。
1.4.编写目的
经过本学期对计算机图形学的学习,对其进行初步的掌握,通过OpenGL编程,对所学内容进行实际应用并发现学习中存在的问题,也是对自己学习工作的检验和测试,在撰写报告的过程中能够更深刻的了解计算机图形学的理念通过这份文档来记录实践过程中遇到的问题以及改善的方法。
现在对整个过程加以认识、记录和总结,留下经验,汲取教训。
为以后的其他工作积攒经验,为以后遇到相同的问题和从事类似项目奠定坚实的基础,以便以后有资可寻、有底可查,增长个人见识,
1.5.相关文献
《ComputerGraphicswithOpenGL》———DonaldHearnM.PaulineBaker
OpenGL编程手册
VC++编程手册;
2产品
2.1.设计分析
1.一个旋转体由其外轮廓线绕其竖直中心轴旋转而成。
2.程序要求建立一个窗口显示竖直的中心轴,并且要求实现轮廓线的编辑,具体包含功能:
节点的增加、删除和节点间自动连线。
3.程序要求建立另外一个窗口显示轮廓线绕中心轴旋转以后的三维物体,本窗口还要求实现三维物体的Phong着色和对三维物体的简单操作,具体包含:
放大、缩小和旋转。
4.移动光源#####
5.纹理映射效果
6.雾化效果
2.2.总体设计
1.项目规划:
本系统是一个基于OpenGL开发的实现能够进行人机交互的绘制3D旋转体的系统,本系统中的功能模块主要分为以下几种:
矩阵运算模块:
实现两个或多个矩阵的相关运算,为绘制图形提供数据结构,体现图形转化过程中的算法。
显示图形模块:
用于设定图像的显示方式,绘制方法,在其中还可以设置光源位置等相关的显示信息。
键盘敲击模块:
对不同的键盘敲击事件作出相应的处理,包括点线的转化,雾化效果等。
鼠标点击模块:
在3D显示窗口添加的鼠标事件,对鼠标的事件作出相应的响应效果。
动作模块:
根据左边用户绘制的2D图形,动态的划出右面相对应的3D图像。
找点模块:
在左边的用户画图窗口进行锁定鼠标点击时靠近的点。
2.系统功能结构
下图写于此
3设计目标
本系统是根据课本中的程序而开发的,基本能够实现需求中所要求的功能,通过本系统可以达到以下目标:
1系统运行稳定,安全可靠。
2界面美观、友好。
3用户操作使用方便。
4生成的3D图形效果良好。
5能够正确的生成用户所要绘制的3D图形
2.3.主要功能模块设计
1矩阵运算模块的设计:
功能描述:
程序启动后,这部分功能模块会为整个应用程序提供算法支持,具体是矩阵直接的相互运算,在2D向3D转化过程中会起到很重要的作用。
代码设计:
floatvv(float*v1,float*v2){
returnv1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];
}
#####
voidvxv(float*n,float*v1,float*v2){
n[0]=v1[1]*v2[2]-v1[2]*v2[1];
n[1]=v1[2]*v2[0]-v1[0]*v2[2];
n[2]=v1[0]*v2[1]-v1[1]*v2[0];
}
voidloadIdentity(Matrixm){
Matrixidentity={{1.0,0.0,0.0,0.0},
{0.0,1.0,0.0,0.0},
{0.0,0.0,1.0,0.0},
{0.0,0.0,0.0,1.0}};
for(inti=0;i<4;i++)
for(intj=0;j<4;j++)
m[i][j]=identity[i][j];
}
voidpreMultiply(Matrixp,Matrixm){
inti,j;
Matrixt;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
t[i][j]=p[i][0]*m[0][j]+p[i][1]*m[1][j]+p[i][2]*m[2][j]+p[i][3]*m[3][j];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
m[i][j]=t[i][j];
}
2显示图形模块的设计:
功能描述:
该模块主要为所要画的图形进行描述,是绘制图形的主要函数,通过调用这个功能模块就能画出用于显示给用户的图形。
代码设计:
//2D图形的display函数
voiddisplay(){
glClear(GL_COLOR_BUFFER_BIT);
if(n==1&&type==GL_LINE_STRIP){
glBegin(GL_POINTS);
glVertex2iv(vert[0]);
glColor3f(0,0.5,0.5);
glVertex2i(width-vert[0][0]-1,vert[0][1]);
glEnd();
}
glColor3f(0,0.5,0.5);#####
glBegin(GL_LINES);
glVertex2i(width/2,0);
glVertex2i(width/2,height-1);
glEnd();
glBegin(type);
for(inti=0;iglEnd();
glColor3f(1,1,0);
glBegin(type);
for(inti=0;iglEnd();
glutSwapBuffers();
initQMesh();
glutSetWindow(winid);
glutPostRedisplay();
}
//3D图形的显示函数
voidmodelDisplay(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
floatM[16];
for(intr=0;r<4;r++)for(intc=0;c<4;c++)M[4*c+r]=CRM[r][c];
glMultMatrixf(M);
glScalef(zoom,zoom,zoom);
drawQMesh();
glPopMatrix();
glPushMatrix();
glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);
glPopMatrix();
glutSwapBuffers();
}
3键盘敲击模块
功能描述:
该功能主要为两个窗体添加键盘敲击事件,在2D窗体中主要添加了反走样效果,清除所画的图,点线转化功能,对于3D窗体主要添加了投影方式的变换,雾化效果,光源移动的功能
代码设计:
//2D绘制窗体的键盘敲击处理函数
voidkeyboard(unsignedcharkey,intx,inty){
switch(key){
case'a':
antialiasing=!
antialiasing;//反走样效果
if(antialiasing){#####
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
}else{
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
break;
case'c':
n=0;break;//清除界面功能
case'l':
type=GL_LINE_STRIP;break;//绘制线功能
case'v':
type=GL_POINTS;break;//绘制点功能
}
glutPostRedisplay();
}
//3D显示窗体的键盘敲击事件处理函数:
voidmodelKeyboard(unsignedcharkey,intx,inty){
switch(key){
case'o':
glMatrixMode(GL_PROJECTION);//正投影
glLoadIdentity();
glOrtho(-4,4,-4,4,6,14);
glMatrixMode(GL_MODELVIEW);
break;
case'p':
glMatrixMode(GL_PROJECTION);//侧投影,不过是默认的
glLoadIdentity();
gluPerspective(45.0,1.0,6.0,14.0);
glMatrixMode(GL_MODELVIEW);
break;
case'm':
lightPosition[0]=lightPosition[0]-0.5;//光源移动
break;
case'n':
lightPosition[1]=lightPosition[1]-0.5;
break;
case'z':
lightPosition[2]=lightPosition[2]-0.5;
break;
case'q':
glEnable(GL_FOG);//雾化效果
{
glFogi(GL_FOG_MODE,GL_LINEAR);
GLfloatfogColor[]={1.9,1.1,2.2,0.5};
glFogfv(GL_FOG_COLOR,fogColor);
glFogf(GL_FOG_START,3.0);
glFogf(GL_FOG_END,15.0);
glHint(GL_FOG_HINT,GL_DONT_CARE);
}
break;
case'k':
glDisable(GL_FOG);
break;#####
}
glutPostRedisplay();
}
4鼠标点击模块
功能描述:
该功能模块主要实现了对两个窗体鼠标事件的处理,对于3D窗体实现了鼠标左键旋转,由键放大缩小的效果,2D窗体实现了左键画点,右键可以对已经存在的点改变它的位置。
代码设计:
//3D窗体的鼠标事件
voidmodelMouse(intbutton,intstate,intx,inty){
switch(button){
caseGLUT_LEFT_BUTTON:
if(state==GLUT_DOWN){
cx=x;
cy=h-1-y;
dx=dy=0;
left_button_down=true;
}else
left_button_down=false;
break;
caseGLUT_RIGHT_BUTTON:
if(state==GLUT_DOWN){
cx=x;
cy=h-1-y;
right_button_down=true;
}else
right_button_down=false;
break;
}
}
//2D窗体鼠标事件
voidmouse(intbutton,intstate,intx,inty){
y=height-1-y;
switch(button){
caseGLUT_LEFT_BUTTON:
#####
if(state==GLUT_DOWN&&!
rubberbanding){
v=n++;
vert[v][0]=(xwidth/2:
(x>=width)?
width-1:
x;
vert[v][1]=(y<0)?
0:
(y>=height)?
height-1:
y;
rubberbanding=true;
glutPostRedisplay();
}
elserubberbanding=false;
break;
caseGLUT_RIGHT_BUTTON:
if(state==GLUT_DOWN&&!
rubberbanding&&(v=findVertex(x,y))!
=-1){
if(glutGetModifiers()==GLUT_ACTIVE_CTRL){
for(inti=v;ivert[v][0]=vert[i+1][0];
vert[i][1]=vert[i+1][1];
}
n--;
}else{
vert[v][0]=(xwidth/2:
(x>=width)?
width-1:
x;
vert[v][1]=(y<0)?
0:
(y>=height)?
height-1:
y;
rubberbanding=true;
}
glutPostRedisplay();
}
elserubberbanding=false;
break;
}
}
5找点模块
功能描述:
此方法主要用于对用户所需要的点进行锁定。
能够改变原来已经存在的点。
intfindVertex(intx,inty){//锁定鼠标靠近的点
intdx,dy;
for(inti=0;idx=vert[i][0]-x;
dy=vert[i][1]-y;
if(dx*dx+dy*dy<16)returni;
}
return-1;#####
}
2.4.主要功能和性能
a.通过Editpolygons窗口(二维多边形编辑视窗)绘制多边形。
b.对绘制出的多边形能增删顶点改变多边形形状。
c.通过Objectwindow:
李文云,向明海窗口(三维旋转体显示视窗)显示在二维多边形编辑视窗中编辑好的旋转体轮廓的三维旋转体映射。
d.在三维旋转体显示视窗中通过o键切换到正投影显示,通过p键切换到透视投影投影显示
e.在三维旋转体显示视窗中:
1)通过小写字母x用于对电光源位置的x坐标做减量操作,大写字母X用于对电光源位置的x坐标做增量操作;
2)小写字母y用于对电光源位置的x坐标做减量操作,大写字母Y用于对电光源位置的y坐标做增量操作;
3)小写字母z用于对电光源位置的z坐标做减量操作,大写字母Z用于对电光源位置的z坐标做增量操作;
4)字母f、F用于开启雾化效果,小写字母n用于关闭雾化效果
f.在三维旋转体显示视窗中,通过按下鼠标右键同时移动光标来改变三维旋转体大小
g.在三维旋转体显示视窗中,通过按下鼠标左键同时移动光标来转动三维旋转体。
说明:
原定的开发目标达到了。
所要求的全部实现
附加要求实现了移动光源,雾化效果两项。
2.5基本流程
这个程序使用VS为编译工具,使用C++语言,运用OPENGL技术,使窗口能够动态的接收用户的输入信息,包括鼠标和键盘的事件响应,使用户能够画出自己想要的对称二维图形,再由程序将其转换为三维图像,并最终实现三维图像的各种#####操纵功能,具体实现是一个一个窗体进行实现的
Editpolygons窗体的实现:
首先,绘制基本窗体,包括左边,色调等内容
接着,绘制中轴线及相关的内容
接着,在窗体中加入键盘和鼠标的事件截获功能,使其能捕获鼠标或键盘的事件
接着,制作点绘制线的功能,将线绘制成几何图形。
接着,利用中轴线使线的坐标关于中轴对称,使其成为对称图形
接着,添加反走样效果,添加清楚界面功能,添加绘制线和绘制点的功能。
DisplayObject窗口的实现
首先,绘制基本窗体,包括左边,色调等内容
接着,通过第一个窗体的内容绘制三维图形
接着,实现其视角的转移
接着,增加其视角缩进效果
最后,增加其雾化效果,光源移动效果
通过二维制图视窗(程序中为Editpolygons)用户可以以交互的方式描绘与修改旋转体的轮廓----二维多边形。
多边形在程序中由一个名为vert的数组代表,它的元素为顶点坐标(x,y)。
器显示的形式可以是一系列的点,一条折现或一条闭合折线。
绘制多边形:
通过交互用户可以增加,删除或改变顶点位置进而给代表旋转体的多边形带来相应网格的变化。
当鼠标光标在Editpolygons视窗中时,不按下鼠标键,光标移动将不会产生任何影响。
当按下左键时,就会在现存顶点序列后面加上一个当前光标位置的顶点。
如果这个新顶点是第一个顶点,则他就以点的形式出现。
否则这个顶点就以线段的形式与前一个顶点相连。
在左键保持被保持被按下状态时的任何光标移动都经过橡皮圈技术处理。
释放左键,新顶点与光标脱离。
用户可以把光标移动到一个现存顶点的重力场之内,并压下鼠标右键键就可#####以选中该顶点。
如果选中成功,就可以在保持右键被压下的状态下,改变顶点位置(使用橡皮圈技术),如果选择失败,则不会对图形产生影响。
函数为:
intfindVertex(intx,inty){
如果在Ctrl建被按下的状态下选择点成功的话,可以删除该顶点。
函数为:
voidmouse(intbutton,intstate,intx,inty)
绘制三维旋转体:
在键盘事件处理子程序voidkeyboard(unsignedcharkey,intx,inty)中定义了几个单字指令键:
a用于启动和终止反走样功能;c,C用于清除显示区域,就是删除所有顶点;l,L以线条的方式显示多边形;v,V仅显示顶点
display子函数在多边形绘制视窗正中间画出一条垂直线来作为旋转轴位置的位置视觉指南:
glBegin(GL_LINES);//绘制中间分界线。
另外还画出当前轮廓线相对于旋转轴的镜面反射来突出正在绘制中的物体的完整外形:
initQMesh();。
最后创建与低昂前轮廓相对应的三位模型,并刷新显示视窗:
glutSetWindow(winid);//显示三位物体显示窗口;glutPostRedisplay();。
回调子程序motion函数跟踪鼠标按钮被按下时的光标位置,在这对顶点以橡皮圈方式附属于于光标的有效范围作了限制,这样每个顶点都不会离开绘制视窗的有半侧:
voidmotion(intx,inty){
if(rubberbanding){//如果橡皮圈打开,更新顶点
vert[v][0]=(xwidth/2:
(x>=width)?
width-