c - 我需要一些帮助,用 openGL 设计太阳能系统

标签 c opengl animation graphics rotation

我被要求在 openGL 中设计一个太阳系并为其制作动画。我是在 C 语言中这样做的。我对于到底应该如何设置轨道动画有点困惑。我应该如何增加每个行星的旋转角度来控制其绕太阳轨道的速度?

这是我迄今为止编写的所有代码,只是尝试一步步进行:

#include <GL/glut.h>
#include <GL/glu.h>

#define FACTOR 30.0
#define SLICES 25
#define STACKS 25

//Viewing angle variables
int eye_x = 2.0;
int eye_y = 3.0;
int eye_z = 10.0;
int up_x = 0.0;
int up_y = 1.0;
int up_z = 0.0;

//Planet diameters in relation to earth
double sun_radius = 100.0;
double earth_radius = 1.0;
double moon_radius = 0.2724;
double mercury_radius = 0.383;
double venus_radius = 0.949;
double mars_radius = 0.532;
double jupiter_radius = 11.21;
double saturn_radius = 9.45;
double uranus_radius = 4.01;
double neptune_radius = 3.88;
double pluto_radius = 0.187;

//Planet distances from sun in relation to earth's distance
double mercury_distance = (sun_radius / FACTOR) + 0.387;
double venus_distance = mercury_distance + 0.723;
double earth_distance = venus_distance + 1.0;
double mars_distance = earth_distance + 1.52;
double jupiter_distance = mars_distance + 5.20;
double saturn_distance = jupiter_distance + 9.58;
double uranus_distance = saturn_distance + 19.20;
double neptune_distance = uranus_distance + 30.05;
double pluto_distance = neptune_distance + 39.24;

/**
 * Init function initializing the background to black.
 */
void init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
    glMatrixMode(GL_MODELVIEW | GL_PROJECTION);
    glEnable(GL_DEPTH_TEST);

    gluLookAt(eye_x, eye_y, eye_z, 0.0, 0.0, 0.0, up_x, up_y, up_z);
}

/*
void stars()
{
    int noOfStars = rand() % 10;
    int i = 0;

    while(i < noOfStars)
    {
        glColor3f(1.0, 1.0, 1.0);
        glPointSize(20.0f);

        int x = rand() % 10;
        int y = rand() % 10;
        int z = -8.0;

        glBegin(GL_POINTS);
            glVertex3f(x, y, z);
        glEnd();

        i++;
    }

    glFlush();
    glutSwapBuffers();
}
*/

void display()
{   
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    //stars();

    //"Zoom out"
    glTranslatef(0.0, 0.0, -20.0);

    //Draw sun
    glColor4f(1.0, 0.5, 0.0, 0.3);
    glutWireSphere(sun_radius / FACTOR, SLICES, STACKS);    

    //Draw mercury
    //Rotate around sun
    //glRotatef(, 0.0, 1.0, 0.0);
    //Distance from sun to mercury
    glTranslatef(mercury_distance, 0.0, 0.0);
    glPushMatrix();
        //glRotatef( , 0.0, 1.0, 0.0);
        glColor4f(1.0, 0.75, 0.75, 0.3);
        glutWireSphere(mercury_radius, SLICES, STACKS);
    glPopMatrix();

    /*
    //Draw venus
    //Distance from sun to venus
    glTranslatef(venus_distance, 0.0, 0.0);
    glPushMatrix();
        glColor4f(1.0, 0.75, 0.75, 0.3);
        glutWireSphere(venus_radius, SLICES, STACKS);
    glPopMatrix();

    //Draw earth
    //Distance from sun to earth
    glTranslatef(earth_distance, 0.0, 0.0);
    glPushMatrix();
        glColor4f(1.0, 0.75, 0.75, 0.3);
        glutWireSphere(earth_radius, SLICES, STACKS);
    glPopMatrix();
    */

    glFlush();
    glutSwapBuffers();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
   glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(1000, 1000);
    glutCreateWindow("solar system");

    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    glutMainLoop();

    return 0;
}   

最佳答案

首先,任何行星到太阳的距离都不是单一的——它们沿着开普勒椭圆运动。 (两周前的一月初,地球距离太阳最近,到了夏天,地球距离太阳最远。)

因此,如果你想精确地做到这一点,行星的位置角不会以恒定的速率变化。您当然可以简化并说行星轨道足够接近圆,因此这并不重要(并说冥王星不再是一颗行星,所以它甚至在那里并不重要)。

但是让我们寻求精确的解决方案:这受牛顿定律约束:

F = g * M_1 * M_2 / r^2 // How do you put equations here?

以及能量守恒,用动能 E = M v^2/2 换取势能 E = - g * M_1 * M_2/r

因此,要模拟行星绕太阳的运动,获取其位置、速度和作用在其上的引力,计算一个时间步后的最终位置,计算作用在其上的新速度和力,并重复。 (对所有行星执行相同的操作,暂时忽略它们之间的引力相互作用。)

这将是太阳系的实际模拟。如果您只想模拟任何给定时间的仓位,请查找 Keplers laws - 本质上是应用牛顿定律的结果。

<小时/>

我刚刚看到上面的文章甚至有一个关于“位置作为时间的函数”的部分 - 所以这应该对您的算法有所帮助。

关于c - 我需要一些帮助,用 openGL 设计太阳能系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28020709/

相关文章:

c - 取消引用指针

css - 跨浏览器动画抗锯齿

javascript - 如何将 D3 数据插值/动画函数应用于动态变化的饼图

python - Kivy 上的动画 Canvas 线

c++ - 分配两个数组一次调用 cudaMalloc

c - 如何在 C 中将 char[] 转换为 char*?

c - 最小堆程序停止工作

linux - ARB组件如何组装

c++ - 如何绑定(bind)部分纹理opengl

c++ - 如何在 OpenGL FBO 中使用多重采样