1、opengl实现太阳地球及月亮的运动模型和小球的自由落体运动实验六1、 实验目的和要求了解且掌握OpenGL中包含的有关三维变换的操作,并且做出模型视图变换、投影变换和视见区变换的实例。2、 实验内容1)在OpenGL中绘制太阳、地球和月亮的运动模型。2)在OpenGL中创建一个球体动画,使球体在窗口内做自由落体运动,并在撞击地面(窗口的下边界)后能够弹回原来的高度。3、 实验步骤1) 相关算法及原理描述1 矩阵堆栈在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到变换后的形体顶点的其次坐标矩阵,这样只要求出形体三维变换矩阵,就可以得
2、到变换后的形体。在OpenGL中,对象的变换也是通过矩阵来实现的。在进行矩阵操作前,需要指定当前操作的矩阵对象,可以使用函数glMatrixMode(GLenum mode); 定义。矩阵堆栈主要用来保存和恢复矩阵的状态,主要用于具有层次结构的模型绘制中,以提高绘图效率。利用函数void glPushMatrix(void); Void glPopMatrix(void); 实现矩阵堆栈的操作。矩阵堆栈是有深度的,如果超出了堆栈深度或当堆栈为空时试图弹出栈顶矩阵,都会发生错误。可以用下面函数获得堆栈深度的最大值: glGet(GL_MAX_MODELVIEW_STACK_DEPTH); glG
3、et(GL_MAX_PROJECTION_STACK_DEPTH); 2 模型视图变换模型视图矩阵是一个4*4的矩阵,用于指定场景的视图变换和几何变换。在进行模型视图矩阵操作前,必须调用函数glMatrixMode(GL_MODELVIEW)指定变换只能影响模型试图矩阵。主要有以下两种方法。121、直接定义矩阵利用函数 void glLoadMartrixfd(const TYPE *m);将m所指定的矩阵置为当前矩阵堆栈的栈顶矩阵。 122、利用高级矩阵函数 平移矩阵函数:void glTranslatedf(TYPE x,TYPE y,TYPE z); 用当前矩阵乘以平移矩阵。 旋转矩阵函
4、数 void glRotatedf(TYPE angle,TYPE x,TYPW y,TYPE z); 缩放矩阵函数 void glScaledf(TYPE x,TYPE y,TYPE z); 如不需要效果积累可调用重置矩阵函数void glLoadIdentity(void); 该函数将单位矩阵置为当前变换矩阵。3 投影变换有两种投影方式,不管调用哪种,必须调用glMAtrixMode(GL_PROJECTION);指定当前处理的矩阵是投影变换矩阵。131、正投影 它的有限观察空间是一个长方体,无论物体距离相机多远,投影后的物体大小尺寸不变。正投影函数有两个:void glOrtho(GLd
5、ouble left,GLdouble right,GLdouble botton,GLdouble top,GLdouble near,GLdouble far); void gluOrtho2D(GLdouble left,GLdouble right,GLdoubl botton,GLdouble top); 1.3.2、透视投影特点是距离视点近的物体大,距离视点远的物体小,远到极点即为消失。透视投影函数也有两个: void glFrustum(GLdouble left,GLdouble Right,GLdouble botton,GLdouble top,GLdouble near,
6、GLdouble far); void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);2) 程序调试、测试与运行结果分析1 太阳、地球和月亮的运动模型2 小球的自由落体运动4、 附录(1)太阳、地球和月亮的运动模型#include static int day = 200;void display() glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PRO
7、JECTION); glLoadIdentity(); gluPerspective(75,1,1,400000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,-200000,200000, 0,0,0, 0,0,1); glColor3f(1,0,0);/sun glutSolidSphere(69600,20,20); glColor3f(0,0,1); glRotatef(day,0,0,-1); glTranslatef(150000,0,0);/earth glutSolidSphere(15945,20,20
8、); glColor3f(1,1,0); glRotatef(day/30.0*360 - day, 0,0,-1); glTranslatef(38000,0,0);/moon glutSolidSphere(4345,20,20); glutSwapBuffers();void timer(int p) day +; if(day 360)day = 0; glutTimerFunc(50,timer,0); glutPostRedisplay();int main(int argc,char *argv) glutInit(&argc,argv); glutInitDisplayMode
9、(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow(earth,moon,sun); glutInitWindowSize(400,400); glutDisplayFunc(display); glutTimerFunc(50,timer,0); glutMainLoop(); return 0;(2)小球的自由落体运动#include#include#include#include#include#define PI 3.1415926double move=20.0;int i=0;int down=1;int count=1;double timeSp
10、an=0; /下降到底所需时间double movey=0.0;double duration=0.0; /持续时间double length=0.0;clock_t start,end;void init(void) printf( init); GLfloat mat_specular=220.220,220.0,220.0,220.0; GLfloat mat_shininess=70.0; GLfloat light_position=0.0, 0.0, 0.0, -2.0; /r-l u-d f-b GLfloat ambientLight = 0.2f, 0.2f, 0.2f, 1
11、.0f ; GLfloat diffuseLight = 0.6f, 0.6f, 0.6f, 1.0f ; GLfloat specular = 1.0f, 1.0f, 1.0f, 1.0f; glClearColor(0.3,0.8,0.8,0.0); /bgc glColor3ub(23, 17, 215); glShadeModel(GL_SMOOTH); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGH
12、T0,GL_AMBIENT,ambientLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); glLightfv(GL_LIGHT0,GL_SPECULAR,specular); glLightfv(GL_LIGHT0,GL_POSITION,light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); /启用深度测试void reshape(int w,int h) printf( reshape); glViewport(0,
13、0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w19.932) move=20; down=1; printf(%i,down); start=clock(); display(); glLoadIdentity(); void MoveSphereDown() if(count=1) start=clock(); count=0; end=clock(); duration = (double)(end - start) /CLOCKS_PER_SEC; length=5*duratio
14、n*duration; move=20-length; if(move-20) timeSpan=duration; /记下下降所经历的时间 move=-20; start=clock(); down=0; /向上运动 display(); glLoadIdentity();void TimerFunc2(int value) if(i=0) /left GLfloat light_position=2.0,0.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=1) /left-up GL
15、float light_position=2.0,2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=2) /up GLfloat light_position=0.0,2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=3) /up-right GLfloat light_position=-2.0,2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_L
16、IGHT0,GL_POSITION,light_position); if(i=4) /right GLfloat light_position=-2.0,0.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=5) /right-down GLfloat light_position=-2.0,-2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=6) /down GLfloat l
17、ight_position=0.0,-2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); if(i=7) /down-left GLfloat light_position=2.0,-2.0,0.0,0.0; /r-l u-d f-b glLightfv(GL_LIGHT0,GL_POSITION,light_position); i=(+i)%8; printf(%i,i); glutTimerFunc(60,TimerFunc2,1);void TimerFunc1(int value) if
18、(down=1) MoveSphereDown(); if(down=0) MoveSphereUp(); glutTimerFunc(10,TimerFunc1,0);int main(int argc,char *argv) glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(400,740); glutInitWindowPosition(300,20); glutCreateWindow(小球自由落体运动); init(); glutDisplayFunc(initDisplay); glutReshapeFunc(reshape); glutTimerFunc(1400,TimerFunc1,0); /毫秒 glutTimerFunc(400,TimerFunc2,1); /毫秒 glutMainLoop(); return 0;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1