为什么我的一维重力模拟不像钟摆?

时间:2018-04-02 18:20:24

标签: java processing simulation physics gravity

我的重力模拟更像是重力弹弓。一旦两个物体相互越过,它们的加速远远超过它们在另一侧的减速。它不平衡。它不会在一个吸引子周围振荡。

其他重力模拟器如何绕过它?例如:http://www.testtubegames.com/gravity.html,如果你创造了两个实体,它们只会前后摆动,不会比原来的距离漂得更远,即使它们在我的例子中相互移动。

它应该是怎样的。但在我的情况下,一旦他们靠近,他们就会相互射击到想象中的银河系的边缘,永远不会回来好几十年。

编辑:以下是错误https://imgur.com/PhhRhP7

的视频

这是在处理中运行的最小测试用例。

//Constants: 

float v;

int unit = 1; //1 pixel = 1 meter

float x;
float y;

float alx;
float aly;

float g = 6.67408 * pow(10, -11) * sq(unit); //g constant

float m1 = (1 * pow(10, 15)); // attractor mass
float m2 = 1; //object mass

void setup() {
size (200,200);
  a = 0;
  v = 0;

  x = width/2; // object x
  y = 0;       // object y

  alx = width/2; //attractor x
  aly = height/2; //attractor y
}

void draw() {
  background(0);
  getAcc();
  applyAcc();

  fill(0,255,0);
  ellipse(x, y, 10, 10); //object
  fill(255,0,0);
  ellipse(alx, aly, 10, 10); //attractor
}


void applyAcc() {
  a = getAcc();
  v += a * (1/frameRate); //add acceleration to velocity
  y += v * (1/frameRate); //add velocity to Y
  a = 0;
}

float getAcc() {
float a = 0;
  float d = dist(x, y, alx, aly); //distance to attractor
  float gravity = (g * m1 * m2)/sq(d); //gforce

  a += gravity/m2;

 if (y > aly){
 a *= -1;} 
 return a;
}

3 个答案:

答案 0 :(得分:1)

您的距离不包括对象的宽度,因此对象有效地同时占据相同的空间。

如上所述,“限制重力”的方法是在外边缘接触时添加法向力,如果是物理模拟的话。

答案 1 :(得分:0)

你应该养成debugging your code的习惯。哪一行代码的行为与您的预期不同?

例如,如果我是你,我会在每次计算时打印出gravity的值:

float gravity = (g * m1 * m2)/sq(d); //gforce
println(gravity);

您会注意到,当您的圈子彼此靠近时,您的gravity价值会急剧上升。这是有道理的,因为你除以sq(d)。广告d变小,gravity增加。

您可以简单地限制gravity值,使其不再出现在图表中:

float gravity = (g * m1 * m2)/sq(d);

if(gravity > 100){
  gravity = 100; 
}

或者你可以限制d,以便它永远不会低于某个值,但结果是相同的。

最后你会发现这并不像你想象的那么容易。你将不得不调整参数,以便你的模拟按照你想要的方式工作。

答案 2 :(得分:0)

此处的工作演示:https://beta.observablehq.com/@shaunlebron/1d-gravity

我遵循了模拟的作者发布的解决方案,该解决方案激发了这个问题here

  

-首先,缩短时间步总是有帮助的。我的模拟作为基准运行,每帧大约40个“步长”,每秒运行30帧。

     

-要处理您所讨论的确切问题,我认为将实体建模为不是纯点质量-而是具有一定半径的球形质量将是至关重要的。这样可以防止重力分散到无穷大。因此,例如,如果在我的模拟中将小行星放到恒星中(关闭了碰撞),重力将随着小行星的靠近而增加,直到到达恒星的表面为止,此时该力将开始减少。当它位于恒星中​​心(或附近)时,作用力将为零(或几乎为零),而不是接近无限大。

在我的演示中,当两个对象足够靠近时,我刚刚关闭了重力。似乎工作足够好。