C++学习路线之入门项目一
C++实现太阳系行星系统
使用 C++实现 OpenGL GLUT 实现一个简单的太阳系行星系统,将涉及一些三维图形技术的数学基础、OpenGL 里的三维坐标系、OpenGL 里的光照模型、GLUT 的键盘事件处理。(该项目使用Vim开发,环境是Ubuntu 24.04.3 LTS)
首先是环境准备,安装必要的库sudo apt update sudo apt install build-essential libgl1-mesa-dev libglut3-dev
这包含了编译 OpenGL/GLUT 程序所需的编译器、OpenGL 库和 GLUT 库。
以下是实现的代码
scss
/*solar_system.cpp*/
#include <GL/glut.h>
#include <cmath>
// 视角控制变量
float angle = 0.0f; // 整体旋转角度
float zoom = -20.0f; // 缩放
float rotX = -20.0f; // X轴旋转
float rotY = 0.0f; // Y轴旋转
int lastX, lastY; // 鼠标位置
bool isDragging = false; // 鼠标拖动状态
// 行星旋转角度
float sunRot = 0.0f;
float earthRot = 0.0f;
float moonRot = 0.0f;
float mercuryRot = 0.0f;
float venusRot = 0.0f;
float marsRot = 0.0f;
// 初始化OpenGL
void init() {
// 设置背景色为黑色
glClearColor(0.0, 0.0, 0.0, 1.0);
// 启用深度测试
glEnable(GL_DEPTH_TEST);
// 启用光照
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); // 主光源(太阳)
// 设置光源属性(太阳)
GLfloat lightPos[] = {0.0f, 0.0f, 0.0f, 1.0f}; // 光源位置(太阳中心)
GLfloat lightAmbient[] = {0.2f, 0.2f, 0.2f, 1.0f}; // 环境光
GLfloat lightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; // 漫反射光
GLfloat lightSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f}; // 镜面光
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
// 启用颜色追踪
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
}
// 绘制球体(行星)
void drawSphere(float radius, int slices, int stacks, float r, float g, float b) {
glColor3f(r, g, b);
glutSolidSphere(radius, slices, stacks);
}
// 绘制轨道
void drawOrbit(float radius) {
glColor3f(0.3f, 0.3f, 0.3f); // 灰色轨道
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 100; i++) {
float theta = 2.0f * M_PI * float(i) / float(100);
float x = radius * cosf(theta);
float z = radius * sinf(theta);
glVertex3f(x, 0.0f, z);
}
glEnd();
}
// 渲染场景
void display() {
// 清除颜色缓冲和深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 设置视角
glTranslatef(0.0f, 0.0f, zoom);
glRotatef(rotX, 1.0f, 0.0f, 0.0f);
glRotatef(rotY, 0.0f, 1.0f, 0.0f);
// 绘制太阳
drawSphere(1.0f, 30, 30, 1.0f, 1.0f, 0.0f); // 黄色太阳
// 绘制水星轨道和水星
drawOrbit(3.0f);
glPushMatrix();
glRotatef(mercuryRot, 0.0f, 1.0f, 0.0f); // 绕太阳旋转
glTranslatef(3.0f, 0.0f, 0.0f); // 放置在轨道上
drawSphere(0.3f, 20, 20, 0.5f, 0.5f, 0.5f); // 灰色水星
glPopMatrix();
// 绘制金星轨道和金星
drawOrbit(4.5f);
glPushMatrix();
glRotatef(venusRot, 0.0f, 1.0f, 0.0f);
glTranslatef(4.5f, 0.0f, 0.0f);
drawSphere(0.5f, 20, 20, 0.8f, 0.6f, 0.4f); // 金黄色金星
glPopMatrix();
// 绘制地球轨道和地球
drawOrbit(6.0f);
glPushMatrix();
glRotatef(earthRot, 0.0f, 1.0f, 0.0f);
glTranslatef(6.0f, 0.0f, 0.0f);
drawSphere(0.6f, 20, 20, 0.0f, 0.0f, 1.0f); // 蓝色地球
// 绘制月球
glRotatef(moonRot, 0.0f, 1.0f, 0.0f);
glTranslatef(1.0f, 0.0f, 0.0f);
drawSphere(0.2f, 15, 15, 0.8f, 0.8f, 0.8f); // 灰白色月球
glPopMatrix();
// 绘制火星轨道和火星
drawOrbit(8.0f);
glPushMatrix();
glRotatef(marsRot, 0.0f, 1.0f, 0.0f);
glTranslatef(8.0f, 0.0f, 0.0f);
drawSphere(0.5f, 20, 20, 1.0f, 0.2f, 0.2f); // 红色火星
glPopMatrix();
// 交换缓冲
glutSwapBuffers();
}
// 调整窗口大小
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)w/(float)h, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
// 更新动画
void update(int value) {
// 更新旋转角度(不同行星有不同的旋转速度)
sunRot += 0.5f;
earthRot += 1.0f;
moonRot += 5.0f;
mercuryRot += 4.0f;
venusRot += 1.5f;
marsRot += 0.8f;
if (sunRot >= 360) sunRot -= 360;
if (earthRot >= 360) earthRot -= 360;
if (moonRot >= 360) moonRot -= 360;
if (mercuryRot >= 360) mercuryRot -= 360;
if (venusRot >= 360) venusRot -= 360;
if (marsRot >= 360) marsRot -= 360;
glutPostRedisplay();
glutTimerFunc(30, update, 0); // 30毫秒后再次更新
}
// 键盘事件处理
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: // ESC键退出
exit(0);
break;
case '+': // 放大
zoom += 0.5f;
break;
case '-': // 缩小
zoom -= 0.5f;
break;
}
glutPostRedisplay();
}
// 鼠标按下事件
void mousePress(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
isDragging = true;
lastX = x;
lastY = y;
} else {
isDragging = false;
}
}
// 鼠标拖动事件
void mouseDrag(int x, int y) {
if (isDragging) {
rotY += (x - lastX) * 0.5f;
rotX += (y - lastY) * 0.5f;
lastX = x;
lastY = y;
glutPostRedisplay();
}
}
// 主函数
int main(int argc, char**argv) {
// 初始化GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("太阳系行星系统");
// 初始化OpenGL
init();
// 注册回调函数
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mousePress);
glutMotionFunc(mouseDrag);
glutTimerFunc(30, update, 0);
// 进入GLUT主循环
glutMainLoop();
return 0;
}
编译和运行 将代码保存为solar_system.cpp
,然后使用以下命令编译:
g++ solar_system.cpp -o solar_system -lglut -lGL -lGLU -lm
编译成功后,运行程序:
bash
./solar_system
更新一下这个系统,完善后代码如下:
scss
#include<iostream>
#include<cmath>
#include<vector>
#include<GL/glut.h>
//视角控制变量
//float angle = 0.0f; //整体旋转角度
float zoom = -250.0f; //缩放控制
float rotX = -20.0f; //绕x轴旋转角度
float rotY = 0.0f; //绕Y轴旋转角度
int lastX, lastY;
bool isDragging = false;
//行星旋转角度
float sunRot = 0.0f; // 太阳自转
float mercuryRot = 0.0f; // 水星公转
float venusRot = 0.0f; // 金星公转
float earthRot = 0.0f; // 地球公转
float moonRot = 0.0f; // 月球公转
float marsRot = 0.0f; // 火星公转
float phobosRot = 0.0f; // 火卫一公转
float deimosRot = 0.0f; // 火卫二公转
float jupiterRot = 0.0f; // 木星公转
float ioRot = 0.0f; // 木卫一公转
float europaRot = 0.0f; // 木卫二公转
float ganymedeRot = 0.0f; // 木卫三公转
float callistoRot = 0.0f; // 木卫四公转
float saturnRot = 0.0f; // 土星公转
float titanRot = 0.0f; // 土卫六公转
float enceladusRot = 0.0f; // 土卫二公转
float uranusRot = 0.0f; // 天王星公转
float titaniaRot = 0.0f; // 天卫三公转
float oberonRot = 0.0f; // 天卫四公转
float neptuneRot = 0.0f; // 海王星公转
float tritonRot = 0.0f; // 海卫一公转
float plutoRot = 0.0f; // 冥王星公转
float ceresRot = 0.0f; // 谷神星公转
float erisRot = 0.0f; // 阋神星公转
float makemakeRot = 0.0f; // 鸟神星公转
float haumeaRot = 0.0f; // 妊神星公转
//初始化OpenGL
void init() {
glClearColor(0.0, 0.0, 0.02, 1.0); //深黑色背景
glEnable(GL_DEPTH_TEST); //启动深度测试
glEnable(GL_LIGHTING); //启动光照
glEnable(GL_LIGHT0); //主光源(太阳)
glEnable(GL_COLOR_MATERIAL); //启动颜色追踪
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
//太阳光源设置
GLfloat lightPos[] = {0.0f, 0.0f, 0.0f, 1.0f}; //光源位置(太阳中心)
GLfloat lightAmbient[] = {0.3f, 0.3f, 0.3f, 1.0f}; //环境光增强
GLfloat lightDiffuse[] = {1.0f, 1.0f, 0.9f, 1.0f}; // 太阳光略带黄色
GLfloat lightSpecular[] = {1.0f, 1.0f, 0.8f, 1.0f}; // 镜面光
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
}
// 绘制球体(天体)
void drawSphere(float radius, int slices, int stacks, float r, float g, float b) {
glColor3f(r, g, b);
glutSolidSphere(radius, slices, stacks);
}
// 绘制轨道(椭圆轨道,增加倾角参数)
void drawOrbit(float radius, float tilt = 0.0f, float eccentricity = 0.0f) {
glColor3f(0.3f, 0.3f, 0.4f); // 深蓝色轨道
glPushMatrix();
glRotatef(tilt, 1.0f, 0.0f, 0.0f); // 轨道倾角
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 100; i++) {
float theta = 2.0f * M_PI * float(i) / 100;
// 椭圆轨道计算(离心率eccentricity)
float r = radius * (1 - eccentricity * eccentricity) / (1 + eccentricity * cosf(theta));
float x = r * cosf(theta);
float z = r * sinf(theta);
glVertex3f(x, 0.0f, z);
}
glEnd();
glPopMatrix();
}
// 绘制土星环
void drawSaturnRings(float planetRadius) {
glColor3f(0.6f, 0.5f, 0.4f); // 土黄色环
glPushMatrix();
glRotatef(90.0f, 1.0f, 0.0f, 0.0f); // 环面与黄道面一致
glScalef(2.0f, 0.1f, 2.0f); // 拉伸形成环
glutSolidTorus(planetRadius * 0.3, planetRadius * 1.2, 10, 50); // 圆环
glPopMatrix();
}
// 渲染场景
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 设置视角
glTranslatef(0.0f, 0.0f, zoom);
glRotatef(rotX, 1.0f, 0.0f, 0.0f);
glRotatef(rotY, 0.0f, 1.0f, 0.0f);
// 绘制太阳(中心天体)
glPushMatrix();
glRotatef(sunRot, 0.0f, 1.0f, 0.0f); // 太阳自转
drawSphere(6.0f, 50, 50, 1.0f, 0.9f, 0.4f); // 黄色太阳(直径放大便于观察)
glPopMatrix();
// 1. 水星(0.39 AU)
drawOrbit(23.4f); // 1 AU = 60单位(0.39*60=23.4)
glPushMatrix();
glRotatef(mercuryRot, 0.0f, 1.0f, 0.0f);
glTranslatef(23.4f, 0.0f, 0.0f);
drawSphere(0.4f, 20, 20, 0.6f, 0.6f, 0.6f); // 灰色水星
glPopMatrix();
// 2. 金星(0.72 AU)
drawOrbit(43.2f); // 0.72*60=43.2
glPushMatrix();
glRotatef(venusRot, 0.0f, 1.0f, 0.0f);
glTranslatef(43.2f, 0.0f, 0.0f);
drawSphere(1.0f, 25, 25, 0.9f, 0.7f, 0.3f); // 金黄色金星
glPopMatrix();
// 3. 地球(1.00 AU)+ 月球
drawOrbit(60.0f); // 1.0*60=60
glPushMatrix();
glRotatef(earthRot, 0.0f, 1.0f, 0.0f);
glTranslatef(60.0f, 0.0f, 0.0f);
drawSphere(1.1f, 30, 30, 0.2f, 0.3f, 1.0f); // 蓝色地球
// 月球
glPushMatrix();
glRotatef(moonRot, 0.0f, 1.0f, 0.0f);
glTranslatef(2.0f, 0.0f, 0.0f);
drawSphere(0.3f, 15, 15, 0.9f, 0.9f, 0.9f); // 灰白色月球
glPopMatrix();
glPopMatrix();
// 4. 火星(1.52 AU)+ 火卫一、火卫二
drawOrbit(91.2f, 1.0f); // 1.52*60=91.2,轨道倾角1度
glPushMatrix();
glRotatef(marsRot, 0.0f, 1.0f, 0.0f);
glTranslatef(91.2f, 0.0f, 0.0f);
drawSphere(0.8f, 25, 25, 0.8f, 0.3f, 0.2f); // 红色火星
// 火卫一
glPushMatrix();
glRotatef(phobosRot, 0.0f, 1.0f, 0.0f);
glTranslatef(1.5f, 0.0f, 0.0f);
drawSphere(0.15f, 10, 10, 0.5f, 0.5f, 0.5f);
glPopMatrix();
// 火卫二
glPushMatrix();
glRotatef(deimosRot, 0.0f, 1.0f, 0.0f);
glTranslatef(-2.2f, 0.0f, 0.0f);
drawSphere(0.1f, 10, 10, 0.4f, 0.4f, 0.4f);
glPopMatrix();
glPopMatrix();
// 矮行星:谷神星(小行星带,火星与木星之间)
drawOrbit(150.0f, 0.5f, 0.07f); // 约2.5 AU
glPushMatrix();
glRotatef(ceresRot, 0.0f, 1.0f, 0.0f);
glTranslatef(150.0f, 0.0f, 0.0f);
drawSphere(0.3f, 15, 15, 0.7f, 0.6f, 0.5f); // 淡棕色谷神星
glPopMatrix();
// 5. 木星(5.20 AU)+ 伽利略四卫
drawOrbit(312.0f, 1.3f); // 5.2*60=312,轨道倾角1.3度
glPushMatrix();
glRotatef(jupiterRot, 0.0f, 1.0f, 0.0f);
glTranslatef(312.0f, 0.0f, 0.0f);
drawSphere(4.0f, 40, 40, 0.8f, 0.7f, 0.5f); // 棕黄色木星
// 木卫一(Io)
glPushMatrix();
glRotatef(ioRot, 0.0f, 1.0f, 0.0f);
glTranslatef(6.0f, 0.0f, 0.0f);
drawSphere(0.5f, 15, 15, 0.9f, 0.4f, 0.4f); // 橙红色
glPopMatrix();
// 木卫二(Europa)
glPushMatrix();
glRotatef(europaRot, 0.0f, 1.0f, 0.0f);
glTranslatef(-8.0f, 0.0f, 0.0f);
drawSphere(0.45f, 15, 15, 0.9f, 0.9f, 1.0f); // 白色
glPopMatrix();
// 木卫三(Ganymede)
glPushMatrix();
glRotatef(ganymedeRot, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, 10.0f);
drawSphere(0.6f, 15, 15, 0.8f, 0.8f, 0.7f); // 淡灰色
glPopMatrix();
// 木卫四(Callisto)
glPushMatrix();
glRotatef(callistoRot, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, -13.0f);
drawSphere(0.55f, 15, 15, 0.7f, 0.7f, 0.6f); // 灰棕色
glPopMatrix();
glPopMatrix();
// 6. 土星(9.58 AU)+ 土卫六、土卫二
drawOrbit(574.8f, 2.5f); // 9.58*60≈574.8,倾角2.5度
glPushMatrix();
glRotatef(saturnRot, 0.0f, 1.0f, 0.0f);
glTranslatef(574.8f, 0.0f, 0.0f);
drawSphere(3.5f, 40, 40, 0.9f, 0.8f, 0.6f); // 黄棕色土星
drawSaturnRings(3.5f); // 绘制土星环
// 土卫六(Titan)
glPushMatrix();
glRotatef(titanRot, 0.0f, 1.0f, 0.0f);
glTranslatef(8.0f, 0.0f, 0.0f);
drawSphere(0.4f, 15, 15, 0.7f, 0.6f, 0.5f); // 橙棕色
glPopMatrix();
// 土卫二(Enceladus)
glPushMatrix();
glRotatef(enceladusRot, 0.0f, 1.0f, 0.0f);
glTranslatef(-5.0f, 0.0f, 0.0f);
drawSphere(0.25f, 12, 12, 0.9f, 0.9f, 0.9f); // 白色
glPopMatrix();
glPopMatrix();
// 7. 天王星(19.22 AU)+ 天卫三、天卫四
drawOrbit(1153.2f, 97.8f); // 19.22*60≈1153.2,倾角97.8度(躺着转)
glPushMatrix();
glRotatef(uranusRot, 0.0f, 1.0f, 0.0f);
glTranslatef(1153.2f, 0.0f, 0.0f);
glRotatef(97.8f, 1.0f, 0.0f, 0.0f); // 自转轴倾斜
drawSphere(3.0f, 35, 35, 0.6f, 0.9f, 0.9f); // 淡青色天王星
// 天卫三(Titania)
glPushMatrix();
glRotatef(titaniaRot, 0.0f, 1.0f, 0.0f);
glTranslatef(6.0f, 0.0f, 0.0f);
drawSphere(0.35f, 12, 12, 0.8f, 0.8f, 0.8f); // 灰白色
glPopMatrix();
// 天卫四(Oberon)
glPushMatrix();
glRotatef(oberonRot, 0.0f, 1.0f, 0.0f);
glTranslatef(-7.0f, 0.0f, 0.0f);
drawSphere(0.3f, 12, 12, 0.75f, 0.75f, 0.75f); // 浅灰色
glPopMatrix();
glPopMatrix();
// 8. 海王星(30.05 AU)+ 海卫一
drawOrbit(1803.0f, 1.7f); // 30.05*60≈1803,倾角1.7度
glPushMatrix();
glRotatef(neptuneRot, 0.0f, 1.0f, 0.0f);
glTranslatef(1803.0f, 0.0f, 0.0f);
drawSphere(2.9f, 35, 35, 0.2f, 0.3f, 0.8f); // 深蓝色海王星
// 海卫一(Triton)
glPushMatrix();
glRotatef(tritonRot, 0.0f, 1.0f, 0.0f);
glTranslatef(5.5f, 0.0f, 0.0f);
drawSphere(0.3f, 12, 12, 0.8f, 0.8f, 0.9f); // 淡蓝色
glPopMatrix();
glPopMatrix();
// 矮行星:冥王星(柯伊伯带,约39 AU)
drawOrbit(2340.0f, 17.0f, 0.25f); // 39*60=2340,高离心率
glPushMatrix();
glRotatef(plutoRot, 0.0f, 1.0f, 0.0f);
glTranslatef(2340.0f, 0.0f, 0.0f);
drawSphere(0.3f, 15, 15, 0.7f, 0.5f, 0.4f); // 淡红色冥王星
glPopMatrix();
// 矮行星:阋神星(~68 AU)
drawOrbit(4080.0f, 44.0f, 0.44f); // 68*60=4080
glPushMatrix();
glRotatef(erisRot, 0.0f, 1.0f, 0.0f);
glTranslatef(4080.0f, 0.0f, 0.0f);
drawSphere(0.32f, 15, 15, 0.8f, 0.7f, 0.6f); // 淡棕色
glPopMatrix();
// 矮行星:鸟神星(~45 AU)
drawOrbit(2700.0f, 29.0f, 0.16f); // 45*60=2700
glPushMatrix();
glRotatef(makemakeRot, 0.0f, 1.0f, 0.0f);
glTranslatef(2700.0f, 0.0f, 0.0f);
drawSphere(0.28f, 15, 15, 0.9f, 0.8f, 0.5f); // 淡橙色
glPopMatrix();
// 矮行星:妊神星(~43 AU)
drawOrbit(2580.0f, 28.2f, 0.19f); // 43*60=2580
glPushMatrix();
glRotatef(haumeaRot, 0.0f, 1.0f, 0.0f);
glTranslatef(2580.0f, 0.0f, 0.0f);
glScalef(1.5f, 0.5f, 0.8f); // 妊神星是椭球形
drawSphere(0.25f, 15, 15, 0.9f, 0.7f, 0.5f); // 淡红色
glPopMatrix();
glutSwapBuffers();
}
// 窗口大小调整
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)w/(float)h, 1.0f, 10000.0f); // 增大远平面
glMatrixMode(GL_MODELVIEW);
}
// 动画更新(根据公转周期设置速度,周期越短速度越快)
void update(int value) {
// 太阳自转(25天/周)
sunRot += 0.05f;
// 类地行星(公转周期短,速度快)
mercuryRot += 4.1f; // 88天 → 最快
venusRot += 1.6f; // 225天
earthRot += 1.0f; // 365天(基准速度)
moonRot += 13.0f; // 月球公转快(27天)
marsRot += 0.53f; // 687天
// 火星卫星
phobosRot += 30.0f; // 火卫一公转极快(7.6小时)
deimosRot += 10.0f; // 火卫二较慢(30.3小时)
// 外行星(公转周期长,速度慢)
jupiterRot += 0.085f; // 11.86年
saturnRot += 0.034f; // 29.46年
uranusRot += 0.0119f; // 84年
neptuneRot += 0.0061f; // 164.8年
// 木星卫星
ioRot += 9.0f; // 木卫一(1.77天)
europaRot += 4.5f; // 木卫二(3.55天)
ganymedeRot += 2.0f; // 木卫三(7.15天)
callistoRot += 1.0f; // 木卫四(16.69天)
// 土星卫星
titanRot += 1.2f; // 土卫六(15.9天)
enceladusRot += 3.0f; // 土卫二(1.37天)
// 天王星卫星
titaniaRot += 1.5f; // 天卫三(8.7天)
oberonRot += 1.2f; // 天卫四(13.5天)
// 海王星卫星
tritonRot += 2.5f; // 海卫一(5.88天)
// 矮行星(极慢)
ceresRot += 0.2f; // 谷神星(4.6年)
plutoRot += 0.004f; // 冥王星(248年)
erisRot += 0.0015f; // 阋神星(557年)
makemakeRot += 0.0025f;// 鸟神星(309年)
haumeaRot += 0.0028f; // 妊神星(285年)
// 角度重置(避免溢出)
auto resetAngle = [](float& angle) {
if (angle >= 360) angle -= 360;
};
resetAngle(sunRot);
resetAngle(mercuryRot);
resetAngle(venusRot);
resetAngle(earthRot);
resetAngle(moonRot);
resetAngle(marsRot);
resetAngle(phobosRot);
resetAngle(deimosRot);
resetAngle(jupiterRot);
resetAngle(ioRot);
resetAngle(europaRot);
resetAngle(ganymedeRot);
resetAngle(callistoRot);
resetAngle(saturnRot);
resetAngle(titanRot);
resetAngle(enceladusRot);
resetAngle(uranusRot);
resetAngle(titaniaRot);
resetAngle(oberonRot);
resetAngle(neptuneRot);
resetAngle(tritonRot);
resetAngle(plutoRot);
resetAngle(ceresRot);
resetAngle(erisRot);
resetAngle(makemakeRot);
resetAngle(haumeaRot);
glutPostRedisplay();
glutTimerFunc(30, update, 0); // 30ms更新一次(~33FPS)
}
// 键盘控制
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: // ESC退出
exit(0);
break;
case '+': // 放大(靠近)
zoom += 10.0f;
if (zoom > -10.0f) zoom = -10.0f; // 限制最小距离
break;
case '-': // 缩小(远离)
zoom -= 10.0f;
if (zoom < -5000.0f) zoom = -5000.0f; // 限制最大距离
break;
}
glutPostRedisplay();
}
// 鼠标事件
void mousePress(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
isDragging = true;
lastX = x;
lastY = y;
} else {
isDragging = false;
}
}
void mouseDrag(int x, int y) {
if (isDragging) {
rotY += (x - lastX) * 0.3f; // 降低灵敏度(远距离天体)
rotX += (y - lastY) * 0.3f;
lastX = x;
lastY = y;
glutPostRedisplay();
}
}
// 主函数
int main(int argc, char**argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1200, 900); // 更大窗口便于观察
glutCreateWindow("太阳系行星系统模拟");
init();
// 注册回调
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mousePress);
glutMotionFunc(mouseDrag);
glutTimerFunc(30, update, 0);
glutMainLoop();
return 0;
}