2013-04-25 54 views
-2

我期待在C++和openGL中模擬太陽系,而且我想知道是否有一種便宜的方法可以生成返回一個x,y,z向量,我可以用於每幀更新每個行星的位置。在openGL中對太陽系進行建模

+0

您可以創建一個類行星與X,Y和Z點(浮點)等,然後,根據每個行星的當前位置和其他相關資料更新其位置,在步驟時間delta_t。 – 2013-04-25 18:59:16

+0

爲什麼它需要便宜?當然,對於大約十幾個物體,任何計算它們相對位置的舊方法都應該能夠達到合理的性能。更棘手的部分將紋理,否則使行星看起來不錯。 – 2013-04-25 18:59:21

+0

那麼這就是我不確定三維運動的正確方程是什麼。 – Yann 2013-04-25 19:09:19

回答

6

關於行星位置,你有幾種選擇。

  • 準確(但「在球公園」):假設行星循環往復,在飛機上
  • 有些不準確(但更接近於現實):下載「orbital elements」從行星JPL的太陽系動力學小組;使用Kepler's equation傳播軌道(比聽起來簡單得多)。這將是最正確的(特別是對於大行星)。
  • 準確:下載JPL Ephemerides的行星的位置(DE405或DE421),並使用可用閱讀器(例如,SPICE),以獲取儘可能多的準確狀態,因爲它是目前可能(注意這不一定是「計算的一個昂貴的「)
  • 準確:下載VSOP數據和相關程序(不如JPL的星曆錶精確,但也是」任務初步設計等級「)。

我發現了前段時間寫的一些代碼,用於演示使用SPICE和OpenGL可視化DE421數據的「快速和骯髒」方式。也許它可以幫助你。

Simple Screenshot

#include<cstdlib> 
#include<cmath> 
#include<OpenGL/gl.h> 
#include<OpenGL/glu.h> 
#include<GLUT/glut.h> 
#include<SpiceUsr.h> 

// hard-code some parameters - in a real application all this would be dynamic 
#define ALTITUDE 700E6  // in kilometers 
#define CLIPPING 100E7 
#define FOV 45.0  // 45-degree field-of-view 
#define WIN_WIDTH 1024 
#define WIN_HEIGHT 1024 

// callback to render the trajectory of a planet using spice (notice 
// that I use 366 points - one per day starting at epoch 0.0 
// (01-Jan-2000 12:00:00 ET) - (r, g, b) is the color 
void render_planet(const char* planet, int r, int g, int b) { 
    unsigned int N = 366; 
    double et = 0.0; 
    double state[3]; 
    double lt; 

    // we just want a simple line 
    glBegin(GL_LINE_STRIP); 
    glColor4d(r, g, b, 1.0); 

    for(unsigned int k=0; k<N; k++) { 
    // call spice to calculate position 
    spkpos_c(planet, et, "ECLIPJ2000", "None", "Sun", state, &lt); 
    // add the point to the pipeline 
    glVertex3d(state[0], state[1], state[2]);  
    // increase time by one day 
    et = 86400 * k; 
    } 
    glEnd();  
} 

// callback to handle window resizing 
void changeSize(int w, int h) { 
if (h == 0) h = 1; 
    float ratio = w * 1.0/h; 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glViewport(0, 0, w, h); 
    gluPerspective(FOV, ratio, 0.2f, CLIPPING); 
    glMatrixMode(GL_MODELVIEW); 
} 

// callback to render scene 
void renderScene() { 
    // use a nice dark gray for the background (as opposed to pitch black) 
    glClearColor(50/255.0, 50/255.0, 50/255.0, 1); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity(); 
    gluLookAt(0.0, 0.0, ALTITUDE, 
     0.0, 0.0, 0.0, 
     0.0, 1.0, 0.0);  
    // here we tell the application which planets to draw, the colors 
    // are (r, g, b), so (1, 1, 0) is all red and all green (yellow), 
    // and so forth - of course this can be simplified to use arbitrary 
    // colors 
    render_planet("Mercury", 1, 1, 0); 
    render_planet("Venus", 0, 1, 0); 
    render_planet("Earth", 0, 0, 1); 
    render_planet("Mars", 1, 0, 0); 
    glutSwapBuffers(); 
} 

int main(int argc, char* argv[]) { 
    // initialize spice kernels 
    furnsh_c("/data/spice/allkernels.txt"); 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowPosition(0, 0); 
    glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT); 
    glutCreateWindow("Simple Trajectory Viewer"); 
    glutDisplayFunc(renderScene); 
    glutReshapeFunc(changeSize); 
    glutMainLoop(); 
    return EXIT_SUCCESS; 
} 
2

如果你想在OpenGL中開發一個全尺寸的太陽能或其他系統,我建議看一下this這本書。它教你如何開發這種應用程序。否則你的問題有太多可能的解決方案。你應該我更具體。