1、计算机图形课程设计报告课程设计报告课程名称: 计算机图形学 任课教师: 姓 名: 学 号: 1. 引言1.1. 课程设计项目创建旋转体总结报告1.2. 编写背景1.概述计算机图形学(Computer Graphics,简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。2.主要组成图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。从构成要素上看,图形主要分为两类,一类是几何要素在构图中具有突出作用的图形,如工程图、等
2、高线地图、曲面的线框图等,另一类非几何要素在构图中具有突出作用的图形,如明暗图、晕渲图、真实感图形等。3.主要目的计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目的真实感图形。为此,必须建立图形所描述的场景的几何表示,再用某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关系。事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实体造型技术作为其主要的研究内容。同时,真实感图形计算的结果是以数字图像的方式提供的,计算机图形学也就和图像处理有着密切的关系。4.概念区分图形与图像两个概念间的区别越来越模糊,但还是有区别
3、的:图像纯指计算机内以位图形式存在的灰度信息,而图形含有几何属性,或者说更强调场景的几何表示,是由场景的几何模型和景物的物理属性共同组成的。#5.研究内容计算机图形学的研究内容非常广泛,如图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法、非真实感绘制,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。1.3.相关概念OpenGl用于编写计算机图形学的程序的编译工具。OpenGL是行业领域中最为广泛接纳的 2D/3D 图形 API, 其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。OpenGL 是独立于视窗操作系统或其它操
4、作系统的,亦是网络透明的。在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL 帮助程序员实现在 PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。旋转体一条平面曲线绕着它所在的平面内的一条定直线旋转所形成的曲面叫作旋转面;封闭的旋转面围成的几何体。3.旋转矩阵在乘以一个向量的时候有改变向量的方向但不改变大小的效果的矩阵。旋转矩阵不包括反演,它可以把右手坐标系改变成左手坐标系或反之。所有旋转加上反演形成了正交矩阵的集合。旋转变换简称旋转.欧氏几何中的一种重要变换.即在欧氏平面上(欧氏空间中),让每一点P绕一固定
5、点(固定轴线)旋转一个定角,变成另一点P,如此产生的变换称为平面上(空间中)的旋转变换.。变换矩阵在线性代数中,线性变换能够用矩阵表示。如果T是一个把R映射到R的线性变换,且x是一个具有n个元素的列向量 ,那么我们把mn的矩阵A,称为T的变换矩阵。#3D坐标系三维笛卡儿坐标系是在二维笛卡儿坐标系的基础上根据右手定则增加第三维坐标(即Z轴)而形成的。2D坐标系在同一个平面上互相垂直且有公共原点的两条数轴构成平面直角坐标系。1.4.编写目的 经过本学期对计算机图形学的学习,对其进行初步的掌握,通过OpenGL编程,对所学内容进行实际应用并发现学习中存在的问题,也是对自己学习工作的检验和测试,在撰写
6、报告的过程中能够更深刻的了解计算机图形学的理念通过这份文档来记录实践过程中遇到的问题以及改善的方法。现在对整个过程加以认识、记录和总结,留下经验,汲取教训。为以后的其他工作积攒经验,为以后遇到相同的问题和从事类似项目奠定坚实的基础,以便以后有资可寻、有底可查,增长个人见识,1.5. 相关文献Computer Graphics with OpenGLDonald Hearn M.Pauline BakerOpenGL编程手册VC+编程手册;2产品2.1设计分析1. 一个旋转体由其外轮廓线绕其竖直中心轴旋转而成。2. 程序要求建立一个窗口显示竖直的中心轴,并且要求实现轮廓线的编辑,具体包含功能:节
7、点的增加、删除和节点间自动连线。3. 程序要求建立另外一个窗口显示轮廓线绕中心轴旋转以后的三维物体,本窗口还要求实现三维物体的Phong着色和对三维物体的简单操作,具体包含:放大、缩小和旋转。4. 移动光源#5. 纹理映射效果6. 雾化效果2.2总体设计1.项目规划:本系统是一个基于OpenGL开发的实现能够进行人机交互的绘制3D旋转体的系统,本系统中的功能模块主要分为以下几种: 矩阵运算模块:实现两个或多个矩阵的相关运算,为绘制图形提供数据结构,体现图形转化过程中的算法。显示图形模块:用于设定图像的显示方式,绘制方法,在其中还可以设置光源位置等相关的显示信息。键盘敲击模块:对不同的键盘敲击事
8、件作出相应的处理,包括点线的转化,雾化效果等。鼠标点击模块:在3D显示窗口添加的鼠标事件,对鼠标的事件作出相应的响应效果。 动作模块:根据左边用户绘制的2D图形,动态的划出右面相对应的3D图像。找点模块:在左边的用户画图窗口进行锁定鼠标点击时靠近的点。2.系统功能结构下图写于此3设计目标本系统是根据课本中的程序而开发的,基本能够实现需求中所要求的功能,通过本系统可以达到以下目标: 1系统运行稳定,安全可靠。2界面美观、友好。3用户操作使用方便。4生成的3D图形效果良好。5能够正确的生成用户所要绘制的3D图形2.3.主要功能模块设计1矩阵运算模块的设计:功能描述:程序启动后,这部分功能模块会为整
9、个应用程序提供算法支持,具体是矩阵直接的相互运算,在2D向3D转化过程中会起到很重要的作用。代码设计:float vv(float * v1, float * v2) return v10 * v20 + v11 * v21 + v12 * v22;#void vxv(float * n, float * v1, float * v2) n0 = v11 * v22 - v12 * v21; n1 = v12 * v20 - v10 * v22; n2 = v10 * v21 - v11 * v20;void loadIdentity(Matrix m) Matrix identity = 1
10、.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(int i = 0;i 4; i+) for(int j = 0;j 4; j+) mij = identityij;void preMultiply(Matrix p, Matrix m) int i , j; Matrix t; for( i = 0; i 4; i +) for( j = 0; j 4; j+) tij = pi0 * m0j + pi1 * m1j + pi2 * m2j + pi3 * m3j; for( i = 0; i 4;
11、 i +) for( j = 0; j 4; j +) mij = tij;2显示图形模块的设计: 功能描述:该模块主要为所要画的图形进行描述,是绘制图形的主要函数,通过调用这个功能模块就能画出用于显示给用户的图形。 代码设计:/2D图形的display函数void display() glClear(GL_COLOR_BUFFER_BIT); if(n = 1 & type =GL_LINE_STRIP) glBegin(GL_POINTS); glVertex2iv(vert0); glColor3f(0,0.5,0.5); glVertex2i(width-vert00-1,vert01
12、); glEnd(); glColor3f(0,0.5,0.5);# glBegin(GL_LINES); glVertex2i(width/2,0); glVertex2i(width/2,height-1); glEnd(); glBegin(type); for(int i = 0;in;i+) glVertex2i(width-verti0-1,verti1); glEnd(); glColor3f(1,1,0); glBegin(type); for(int i = 0;in;i+) glVertex2iv(verti); glEnd(); glutSwapBuffers(); in
13、itQMesh(); glutSetWindow(winid); glutPostRedisplay(); /3D图形的显示函数void modelDisplay() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); float M16; for(int r = 0; r 4; r+) for(int c = 0; c 4; c+) M4 * c + r = CRMrc; glMultMatrixf(M); glScalef(zoom,zoom,zoom); drawQMesh(); glPopMatrix(
14、); glPushMatrix(); glLightfv(GL_LIGHT0,GL_AMBIENT,amb); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glPopMatrix(); glutSwapBuffers();3键盘敲击模块 功能描述:该功能主要为两个窗体添加键盘敲击事件,在2D窗体中主要添加了反走样效果,清除所画的图,点线转化功能,对于3D窗体主要添加了投影方式的变换,雾化效果,光源移动的功能代码设计:/2D绘制窗体的键盘敲击处理函数void keyboard(unsigned char key, int x,int y)
15、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; /绘制点功能 glutPost
16、Redisplay();/3D显示窗体的键盘敲击事件处理函数:void modelKeyboard(unsigned char key, int x, int y) 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
17、.0,6.0,14.0); glMatrixMode(GL_MODELVIEW); break; case m:lightPosition0 = lightPosition0 - 0.5; /光源移动 break; case n:lightPosition1 = lightPosition1 - 0.5; break; case z:lightPosition2 = lightPosition2 - 0.5; break; case q:glEnable(GL_FOG); / 雾化效果 glFogi(GL_FOG_MODE, GL_LINEAR); GLfloat fogColor = 1.9
18、, 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窗
19、体的鼠标事件void modelMouse(int button,int state,int x,int y) switch (button) case GLUT_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; case GLUT_RIGHT_BUTTON: if(state = GLUT_DOWN) cx = x; cy = h - 1 - y; right_button
20、_down = true; else right_button_down = false; break; /2D窗体鼠标事件void mouse(int button, int state, int x ,int y) y = height - 1 - y; switch(button) case GLUT_LEFT_BUTTON:# if(state = GLUT_DOWN & ! rubberbanding ) v = n+; vertv0 = (x = width) ? width - 1 : x; vertv1 = (y = height) ? height -1 : y; rubbe
21、rbanding = true; glutPostRedisplay(); else rubberbanding = false; break; case GLUT_RIGHT_BUTTON: if(state = GLUT_DOWN & ! rubberbanding & (v = findVertex(x,y) != -1) if(glutGetModifiers() = GLUT_ACTIVE_CTRL) for (int i = v; i n-1; i+) vertv0 = verti+10; verti1 = verti+11; n-; else vertv0 = (x = widt
22、h) ? width - 1 : x; vertv1 = (y = height) ? height -1 : y; rubberbanding = true; glutPostRedisplay(); else rubberbanding = false; break; 5找点模块功能描述:此方法主要用于对用户所需要的点进行锁定。能够改变原来已经存在的点。int findVertex(int x,int y) /锁定鼠标靠近的点 int dx,dy; for(int i = 0;i n;i+) dx = verti0-x; dy = verti1-y; if(dx*dx + dy*dy 16
23、) return i; return -1;#2.4.主要功能和性能a. 通过Edit polygons窗口(二维多边形编辑视窗)绘制多边形。b. 对绘制出的多边形能增删顶点改变多边形形状。c. 通过Object window:李文云,向明海窗口(三维旋转体显示视窗)显示在二维多边形编辑视窗中编辑好的旋转体轮廓的三维旋转体映射。d. 在三维旋转体显示视窗中通过o键切换到正投影显示,通过p键切换到透视投影投影显示e. 在三维旋转体显示视窗中:1) 通过小写字母x用于对电光源位置的x坐标做减量操作,大写字母X用于对电光源位置的x坐标做增量操作;2) 小写字母y用于对电光源位置的x坐标做减量操作,大
24、写字母Y用于对电光源位置的y坐标做增量操作;3) 小写字母z用于对电光源位置的z坐标做减量操作,大写字母Z用于对电光源位置的z坐标做增量操作;4) 字母f、F用于开启雾化效果,小写字母n用于关闭雾化效果f. 在三维旋转体显示视窗中,通过按下鼠标右键同时移动光标来改变三维旋转体大小g. 在三维旋转体显示视窗中,通过按下鼠标左键同时移动光标来转动三维旋转体。说明:原定的开发目标达到了。所要求的全部实现附加要求实现了移动光源,雾化效果两项。2.5基本流程这个程序使用VS为编译工具,使用C+语言,运用OPENGL技术,使窗口能够动态的接收用户的输入信息,包括鼠标和键盘的事件响应,使用户能够画出自己想要
25、的对称二维图形,再由程序将其转换为三维图像,并最终实现三维图像的各种#操纵功能,具体实现是一个一个窗体进行实现的Edit polygons窗体的实现:首先,绘制基本窗体,包括左边,色调等内容接着,绘制中轴线及相关的内容接着,在窗体中加入键盘和鼠标的事件截获功能,使其能捕获鼠标或键盘的事件接着,制作点绘制线的功能,将线绘制成几何图形。接着,利用中轴线使线的坐标关于中轴对称,使其成为对称图形接着,添加反走样效果,添加清楚界面功能,添加绘制线和绘制点的功能。Display Object窗口的实现首先,绘制基本窗体,包括左边,色调等内容接着,通过第一个窗体的内容绘制三维图形接着,实现其视角的转移接着,
26、增加其视角缩进效果最后,增加其雾化效果,光源移动效果通过二维制图视窗(程序中为Edit polygons)用户可以以交互的方式描绘与修改旋转体的轮廓-二维多边形。多边形在程序中由一个名为vert的数组代表,它的元素为顶点坐标(x , y)。器显示的形式可以是一系列的点,一条折现或一条闭合折线。绘制多边形:通过交互用户可以增加,删除或改变顶点位置进而给代表旋转体的多边形带来相应网格的变化。当鼠标光标在Edit polygons视窗中时,不按下鼠标键,光标移动将不会产生任何影响。当按下左键时,就会在现存顶点序列后面加上一个当前光标位置的顶点。如果这个新顶点是第一个顶点,则他就以点的形式出现。否则这
27、个顶点就以线段的形式与前一个顶点相连。在左键保持被保持被按下状态时的任何光标移动都经过橡皮圈技术处理。释放左键,新顶点与光标脱离。用户可以把光标移动到一个现存顶点的重力场之内,并压下鼠标右键键就可#以选中该顶点。如果选中成功,就可以在保持右键被压下的状态下,改变顶点位置(使用橡皮圈技术),如果选择失败,则不会对图形产生影响。函数为:int findVertex(int x,int y) 如果在Ctrl建被按下的状态下选择点成功的话,可以删除该顶点。函数为:void mouse(int button, int state, int x ,int y)绘制三维旋转体:在键盘事件处理子程序void
28、keyboard(unsigned char key, int x,int y)中定义了几个单字指令键:a用于启动和终止反走样功能; c,C用于清除显示区域,就是删除所有顶点; l,L以线条的方式显示多边形; v,V仅显示顶点display子函数在多边形绘制视窗正中间画出一条垂直线来作为旋转轴位置的位置视觉指南: glBegin(GL_LINES); /绘制中间分界线。另外还画出当前轮廓线相对于旋转轴的镜面反射来突出正在绘制中的物体的完整外形: initQMesh();。最后创建与低昂前轮廓相对应的三位模型,并刷新显示视窗: glutSetWindow(winid);/显示三位物体显示窗口 ;glutPostRedisplay();。回调子程序motion函数跟踪鼠标按钮被按下时的光标位置,在这对顶点以橡皮圈方式附属于于光标的有效范围作了限制,这样每个顶点都不会离开绘制视窗的有半侧: void motion(int x, int y) if(rubberbanding)/如果橡皮圈打开,更新顶点 vertv0 = (x = width) ? width -
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1