-3

私は太陽系を c++ と openGL 内でモード化しようとしています。各惑星の位置を毎回更新するために使用できる x、y、z ベクトルを返す安価な方法があるかどうか疑問に思っていました。フレーム。

4

2 に答える 2

6

惑星の位置に関しては、いくつかの選択肢があります。

  • 不正確 (しかし「球場内」): 惑星が平面上で円を描いて移動すると仮定する
  • やや不正確 (ただし現実にかなり近い): JPL の太陽系ダイナミクス グループから惑星の「軌道要素」をダウンロードします。ケプラーの方程式を使用して軌道を伝播します(見た目よりもはるかに簡単です)。これはほとんど正しいでしょう (特に大きな惑星の場合)。
  • 正確: 惑星の位置 (DE405 または DE421) のJPL Ephemeridesをダウンロードし、利用可能なリーダーの 1 つ (たとえばSPICE ) を使用して、現在可能な限り正確に状態を取得します (これは必ずしも「計算コストが高い」とは限らないことに注意してください)。 )
  • 正確: VSOPデータと関連プログラムをダウンロードします (JPL の天体暦ほど正確ではありませんが、「ミッション予備設計グレード」でもあります)。

SPICE と OpenGL を使用してDE421データを視覚化するための「手っ取り早い」方法を示すために、少し前に書いたコードを見つけました。多分それはあなたを助けることができます。

シンプルなスクリーンショット

#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;  
}
于 2013-04-25T19:52:25.083 に答える
1

OpenGL でフル スケールのソーラー システムやその他のシステムを開発したい場合は、この本を読むことをお勧めします。この本はまさにこの種のアプリケーション開発を教えてくれます。そうでなければ、あなたの質問には考えられる解決策が多すぎます。

于 2013-04-25T19:24:15.813 に答える