1、太阳系运行动画资料大学计算机科学与技术学院课程设计报告2009 2010学年第二学期课程名称 计算机图形学 设计题目 实现太阳系运行动画 学生姓名 学 号 专业班级 指导教师 2010 年 6 月 29 日第1章设计内容与要求1.1总体目标和要求目标:以图形学算法为目标,深入研究。继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到:1)巩固和实践计算机图形学课程中的理论和算法;2)学习表现计算机图形学算法的技巧;3)培养认真学习、积极探索的精神。总体要求:策划、设
2、计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。1.2内容与要求内容:(1)掌握动画基本原理;(2)实现三维几何变换及其组合;功能要求:(1)利用glutWireSphere创建太阳、地球、月亮三个球体;(2)编写三维旋转变换矩阵实现“月亮绕着地球转,地球绕着太阳转”的效果;第2章 总体设计2.1 实验原理 设计利用VC+OpenGL作为开发平台设计程序,实现三维几何变换及其组合等各项功能。OpenGL的基本几何变换函数介绍如下:(1) 平移变换平移变换函数如下:void glTranslatefd(TYPE x,TYPE y,TYPE z);
3、三个函数参数就是目标分别沿三个轴向平移的偏移量。这个函数表示用这三个偏移量生成的矩阵乘以当前矩阵。当参数是(0.0,0.0,0.0)时,表示对函数glTranslate*()的操作是单位矩阵,也就是对物体没有影响。(2) 旋转变换旋转变换函数如下:void glRotatefd(TYPE angle,TYPE x,TYPE y,TYPE z);函数中第一个参数是表示目标沿从点(x,y,z)到原点的方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。这个函数表示用这四个参数生成的矩阵乘以当前矩阵。当角度参数是0.0时,表示对物体没有影响。2.2 动画实现原理双缓存技术:这项技术能使你执行绘图代码
4、时能够在一个屏幕之外的缓冲区内进行渲染,然后用交换命令把图形放到屏幕上。双缓冲技术有两种用途,第一个是有些复杂的图形可能要花很长的时间绘制,而你又不希望图像绘制的所有步骤都被看见,使用双缓冲技术就可以合成一幅图像并在完成后才显示出来。用户永远不会看到不完整的图像,只有整幅图像准备就绪之后才会把它在瞬间置于屏幕之上。双缓冲技术的第二个用处是制作动画。每一帧都在画面外的缓冲区绘制,完成之后再交换到屏幕上。OpenGL支持双缓冲,但是并不是真正用来交换前台缓冲区和后台缓冲区的。实际上,每个OpenGL支持的窗口系统都可以通过一个函数调用glutS();来实现前后缓冲区之间的交换。本此课程设计使用了双
5、缓存模式,程序在空闲时一直不停的调用display函数,这个函数绘制完图像后,改变旋转的角度,然后交换双缓存,这样,每画完一帧就交换,形成了动画。另外,使用了深度缓存,激活了深度测试,这样,被遮挡的面就不会显示,大家可以把激活深度缓存的一行去掉看看效果。大家还可以改变变换的方式,达到不同的效果。第3章 详细设计3.1 球体绘制 绘制球体需要用到Opengl的函数如下:void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); 是画线框球函数。实体绘制函数中,radius表示球体的半径,slices表示球体围绕z轴分割的数目
6、,stacks表示球体沿着z轴分割的数目。 其中太阳、地球和月亮都是用glutWireSphere函数画的。利用glutWireSphere函数可以画出立体感的线框图。代码如下: glutWireSphere( 50.f, 80, 80 );绘制太阳 glutWireSphere( 20.f, 40, 40 );绘制地球 glutWireSphere(7, 10, 10);绘制月球3.2 键盘命令 为了更好的实现交互,添加了“”、“”、“”和“”四个键盘命令。可以以不同的角度来看三个球体的相对运动。运用SpecialKeys(int key, int x, int y)函数的参数来控制以太阳为
7、中心的球体的旋转,函数主要代码如下:if(key = GLUT_KEY_UP) xRot -= 5.0f; if(key = GLUT_KEY_DOWN) xRot += 5.0f; if(key = GLUT_KEY_LEFT) yRot -= 5.0f; if(key = GLUT_KEY_RIGHT) yRot += 5.0f; if(xRot 360.0f) xRot = 0.0f; if(xRot 360.0f) yRot = 0.0f; if(yRot 360.0f或yRot 360.0f时就表示转了一圈,重新置零;xRot -1.0f或yRot = 360 )earthAngle
8、 -= 360; 月球绕地球旋转实现函数glRotatef(earthAngle/30.0*360.0, 0.0f, 0.0f, -1.0f);由于地球绕着太阳转的方向和月球绕着地球转的方向相反所以函数最后一个参数为-1,又月球绕着地球转大概一个月,所以第一个参数为earthAngle/30.0*360.0,月球绕着地球转的速度是地球绕公转的12倍。3.4 球体的显示 当三个球体显示在屏幕上是,在变换窗体的大小时,为了避免显示的图形的变形,所以程序添加了一个ChangeSize( GLsizei w, GLsizei h )子程序。在程序中用到有两个比较重要的投影变换函数,glViewport
9、和glOrtho。glOrtho函数: glOrtho(left, right, bottom, top, near, far), left表示视景体左面的坐标,right表示右面的坐标,bottom表示下面的,top表示上面的。glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。假设有一个球体,半径为1,圆心在(0, 0, 0),那么,我们设定glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);就表示用一个宽高都是3的框框把这个球体整个都装了进来。 如果设定glOrtho(0.0, 1.5, -1.5, 1.5, -1
10、0, 10);就表示用一个宽是1.5, 高是3的框框把整个球体的右面装进来;如果设定glOrtho(0.0, 1.5, 0.0, 1.5, -10, 10);就表示用一个宽和高都是1.5的框框把球体的右上角装了进来。glViewport函数: glOrtho函数只是负责使用什么样的视景体来截取图像,并不负责使用某种规则把图像呈现在屏幕上。glViewport主要完成这样的功能。它负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。假设用一个正方形截面的视景体截取的图像,但是拉伸到屏幕上显示的时候显示屏变宽了, 倒是显示的时候把一个正方形的图像“活生生的给拉宽了”。就会产生变形。这样,就需要调整
11、OpenGL显示屏。因为用的正方形的视景体,所以虽然窗体是那么宽,但是只用其中的长就够了。实现代码:GLfloat nRange = 250.0f;/ 大小 if(h = 0) h = 1;/ 为窗口尺寸设置视角 glViewport(0, 0, w, h); /重设投影映射矩阵堆 glMatrixMode(GL_PROJECTION);/设置当前矩阵为模型视图矩阵 glLoadIdentity(); / 重置当前指定的矩阵为单位矩阵 if (w = h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
12、else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); glMatrixMode(GL_MODELVIEW); glLoadIdentity();SetupRC()函数为显示的设置函数,有设置清空颜色,选择平坦或光滑渐变模式,或被遮住的部分不绘制。3.5 程序缺陷 本程序实现的功能是太阳、地球和月亮的旋转问题,虽然程序实现了,但是还有不足之处。 第一:程序的功能不能实现地球的公转轨道不是真正的公转轨道,月球的也不可以。 第二:地球的公转周期和月球绕地球转的周期的关系不是很精确。 第三:地球和月球虽然自转
13、,但是方向是随机的,不能确定。第4章 功能实现4.1月亮绕着地球转,地球绕着太阳转4.2 键盘命令实现4.3主要的程序清单#include GL/glut.h#include #include static GLfloat xRot = 100.0f;static GLfloat yRot = 0.0f;void SpecialKeys(int key, int x, int y);void ChangeSize( GLsizei w, GLsizei h );void SetupRC();void RenderScene() glClear(GL_COLOR_BUFFER_BIT | GL_
14、DEPTH_BUFFER_BIT);/清空颜色缓冲区,填充的颜色由 glClearColor( 0, 0.0, 0.0, 1 ); 指定为黑色 glPushMatrix();将当前矩阵压入堆栈 glRotatef(xRot, 1.0f, 0.0f, 0.0f);/x,y,z 定义的是转动轴的位置,模型位置和轴位置越远,转的越慢,要是轴穿过模型中心,就是自传 glRotatef(yRot, 0.0f, 1.0f, 0.0f); /绘制太阳 glColor3f( 1.0f, 1.0f, 0.0f );/黄色 glutWireSphere( 50.f, 80, 80 );/画太阳 /绘制地球 sta
15、tic GLfloat earthAngle = 0; const GLfloat RADIUS = 100.f;/绕着太阳转的半径范围 glRotatef( earthAngle, 0, 0, 1 );/x,y,z 定义的是转动轴的位置,模型位置和轴位置越远,转的越慢,要是轴穿过模型中心,就是自传 glTranslatef( 100.f, 100.f, 0 );/物体将在(0.0f,0.0f,0.0f)的位置绘制 glColor3f( 0.1f, 0.1f, 0.7f );/颜色 glutWireSphere( 20.f, 40, 40 ); / 绘制“月亮” glColor3f(1.0f,
16、 1.0f, 1.0f); glRotatef(earthAngle/30.0*360.0, 0.0f, 0.0f, -1.0f); glTranslatef(RADIUS/3, 0.0f, 0.0f); glutWireSphere(7, 10, 10); /转转转转 earthAngle += 0.1; if ( earthAngle = 360 ) earthAngle -= 360; printf( Angle:%fn, earthAngle ); glPopMatrix();弹出先前所压矩阵 glutS();/双缓冲int main(int argc, char* argv) glu
17、tInit(&argc, argv);/对GLUT进行初始化,本函数必须在GLUT使用之前被调用。 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);/设置显示方式 glutInitWindowSize (1250, 700);/设置窗口大小 glutInitWindowPosition (1, 1);/设置窗口在屏幕中的位置 glutCreateWindow( 计算机-07-4-张坤 );/创建窗口,参数作为标题 glutDisplayFunc( RenderScene ); glutIdleFunc (RenderScene)
18、; /glutIdleFunc 表示在CPU空闲的时间调用某一函数 glutReshapeFunc( ChangeSize ); glutSpecialFunc( SpecialKeys ); SetupRC(); glutMainLoop();/设置一个消息循环 return 1;void SetupRC() glClearColor( 0, 0, 0, 1.0 ); glShadeModel( GL_SMOOTH );/选择平坦或光滑渐变模式。GL_SMOOTH为后者 glEnable(GL_DEPTH_TEST);/被遮住的部分不绘制void ChangeSize( GLsizei w,
19、 GLsizei h ) GLfloat nRange = 250.0f;/ 大小 if(h = 0) h = 1;/ 为窗口尺寸设置视角 glViewport(0, 0, w, h); /重设投影映射矩阵堆 glMatrixMode(GL_PROJECTION);/设置当前矩阵为模型视图矩阵 glLoadIdentity(); / 重置当前指定的矩阵为单位矩阵 if (w 360.0f) xRot = 0.0f; if(xRot 360.0f) yRot = 0.0f; if(yRot -1.0f) yRot = 359.0f; glutPostRedisplay();/ 刷新窗口 Rend
20、eScene()第5章 总结本文通过主要利用Visual C+6.0来实现太阳系运行动画。并对太阳系运行动画的实现进行简单的分析和介绍,通过本文以达到对Opengl的应用有一个较清晰的认识。通过本次课程设计,让我学到了很多东西,熟练掌握了使用OpenGL提供的标准库函数,对Opengl有了进一步的了解,同时也让我学会了开发系统的结构理念及一些基本步骤。不足之处就是有些东西我掌握的还不够牢固和不够深入,我以后还须加倍努力。参考文献1 徐文鹏. 计算机图形学 M. 北京:机械工业出版社2 唐荣锡,等. 计算机图形学教程(修订版) M. 北京:科学出版社3 银红霞,等. 计算机图形学 M. 北京:中国水利水电出版社4 孔令德,计算机图形学实践教程 (VisualC+版) 清华大学出版社
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1