计算机图形学课程设计报告.docx

上传人:b****8 文档编号:9179228 上传时间:2023-05-17 格式:DOCX 页数:26 大小:321.35KB
下载 相关 举报
计算机图形学课程设计报告.docx_第1页
第1页 / 共26页
计算机图形学课程设计报告.docx_第2页
第2页 / 共26页
计算机图形学课程设计报告.docx_第3页
第3页 / 共26页
计算机图形学课程设计报告.docx_第4页
第4页 / 共26页
计算机图形学课程设计报告.docx_第5页
第5页 / 共26页
计算机图形学课程设计报告.docx_第6页
第6页 / 共26页
计算机图形学课程设计报告.docx_第7页
第7页 / 共26页
计算机图形学课程设计报告.docx_第8页
第8页 / 共26页
计算机图形学课程设计报告.docx_第9页
第9页 / 共26页
计算机图形学课程设计报告.docx_第10页
第10页 / 共26页
计算机图形学课程设计报告.docx_第11页
第11页 / 共26页
计算机图形学课程设计报告.docx_第12页
第12页 / 共26页
计算机图形学课程设计报告.docx_第13页
第13页 / 共26页
计算机图形学课程设计报告.docx_第14页
第14页 / 共26页
计算机图形学课程设计报告.docx_第15页
第15页 / 共26页
计算机图形学课程设计报告.docx_第16页
第16页 / 共26页
计算机图形学课程设计报告.docx_第17页
第17页 / 共26页
计算机图形学课程设计报告.docx_第18页
第18页 / 共26页
计算机图形学课程设计报告.docx_第19页
第19页 / 共26页
计算机图形学课程设计报告.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

计算机图形学课程设计报告.docx

《计算机图形学课程设计报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学课程设计报告.docx(26页珍藏版)》请在冰点文库上搜索。

计算机图形学课程设计报告.docx

计算机图形学课程设计报告

计算机图形学课程设计报告

 

组号:

第七组

小组成员:

宋洁

邵海军

谷文海

冯新科

学院:

资源环境学院

专业班级:

地科14-2

***********

 

1实习目的

课程设计是信息与计算科学专业集中实践性环节之一,是学习完《计算机图形学》课程后进行的一次全面的综合练习。

其目的是:

(1)要达到理论与实际应用相结合,使学生能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养良好的程序设计技能。

(2)在实践中认识为什么要学习数据结构,掌握数据结构、程序设计语言、程序设计技术之间的关系,是前面所学知识的综合和回顾。

要求

(1)了解并掌握交互式图形系统的设计方法,具备初步的独立分析和设计能力;

(2)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;

(3)提高综合运用所学的理论知识和方法独立分析和解决问题的能;

(4)训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风;

(5)培养学生团结协作,共同完成相关课题的能力。

2课程设计题目

人机交互系统三维图形处理及动画实现

题目要求及内容

要求

创建三维立体图形,通过创建菜单及键盘、鼠标事件实现对图形的人机交互式处理。

在理解直线、圆、区域填充、图形裁剪等理论知识的基础上,借助于程序设计语言VC++和OpenGL三维图形库进行小型图形应用软件或三维场景的开发。

本课程课程设计注重图形交互处理的主要实现,包括如下几部分:

三维立体图形人机交互的处理,主要内容包括以下几点:

(1)创建菜单及键盘事件实现对图形的基本处理;

(2)平移、缩放、旋转等计算机图形的几何变换;

(3)图形的裁剪;

(4)平面投影和透视投影;

(5)消隐和光照处理;

(6)动画的绘制及实现。

附:

二维图形的绘制

主要内容包括以下几点:

(1)点、线、圆、多边形、Bezier曲线等计算机基本图元的的绘制;

(2)点、线、圆、多边形、Bezier曲线等计算机基本图元属性的设置。

内容分析 

定义三维齐次坐标结构和面的结构;定义各图形绕轴旋转的结构及各坐标轴的放缩结构;

定义各个光源的属性及材质表面的属性;

定义键盘输入及鼠标输入对应响应的事件;

定义各菜单对应执行的响应事件;

通过双缓存技术实现动画效果。

实习原理

人机交互

人机交互主要包括鼠标输入、键盘输入以及创建菜单执行对应的处理事件,其基本原理如下:

鼠标:

1)检测鼠标Clicks

GLUT为处理鼠标clicks事件提供了一个方法。

函数glutMouseFunc,这个函数一般在程序初始化阶段被调用。

函数原型如下:

voidglutMouseFunc(void(*func)(intbutton,intstate,intx,inty));

参数:

func:

处理鼠标click事件的函数的函数名。

从上面可以看到到,处理鼠标click事件的函数,一定有4个参数。

第一个参数表明哪个鼠标键被按下或松开,这个变量可以是下面的三个值中的一个:

GLUT_LEFT_BUTTON

GLUT_MIDDLE_BUTTON

GLUT_RIGHT_BUTTON

第二个参数表明,函数被调用发生时,鼠标的状态,也就是是被按下,或松开,可能取值如下:

GLUT_DOWN

GLUT_UP

当函数被调用时,state的值是GLUT_DOWN,那么程序可能会假定将会有个GLUT_UP事件,甚至鼠标移动到窗口外面,也如此。

然而,如果程序调用glutMouseFunc传递NULL作为参数,那么GLUT将不会改变鼠标的状态。

剩下的两个参数(x,y)提供了鼠标当前的窗口坐标(以左上角为原点)。

2)检测动作(motion)

GLUT提供鼠标motion检测能力。

有两种GLUT处理的motion:

activemotion和passivemotion。

Activemotion是指鼠标移动并且有一个鼠标键被按下。

Passivemotion是指当鼠标移动时,并有没鼠标键按下。

如果一个程序正在追踪鼠标,那么鼠标移动期间,每一帧将产生一个结果。

GLUT让我们可以指定两个不同的函数,一个追踪passivemotion,另一个追踪activemotion。

它们的函数原型,如下:

voidglutMotionFunc(void(*func)(intx,inty));

voidglutPassiveMotionFunc(void(*func)(intx,inty));

参数:

Func:

处理各自类型motion的函数名。

处理motion的参数函数的参数(x,y)是鼠标在窗口的坐标。

以左上角为原点。

3)检测鼠标进入或离开窗口

GLUT还能检测鼠标鼠标离开,进入窗口区域。

一个回调函数可以被定义去处理这两个事件。

GLUT里,调用这个函数的是glutEntryFunc,函数原型如下:

voidglutEntryFunc(void(*func)(intstate));

参数:

Func:

处理这些事件的函数名。

上面函数的参数中,state有两个值:

GLUT_LEFT

GLUT_ENTERED

表明,是离开,还是进入窗口。

键盘:

当你按下一个键后,GLUT提供了两个函数为这个键盘消息注册回调。

1)第一个是glutKeyboardFunc。

这个函数是告诉窗口系统,哪一个函数将会被调用来处理普通按键消息。

普通键是指字母,数字,和其他可以用ASCII代码表示的键。

函数原型如下:

voidglutKeyboardFunc(void(*func)(unsignedcharkey,intx,inty));

参数:

func:

处理普通按键消息的函数的名称。

如果传递NULL,则表示GLUT忽略普通按键消息。

这个作为glutKeyboardFunc函数参数的函数需要有三个形参。

第一个表示按下的键的ASCII码,其余两个提供了,当键按下时当前的鼠标位置。

鼠标位置是相对于当前客户窗口的左上角而言的。

2)GLUT提供函数glutSpecialFunc以便当有特殊键按下的消息时,你能注册你的函数。

函数原型如下:

voidglutSpecialFunc(void(*func)(intkey,intx,inty));

参数:

func:

处理特殊键按下消息的函数的名称。

传递NULL则表示GLUT忽略特殊键消息。

菜单:

弹出式菜单(像点鼠标右键出来的菜单那样的)也是GLUT的一部分,虽然它不能实现我们经常看到的windows系统弹出式菜单的所有的功能,但是它也有很大的作用。

给一个程序增加菜单提供了一个比键盘更简单的方法来和程序交互,选择不同选项,而不用去记那些按键。

1)创建菜单:

创建菜单函数glutCreateMenu的原型如下:

intglutCreateMenu(void(*func)(intvalue));

参数:

 func:

为新建的菜单处理菜单事件的函数名。

这个函数的返回值是菜单的标识符(menuidentifier)。

2)菜单增加条目:

出来个空菜单也没什么用,使用的函数是glutAddMenuEntry:

voidglutAddMenuEntry(char*name,intvalue);

参数:

 name:

菜单名称的字符串。

 value:

当你选择菜单里的一项后,这个值就返回给上面的glutCreateMenu里调用的函数。

3)联接鼠标:

必须指定菜单怎么出现,使用GLUT你可以在按下一个鼠标按键后让菜单显示,函数是glutAttachMenu:

voidglutAttachMenu(intbutton);

参数:

 button:

一个整数,指定菜单和哪个鼠标键关联起来。

botton可以去下面的值;

 GLUT_LEFT_BUTTON

 GLUT_MIDDLE_BUTTON

 GLUT_RIGHT_BUTTON

用glutAttachMenu来在鼠标和菜单间建立关联,但我们有时候需要断开这种关联。

完成这个工作的函数是glutDetachMenu。

函数原型如下:

voidglutDetachMenu(intbutton);

参数:

 button:

要断开的鼠标按键。

Button的取值和glutAttachMenu一样。

最后,如果你想恢复被菜单使用了的资源,我们可以销毁(destroy)它,相应的函数是glutDestroyMenu,它的原型如下:

voidglutDestroyMenu(intmenuIdentifier);

参数:

 menuIdentifier:

要销毁的菜单的标识符,它必须和函数glutCreateMenu返回的值相同。

4)子菜单的建立:

和我们前面用的建立菜单的函数一样。

建立菜单后我们把子菜单作为一个条目添加进去。

使用函数glutAddSubMenu来完成这项工作:

voidglutAddSubMenu(char*entryName,intmenuIndex);

参数:

entryName:

子菜单名称。

menuIndex:

子菜单索引,这个就是我们调用glutCreateMenu来创建子菜单返回的值。

动画

计算机动画与实际的动画有些不同,实际的动画都是先画好,播放的时候直接显示出来,计算机动画则是一边画一边显示,通过双缓存技术将后台绘制好的图形与前台图形交换,这样循环反复,屏幕上便呈现出我们所看到的动画。

计算机实现动画主要启动双缓冲功能,在主函数里启用双缓冲:

glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);

当每次绘制完成时,我们需要交换两个缓冲区,把绘制好的信息显示到屏幕。

为了完成这一工作,我们在绘图函数里调用glutSwapBuffers()便很好的实现了动画前台与后台的光滑交换显示,达到了动画效果。

几何变换

二维几何图形变换

对于几何变换主要通过与变换矩阵的矩阵运算改变顶点坐标(用齐次坐标)来实现:

例如:

(1)放缩:

(2)旋转:

(3)

关于x轴对称:

(4)关于原点对称:

(5)沿X轴方向的错切变换:

三维几何图形变换:

三维几何图形变换原理同二维几何图形变换,只是采用的变换矩阵为4×4矩阵,空间点[xyz]采用四维齐次坐标[XYZ1]表示。

2、OpenGL环境下的几何变换

基本变换函数:

(1)平移矩阵构造函数为glTranslate(tx,ty,tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘。

tx,ty,tz指定这个移动物体的矩阵,它们可以是任意的实数值,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维应用来说,tz=。

(2)旋转矩阵构造函数为glRotate(theta,vx,vy,vz),作用是把当前矩阵和一个表示旋转物体的矩阵相乘。

theta,vx,vy,vz指定这个旋转物体的矩阵,物体将绕着(0,0,0)到(x,y,z)的直线以逆时针旋转,参数theta表示旋转的角度。

向量v=(vx,vy,vz)的分量可以是任意的实数值,该向量用于定义通过坐标原点的旋转轴的方向,后缀为f(单精度浮点float)或d(双精度浮点double),对于二维旋转来说,vx=,vy=,vz=。

(3)缩放矩阵构造函数为glScale(sx,sy,sz),作用是把当前矩阵和一个表示缩放物体的矩阵相乘。

sx,sy,sz指定这个缩放物体的矩阵,分别表示在x,y,z方向上的缩放比例,它们可以是任意的实数值,当缩放参数为负值时,该函数为反射矩阵,缩放相对于原点进行,后缀为f(单精度浮点float)或d(双精度浮点double)。

假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。

那么,经过变换得到的顶点坐标就是((RT)v)。

由于矩阵乘法满足结合率,((RT)v)=R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。

即:

实际变换的顺序与代码中写的顺序是相反的。

由于“先移动后旋转”和“先旋转后移动”得到的结果很可能不同,初学的时候需要特别注意这一点。

由于模型变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。

设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:

glMatrixMode(GL_MODELVIEW);

该语句指定一个4×4的建模矩阵作为当前矩阵。

通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。

把当前矩阵设置为单位矩阵的函数为:

glLoadIdentity();

我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。

当我们需要保存时,调用glPushMatrix()函数,它相当于把当前矩阵压入堆栈。

当需要恢复最近一次的保存时,调用glPopMatrix()函数,它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。

OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。

因此不必过于担心矩阵的容量问题。

通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。

注意:

模型视图矩阵和投影矩阵都有相应的堆栈。

使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵。

OpenGL环境下三维图形变换相关函数:

(1)glMatrixMode(GLenummode)//设置当前矩阵类型

(2)glLoadMatrix{fd}(constTYPE*m)//用指定的矩阵替换当前矩阵

(3)glLoadIdentity(void)//用单位矩阵替换当前矩阵

(4)glMultMatrix{fd}(constTYPE*m)//用当前矩阵去乘*m所指定的矩阵,并将结果存放与*m中

(5)glTranslate{fd}(TYPEx,TYPEy,TYPEz)//平移变换函数

(6)glRotate{fd}(TYPEangle,TYPEx,TYPEy,TYPEz)//旋转变换函数

(7)glScale{fd}(TYPEx,TYPEy,TYPEz)//缩放和反射变换函数

(8)glPushMatrix(void);glPopMatrix(void);//堆栈操作函数

 

3主要流程图

三维图形处理流程图

 

图3-1三维图形处理流程图

 

二维几何画板流程图

 

图3-2二维几何画板流程图

4主要源程序

主要源程序

程序主要由绘制图形、创建菜单、添加光照、几何变换及视点等基本功能组成,程序实现由以下几个基本图形绘制程序:

voidmyDisplay(void)

{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glTranslated(0,0,-60);

立方体();

球();

月亮();

路面();

仓库();

房子();

太阳();

行星();

天桥();

glPopMatrix();

glFlush();

glutSwapBuffers();

}

视点设置:

gluLookAt(-1,-1,1,-1,1,1,0,0,1);//XOZ面

gluLookAt(-1,-1,1,-1,-1,0,0,1,0);//XOY面

光照设置:

glEnable(GL_LIGHTING);//启动光照

glDisable(GL_LIGHTING);//关闭光照

注册鼠标事件:

glutMotionFunc(myMouseMotion_旋转);

glutMotionFunc(myMouseMotion_移动);

glutMouseFunc(myMouse_放大);

glutMouseFunc(myMouse_缩小);

主函数:

intmain(intargc,char*argv[])

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);

glutInitWindowPosition(300,50);

glutInitWindowSize(winWidth,winHeight);

glutCreateWindow("计算机图形处理课程设计——三维图形处理");

init();

init1();

glutDisplayFunc(&myDisplay);

glutReshapeFunc(Reshape);

createGLUTMenus();

glutKeyboardFunc(keyboard);

glutIdleFunc(&myAnimate);//设置全局空闲回调函数

glutMainLoop();

return0;

}

图4-1三维图形处理运行初始图形

键盘事件函数

voidkeyboard(unsignedcharkey,intx,inty)

{

switch(key)

{

case'y':

year=(year+1)%360;

if(year==2*(int)(acos/*180/PI))

year=-year;

glutPostRedisplay();break;

case'Y':

year=(year-1)%360;

if(year==-2*(int)(acos/*180/PI))

year=-year;

glutPostRedisplay();break;

default:

break;

}

}

图4-2键盘事件运行图

菜单

创建菜单函数

voidprocessMenuEvents(intoption)

{

switch(option)

{

case恢复:

glutMouseFunc(NULL);

glutMotionFunc(NULL);

glDisable(GL_LIGHTING);

init1();break;

case旋转:

glutMouseFunc(NULL);

glutMotionFunc(myMouseMotion_旋转);break;

case移动:

glutMouseFunc(NULL);

glutMotionFunc(myMouseMotion_移动);break;

case启动光照:

glEnable(GL_LIGHTING);break;

case关闭光照:

glDisable(GL_LIGHTING);break;

case放大:

glutMotionFunc(NULL);

glutMouseFunc(myMouse_放大);break;

case缩小:

glutMotionFunc(NULL);

glutMouseFunc(myMouse_缩小);break;

caseXOZ面:

glLoadIdentity();

gluLookAt(-1,-1,1,-1,1,1,0,0,1);break;

caseXOY面:

glLoadIdentity();

gluLookAt(-1,-1,1,-1,-1,0,0,1,0);break;

default:

break;

}

}

voidcreateGLUTMenus()

{

intmenu,submenu1,submenu2,submenu3;

submenu1=glutCreateMenu(processMenuEvents);

glutAddMenuEntry("启动光照",启动光照);

glutAddMenuEntry("关闭光照",关闭光照);

submenu2=glutCreateMenu(processMenuEvents);

glutAddMenuEntry("旋转",旋转);

glutAddMenuEntry("移动",移动);

glutAddMenuEntry("放大",放大);

glutAddMenuEntry("缩小",缩小);

submenu3=glutCreateMenu(processMenuEvents);

glutAddMenuEntry("XOZ面",XOZ面);

glutAddMenuEntry("XOY面",XOY面);

menu=glutCreateMenu(processMenuEvents);

glutAddSubMenu("环境设置",submenu1);

glutAddSubMenu("几何变换",submenu2);

glutAddSubMenu("视图设置",submenu3);

glutAddMenuEntry("恢复",恢复);

glutAttachMenu(GLUT_RIGHT_BUTTON);

}

图4-3创建菜单运行图

光照函数

voidinit()

{

GLfloatlight1_ambient[]={,,,};

GLfloatlight1_diffuse[]={,,,};

GLfloatlight1_specular[]={,,,};

GLfloatlight1_position[]={,,,};

GLfloatlight2_ambient[]={,,,};

GLfloatlight2_diffuse[]={,,,};

GLfloatlight2_specular[]={,,,};

GLfloatlight2_position[]={,,,};

GLfloatlight3_ambient[]={,,,};

GLfloatlight3_diffuse[]={,,,};

GLfloatlight3_specular[]={,,,};

GLfloatlight3_position[]={,,,};

GLfloatspot0_direction[]={,,};

GLfloatspot3_direction[]={,,};

glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);

glLightfv(GL_LIGHT1,GL_DIFFU

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2