【问题标题】:Modelling the solar system in openGL [closed]在 openGL 中模拟太阳系 [关闭]
【发布时间】:2013-04-19 19:19:43
【问题描述】:

我正在寻找在 c++ 和 openGL 中模拟太阳系,我想知道是否有一种便宜的方法可以生成,它可以返回一个 x、y、z 向量,我可以使用它来更新位置每颗行星每一帧。

【问题讨论】:

  • 可以创建一个有x、y、z点(floats)等的类行星,然后根据每个行星的当前位置和其他相关数据更新它的位置,时间步长delta_t。
  • 为什么要便宜?当然,对于十几个物体,任何计算它们相对位置的旧方法都应该能够达到合理的性能。更棘手的部分将是纹理以及使行星看起来不错。
  • 嗯,我不确定正确的三维运动方程是什么。
  • 那么,您可以让某物在二维中沿椭圆或圆形移动吗?然后,您需要做的就是将平面与一个世界矩阵相乘,该矩阵对应于每个行星的“倾斜”“水平”。这将为您提供第三个维度。

标签: c++ math opengl modeling


【解决方案1】:

关于行星位置,您有多种选择。

  • 不准确(但“在球场上”):假设行星在平面上做圆周运动
  • 有些不准确(但更接近现实):从 JPL 的太阳系动力学组下载行星的“orbital elements”;使用Kepler's equation 传播轨道(比听起来简单得多)。这基本上是正确的(尤其是对于大型行星)。
  • 准确:下载JPL Ephemerides 获取行星位置(DE405 或 DE421),并使用可用的阅读器之一(例如,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;  
}

【讨论】:

    【解决方案2】:

    如果你想在 OpenGL 中开发一个完整的太阳能或其他系统,我建议你看一下this 书。它教你这种应用程序开发。否则你的问题有太多可能的解决方案。你我应该更具体吗?

    【讨论】:

      猜你喜欢
      • 2018-08-19
      • 2019-02-05
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 2011-01-04
      • 1970-01-01
      相关资源
      最近更新 更多