我的重力模拟更像是重力弹弓。一旦两个物体相互越过,它们的加速远远超过它们在另一侧的减速。它不平衡。它不会在一个吸引子周围振荡。
其他重力模拟器如何绕过它?例如: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;
}
答案 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帧。
-要处理您所讨论的确切问题,我认为将实体建模为不是纯点质量-而是具有一定半径的球形质量将是至关重要的。这样可以防止重力分散到无穷大。因此,例如,如果在我的模拟中将小行星放到恒星中(关闭了碰撞),重力将随着小行星的靠近而增加,直到到达恒星的表面为止,此时该力将开始减少。当它位于恒星中心(或附近)时,作用力将为零(或几乎为零),而不是接近无限大。
在我的演示中,当两个对象足够靠近时,我刚刚关闭了重力。似乎工作足够好。