opengl实现太阳地球及月亮的运动模型和小球的自由落体运动.docx
- 文档编号:27888764
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:13
- 大小:57KB
opengl实现太阳地球及月亮的运动模型和小球的自由落体运动.docx
《opengl实现太阳地球及月亮的运动模型和小球的自由落体运动.docx》由会员分享,可在线阅读,更多相关《opengl实现太阳地球及月亮的运动模型和小球的自由落体运动.docx(13页珍藏版)》请在冰豆网上搜索。
opengl实现太阳地球及月亮的运动模型和小球的自由落体运动
实验六
1、实验目的和要求
了解且掌握OpenGL中包含的有关三维变换的操作,并且做出模型视图变换、投影变换和视见区变换的实例。
2、实验内容
1)在OpenGL中绘制太阳、地球和月亮的运动模型。
2)在OpenGL中创建一个球体动画,使球体在窗口内做自由落体运动,并在撞击地面(窗口的下边界)后能够弹回原来的高度。
3、实验步骤
1)相关算法及原理描述
1矩阵堆栈
在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到变换后的形体顶点的其次坐标矩阵,这样只要求出形体三维变换矩阵,就可以得到变换后的形体。
在OpenGL中,对象的变换也是通过矩阵来实现的。
在进行矩阵操作前,需要指定当前操作的矩阵对象,可以使用函数glMatrixMode(GLenummode);定义。
矩阵堆栈主要用来保存和恢复矩阵的状态,主要用于具有层次结构的模型绘制中,以提高绘图效率。
利用函数voidglPushMatrix(void);
VoidglPopMatrix(void);实现矩阵堆栈的操作。
矩阵堆栈是有深度的,如果超出了堆栈深度或当堆栈为空时试图弹出栈顶矩阵,都会发生错误。
可以用下面函数获得堆栈深度的最大值:
glGet(GL_MAX_MODELVIEW_STACK_DEPTH);
glGet(GL_MAX_PROJECTION_STACK_DEPTH);
2模型视图变换
模型视图矩阵是一个4*4的矩阵,用于指定场景的视图变换和
几何变换。
在进行模型视图矩阵操作前,必须调用函数glMatrixMode(GL_MODELVIEW)指定变换只能影响模型试图矩阵。
主要有以下两种方法。
1.2.1、直接定义矩阵
利用函数voidglLoadMartrix{fd}(constTYPE*m);将m所指定的矩阵置为当前矩阵堆栈的栈顶矩阵。
1.2.2、利用高级矩阵函数
平移矩阵函数:
voidglTranslate{df}(TYPEx,TYPEy,TYPEz);
用当前矩阵乘以平移矩阵。
旋转矩阵函数
voidglRotate{df}(TYPEangle,TYPEx,TYPWy,TYPEz);
缩放矩阵函数
voidglScale{df}(TYPEx,TYPEy,TYPEz);
如不需要效果积累可调用重置矩阵函数
voidglLoadIdentity(void);该函数将单位矩阵置为当前变换矩阵。
3投影变换
有两种投影方式,不管调用哪种,必须调用
glMAtrixMode(GL_PROJECTION);指定当前处理的矩阵是投影变换矩阵。
1.3.1、正投影
它的有限观察空间是一个长方体,无论物体距离相机多远,投影后的物体大小尺寸不变。
正投影函数有两个:
voidglOrtho(GLdoubleleft,GLdoubleright,GLdoublebotton,
GLdoubletop,GLdoublenear,GLdoublefar);
voidgluOrtho2D(GLdoubleleft,GLdoubleright,GLdoublbotton,
GLdoubletop);
1.3.2、透视投影
特点是距离视点近的物体大,距离视点远的物体小,远到极点即为消失。
透视投影函数也有两个:
voidglFrustum(GLdoubleleft,GLdoubleRight,GLdoublebotton,
GLdoubletop,GLdoublenear,GLdoublefar);
voidgluPerspective(GLdoublefovy,GLdoubleaspect,
GLdoublezNear,GLdoublezFar);
2)程序调试、测试与运行结果分析
1太阳、地球和月亮的运动模型
2小球的自由落体运动
4、附录
(1)太阳、地球和月亮的运动模型
#include
staticintday=200;
voiddisplay()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
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);
glColor3f(1,1,0);
glRotatef(day/30.0*360-day,0,0,-1);
glTranslatef(38000,0,0);//moon
glutSolidSphere(4345,20,20);
glutSwapBuffers();
}
voidtimer(intp)
{day++;
if(day>360)day=0;
glutTimerFunc(50,timer,0);
glutPostRedisplay();
}
intmain(intargc,char**argv)
{glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutCreateWindow("earth,moon,sun");
glutInitWindowSize(400,400);
glutDisplayFunc(display);
glutTimerFunc(50,timer,0);
glutMainLoop();
return0;
}
(2)小球的自由落体运动
#include
#include
#include
#include
#include
#definePI3.1415926
doublemove=20.0;
inti=0;
intdown=1;
intcount=1;
doubletimeSpan=0;//下降到底所需时间
doublemovey=0.0;
doubleduration=0.0;//持续时间
doublelength=0.0;
clock_tstart,end;
voidinit(void)
{printf("init");
GLfloatmat_specular[]={220.220,220.0,220.0,220.0};
GLfloatmat_shininess[]={70.0};
GLfloatlight_position[]={0.0,0.0,0.0,-2.0};//r-lu-df-b
GLfloatambientLight[]={0.2f,0.2f,0.2f,1.0f};
GLfloatdiffuseLight[]={0.6f,0.6f,0.6f,1.0f};
GLfloatspecular[]={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_LIGHT0,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);//启用深度测试
}
voidreshape(intw,inth)
{printf("reshape");
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-12,12,-12*(GLfloat)(h)/(GLfloat)(w),12*(GLfloat)(h)/(GLfloat)(w),-1.0,1.0);
elseglOrtho(-12*(GLfloat)(w)/(GLfloat)(h),12*(GLfloat)(w)/(GLfloat)(h),-12,12,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidinitDisplay(void)
{printf("initDisplay()");
down=1;//向下运动
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,20.0,0.0);
glutSolidSphere(0.4,40,50);
glutSwapBuffers();
}
voiddisplay(void)
{printf("Display()");
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,move,0.0);
glutSolidSphere(0.4,40,50);
glutSwapBuffers();
}
voidMoveSphereUp()
{end=clock();
duration=(double)(end-start-16.0)/CLOCKS_PER_SEC;
length=5*(timeSpan-duration)*(timeSpan-duration);
move=20-length;
if(move>19.932){
move=20;
down=1;
printf("%i",down);
start=clock();
}
display();
glLoadIdentity();
}
voidMoveSphereDown()
{
if(count==1){
start=clock();
count=0;
}
end=clock();
duration=(double)(end-start)/CLOCKS_PER_SEC;
length=5*duration*duration;
move=20-length;
if(move<-20){
timeSpan=duration;//记下下降所经历的时间
move=-20;
start=clock();
down=0;//向上运动
}
display();
glLoadIdentity();
}
voidTimerFunc2(intvalue){
if(i==0){//left
GLfloatlight_position[]={2.0,0.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==1){//left-up
GLfloatlight_position[]={2.0,2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==2){//up
GLfloatlight_position[]={0.0,2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==3){//up-right
GLfloatlight_position[]={-2.0,2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==4){//right
GLfloatlight_position[]={-2.0,0.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==5){//right-down
GLfloatlight_position[]={-2.0,-2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==6){//down
GLfloatlight_position[]={0.0,-2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
if(i==7){//down-left
GLfloatlight_position[]={2.0,-2.0,0.0,0.0};//r-lu-df-b
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
}
i=(++i)%8;
printf("%i",i);
glutTimerFunc(60,TimerFunc2,1);
}
voidTimerFunc1(intvalue){
if(down==1){
MoveSphereDown();
}
if(down==0){
MoveSphereUp();
}
glutTimerFunc(10,TimerFunc1,0);
}
intmain(intargc,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();
return0;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- opengl 实现 太阳 地球 月亮 运动 模型 小球 自由落体运动