C++实现太阳系行星系统

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;
}
相关推荐
Moonbit1 天前
月报 Vol.02:新增条件编译属性 cfg、#alias属性、defer表达式,增加 tuple struct 支持
后端·程序员·编程语言
Moonbit6 天前
MoonBit Pearls Vol.03:01背包问题
后端·算法·编程语言
神经星星6 天前
登 Science,David Baker 团队提出无序区域结合蛋白设计新方法,专攻不可成药靶点
人工智能·机器学习·编程语言
神经星星6 天前
【TVM 教程】向 Relay 中添加算子
人工智能·开源·编程语言
秋难降7 天前
零基础学习SQL(一)-----关系型数据库DDL和图形化界面工具Datagrip
数据库·mysql·编程语言
Jooolin7 天前
【C++】STL:Stack详解
c++·ai编程·编程语言
Jooolin7 天前
【C++】C++中的模板是个啥机制?好用吗?
c++·ai编程·编程语言
袁庭新10 天前
2025年07月总结
人工智能·aigc·编程语言
数据智能老司机11 天前
精通ROS 2机器人编程——ROS 2入门
机器人·ai编程·编程语言