一 目标
用线框绘制两个球体,命名为地球和月球。实现月球的自装和公转,并通过键盘输入控制旋转的方向
二 参考资料
1、glPushMatrix()和glPopMatrix():https://blog.csdn.net/tyxkzzf/article/details/40907273
2、键盘控制:https://blog.csdn.net/xie_zi/article/details/1911891
三 源代码
- #include<GL\glut.h>
- #include<math.h>
- #define pi 3.1415926
- //----------------//
- // 观察坐标系参数 //
- //----------------//
- //观察坐标系原点
- GLdouble x = 0.0;
- GLdouble y = 2.0;
- GLdouble z = 20.0;
- //视点
- GLdouble X = 0.0;
- GLdouble Y = 0.0;
- GLdouble Z = 0.0;
- //向上向量
- GLdouble vx = 0.0;
- GLdouble vy = 1.0;
- GLdouble vz = 0.0;
- //---------------------------//
- // 定义星球旋转相关参数 //
- //---------------------------//
- GLint distance = 25; //星球间距离
- GLdouble moonAngle = 0; //月球自转角度
- GLdouble revoAngle = 0; //公转角度
- //地球坐标
- GLdouble earthX = 0;
- GLdouble earthY = 0;
- GLdouble earthZ = 0;
- //月球坐标
- GLdouble moonX = distance;
- GLdouble moonY = 0;
- GLdouble moonZ = 0;
- //星球大小
- GLint earthSize = 8;
- GLint moonSize = 5;
- //月球自转、公转方向
- bool direction1 = false;//控制自转
- bool direction2 = false;//控制公转
- void init_observe()
- {
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glMatrixMode(GL_MODELVIEW);
- gluLookAt(x, y, z, X, Y, Z, vx, vy, vz);
- glMatrixMode(GL_PROJECTION);
- glFrustum(-3.0, 3.0, -3.0, 3.0, 1.0, 30.0);
- }
- void drawPlanet(GLfloat x, GLfloat y, GLfloat z, GLfloat angle, GLint size)
- {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glTranslatef(x, y, z); //平移坐标系
- glRotatef(angle, 0.0, 0.0, 1.0); //旋转坐标系
- glutWireSphere(size, 10, 10); //绘制线框球体,包括10条经线和10条纬线
- glPopMatrix();
- }
- void revolution()
- {
- if (direction1)
- {
- moonAngle += 0.1;
- if (moonAngle >= 360)
- moonAngle -= 360;
- }
- else
- {
- moonAngle -= 0.1;
- if (moonAngle <= 0)
- moonAngle += 360;
- }
- if (direction2)
- {
- revoAngle += 0.01;
- if (revoAngle >= 360)
- revoAngle -= 360;
- }
- else
- {
- revoAngle -= 0.01;
- if (revoAngle <= 0)
- revoAngle += 360;
- }
- moonX = (GLdouble)distance*cos(revoAngle*pi/180);
- moonY = (GLdouble)distance*sin(revoAngle*pi/180); //计算月球坐标
- }
- void keyboard(unsigned char k, int x, int y)
- {
- if (k == 27)
- exit(0);
- int mod;
- if (k == 'd'||k == 'D')
- {
- mod = glutGetModifiers();
- if (mod == GLUT_ACTIVE_SHIFT) // shift 被按下
- direction1 = false;
- else
- direction1 = true;
- }
- else if (k == 'y'||k == 'Y')
- {
- mod = glutGetModifiers();
- if (mod == GLUT_ACTIVE_SHIFT)
- direction2 = false;
- else
- direction2 = true;
- }
- }
- void display()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- //draw earth
- glColor3f(0.0, 0.0, 1.0);
- drawPlanet(earthX, earthY, earthZ, 0, earthSize);
- //draw moon
- glColor3f(0.0, 1.0, 1.0);
- drawPlanet(moonX, moonY, moonZ, moonAngle, moonSize);
- glFlush();
- revolution();
- glutPostRedisplay();
- }
- void main(int argc, char**argv)
- {
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
- glutInitWindowPosition(10, 10);
- glutInitWindowSize(700, 700);
- glutCreateWindow("Planet");
- init_observe();
- glutDisplayFunc(display);
- glutKeyboardFunc(keyboard);
- glutMainLoop();
- }