C++ 开普勒和牛顿定律

标签 c++ math physics sfml

所以我有两个文件。一个主文件和一个 nbody 文件。

我想做的是使用 SFML 绘制到窗口上并基本上模拟银河轨道。我一直遇到的该死的问题是,虽然从语法的角度来看一切正常,但所有的行星都在超出比例并且完全不稳定。

我不明白为什么它不起作用。 请帮我解决这个问题..

这是 nbody 文件。

 #include SFML/Graphics.hpp
 #include SFML/Window.hpp
 #include iostream
 #include cmath
 #include cstring
 class Body:sf::Drawable{
  sf::String file;
  sf::Texture texture;

public:
  double x,y;
  double xvel,yvel,mass,scale,winsize;
  sf::Sprite sprite;
  Body(double _x,double _y,double _xvel, double _yvel, double           _mass,std::string _file,double _scale,double _winsize){
    x = _x;
    y = _y;
    xvel = _xvel;
    yvel = _yvel;
    mass = _mass;
    file = _file;
    scale = _scale;

  }
  sf::Sprite Sprite(){
    texture.loadFromFile(file);
    sprite.setTexture(texture);
    sprite.setPosition(x,y);
    return sprite;
  }

  void move(double position, std::vector<Body> galaxy, double time){
    double G = 6.67 * pow(10,-11);
    double Fx=0, Fy=0;

for(double i=0;i<galaxy.size();i++){
  if(position!=i){      
double x1 = x;
double x2 = (galaxy.at(i)).x;
double dx = (x2-x1)*scale;  ////The math here works

double y1 = y;
double y2 = (galaxy.at(i)).y;
double dy = (y2-y1)*scale; /// The math here works

double m2 = (galaxy.at(i)).mass;
double m1 = mass; //results in mass

double r = sqrt((dx * dx)+(dy * dy));
double F = G*m1*m2/(r*r);


Fx += (F*dx)/r;
Fy += (F*dy)/r; 

  }
  xvel += Fx/mass*time;
  yvel += Fy/mass*time;

  x+=xvel/100000;
  y+=yvel/100000;
  Sprite();
}         
  }

 virtual void draw(sf::RenderTarget& target, sf::RenderStates states)      const{
   target.draw(sprite,states); //parameters should be in here
  }  
};

主文件:

#include <cmath>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <string>
#include <vector>
#include "nbody.cpp"
int main(int argc, char *argv[]){
  void move(double position, std::vector<Body> galaxy,double scale);
  int f;

  std::cin>>f;
  double radius, scale, winsize;
  winsize = 800;

  std::cin>>radius;
  std::cout<<radius<<" \n";
  std::vector<Body> galaxy;

  scale = radius/(winsize/2);  
  for(double i=0;i<f;i++){ 
    double x,y,xv,yv,m;
    std::string name;
    std::cin>>x;
    std::cin>>y;
    std::cin>>xv;
    std::cin>>yv;  
    std::cin>>m;
    std::cin>>name;
    x = x/scale+(winsize/2);
    y = y/scale+(winsize/2);

    std::cout<<x<<" "<<y<< " " << xv << " " << yv<< " "<< m<< "\n";

    Body b(x,y,xv,yv,m,name,scale,winsize);
    galaxy.push_back(b);
  }  

  sf::RenderWindow window(sf::VideoMode(winsize, winsize), "Universe");    
  double time =0;
  while (window.isOpen())
    {
      sf::Event event;
      while (window.pollEvent(event))
    {
      if (event.type == sf::Event::Closed)
        window.close();
    }

      window.clear();
      for(double i=0;i<galaxy.size();i++){
    double position = i;
    (galaxy.at(i)).move(position,galaxy,time);  
    sf::Sprite a = (galaxy.at(i).sprite);
    window.draw(a);
      } 
      window.display();
      time +=.1;
    }

  return 0;
}

我有一个行星文本文件,它通过管道传输到生成太阳系的函数中。第一个数字是实体的数量,第二个是半径,每行中的所有其他数字是每个行星的属性:顺序为 (x,y,xvel,yvel,mass,imagefile)

5
2.50e+11
0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  1.9890e+30      sun.gif
 1.4960e+11  0  0.0000e+00  2.9800e+04  5.9740e+24    earth.gif
 2.2790e+11  0           0.0000e+00  2.4100e+04  6.4190e+23     mars.gif
 5.7900e+10  0 0.0000e+00  4.7900e+04  3.3020e+23  mercury.gif
 1.0820e+11  0 0.0000e+00  3.5000e+04  4.8690e+24    venus.gif

谢谢

最佳答案

总是一样的问题:

首先计算所有力,然后,在考虑所有相互作用后,更新速度和位置。将其混合会导致后来的交互越来越多地与新位置一起计算。这引入了一种完全取决于集合中对象顺序的漂移。

看在皮特的份上,使用比辛欧拉更好的东西(我认为你没有意识到这一点)。这对于一些 quick'n'dirty 游戏物理来说是可以接受的,但对于半科学目的来说则不行。至少使用 Verlet 或更好的 RK4 或辛四阶方法。

标准链接:Moving stars around

关于C++ 开普勒和牛顿定律,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29619154/

相关文章:

c++ - 我想在空 tableWidget 中添加带有文本的新项目

c++ - 从二进制文件读取后出现未处理的异常,当控制权返回给调用函数时

Java减去没有库的月份

algorithm - 寻找纳米粒子

javascript - 确定两个圆相交的点和 Angular 。

c++ - 基于范围的循环 : get item by value or reference to const?

c# - 需要数学库来操作序列/范围

javascript - Math.max 不返回正在比较的任何一个数字

iOS - Cocos2d、Box2d 或 Chipmunk

c++ - 仅 WPF 应用程序托管代码吗?