Java/Processing 计算返回 "NaN" 和 "Infinity"

Java/Processing calculations returning "NaN" and "Infinity"

我正在尝试在 Processing/Java 中模拟 three-body problem。我创建了一个 Planet 对象并定义了几个函数来计算行星的吸引力、力和速度。程序运行没有任何错误。问题在于计算返回 Infinity 和 NaN 输出。 我还没有发现任何被零除的错误。 为什么要这样做?

float simulationTime = 0.01;
float earthMass = pow(10,24)*5.972;

Planet[] bodies = {new Planet(100,200, 0, 0,earthMass/2),
                   new Planet(400,500, 0, 0,earthMass/2),
                   new Planet(800,200, 0, 0,earthMass/2)};
int size = 500;
float G = 6.674*pow(10, -11);
float gravAttract(float mass1, float mass2, float x1, float y1, float x2, float y2) {
  float force = G*mass1*mass2/pow(dist1(x1, y1, x2, y2), 2);
  //println(pow(dist1(x1, y1, x2, y2), 2));
  //println(force);
  return force;
}
float attract(Planet one,Planet two){
  float force = G*one.mass*two.mass/pow(dist1(one.xpos,one.ypos,two.xpos,two.ypos),2);
  println(one.xpos,two.xpos,one.xspeed,two.xspeed);
  return force;
}
float[] forceXY(int body){
  float[] xy = {0,0};
  for (int ii = 0; ii<bodies.length; ii = ii+1){
    if (ii == body){
      continue;
    }
    else{
      xy[0] = xy[0]+attract(bodies[body],bodies[ii])*
      (bodies[ii].xpos-bodies[body].xpos)/dist1(bodies[body].xpos,bodies[body].ypos,bodies[ii].xpos,bodies[ii].ypos);
      xy[1] = xy[1]+attract(bodies[body],bodies[ii])*
      (bodies[ii].ypos-bodies[body].ypos)/dist1(bodies[body].xpos,bodies[body].ypos,bodies[ii].xpos,bodies[ii].ypos);
      println(xy);
    }
  }
  return xy;
}
float dist1(float x1,float y1,float x2,float y2){
  float x = dist(x1,y1,x2,y2);
  x = x*149.6*pow(10,7);
  //println(x1,y1,x2,y2);
  return x;
}
class Planet {
  float xpos;
  float ypos;
  float xspeed;
  float yspeed;
  float mass;

  Planet(float a, float b, float c, float d, float e) {
    xpos = a;
    ypos = b;
    xspeed = c;
    yspeed = d;
    mass = e;
  }
  void update(float xforce, float yforce) {
    //println("xy",xpos,ypos);
    float xa = xforce/mass;
    float ya = yforce/mass;
    xspeed = xspeed + xa*simulationTime;
    yspeed = yspeed + ya*simulationTime;
    xpos = xpos + xspeed*simulationTime;
    ypos = ypos + yspeed*simulationTime;
  }
}
void setup() {
  size(1000, 1000);
  frameRate(1);
}
void draw() {
  background(0);
  
  for (int ii = 0; ii < bodies.length; ii = ii+1){
    float[] asdf = new float[2];
    asdf = forceXY(ii);
    circle(bodies[ii].xpos,bodies[ii].ypos,10);
    bodies[ii].update(asdf[0],asdf[1]);
  }
}

我看到您正在尝试使用实际物理值进行计算。问题在于天文质量、距离和力都是天文数字,不仅是字面上的,而且是比喻上的。数字太大,无法使用float数据类型的有限范围表示中间计算的结果。

解决方法是更改​​单位。例如,不使用米、千克和秒,而是以“天文单位”(地球和太阳之间的距离)测量距离,以地球质量的倍数测量质量,以年为单位测量时间。或者使用标准 "astronomical system of units"。最重要的是,这会改变引力常数 G 的值。

如果您不太热衷于进行模拟来预测行星的真实位置,那么只需“即兴发挥”并设置 G=1、将质量设置为较小的数字,以及玩弄速度。你会发现想出一个逼真的模拟是非常容易的。