我正在进行 n 体模拟。由于某种原因,当我有两个物体彼此绕轨道运行并添加第三个物体时,两个初始物体停止彼此绕轨道运行。
示例:
/image/ZIGYY.png - 地球绕太阳公转,当我添加火星时,/image/tcrDK.png ,地球和火星不绕太阳运行,并且都沿直线运行。几乎就像 body 上根本没有计算力一样。怎么会这样?
相关代码如下:
更新
public void update(float deltaTime){
for(int i=0; i<bodies.size();i++){
resetForces();
bodies.get(i).update((float)(deltaTime / Math.pow(10,9))*timeScale);
lastTime = System.nanoTime();
//sets the forces for all bodies
for(int n=0; n<bodies.size();n++){
if(bodies.get(i)!=bodies.get(n)){
if(bodies.get(i) == null || bodies.get(n)==null){
System.out.println("nullPointerException error averted");
}else{
bodies.get(i).setForce(Physics.getFx(bodies.get(i), bodies.get(n)), Physics.getFy(bodies.get(i), bodies.get(n)));
}
if(Physics.getDistanceBetween(bodies.get(i), bodies.get(n)) < (bodies.get(i).radius + bodies.get(n).radius)*distanceScale){
collision(bodies.get(i),bodies.get(n));
if(bodies.size()==i){
return;
}
}
}
}
}
}
行星
public void sun(){
sun = new Body("Sun", Physics.massSun, 20, 0,0, new Color(0xffff00), (float)0, (float)0);
bodies.add(sun);
}
public void earth(){
earth = new Body("earth", Physics.massEarth, 10, Physics.astUnit/distanceScale,0, new Color(0x0000ff), (float)0, (float)0);
bodies.add(earth);
earth.setVelocity(0,(float)Physics.getInitVy((long)Physics.getDistanceBetween(earth, sun), sun));
}
public void mars(){
mars = new Body("Mars", Physics.massMars, 10, (long)(1.5*Physics.astUnit/distanceScale) ,0, new Color(0x00ff00), (float)0, (float)0);
mars.setVelocity(0,(float)Physics.getInitVy((long)Physics.getDistanceBetween(mars, sun), sun));
bodies.add(mars);
}
这可能是所有相关的代码,如果您需要查看整个程序或有任何其他问题,请询问我。我真的需要你的帮助,该项目很快就要到期了。请记住,我只是高中生,我根本不是一个有经验的程序员。
最佳答案
昨天有一个关于非常相似的代码的不同问题:n-body simulation - IndexOutOfBoundsException occurring randomly 。您将需要阅读答案,因为您的答案似乎很容易受到那里报告的相同问题的影响。
但是,您的具体问题似乎是调用 resetForces()
的位置。由于该方法不带任何参数,因此它必须重置模拟中所有物体的力。因此,您应该在每个时间步调用它一次。相反,您对每个物体调用一次,因此每次考虑一个新物体时,您也会删除为所有其他物体计算的所有力。
此外,您将位置更新与力计算混合在一起,这似乎很奇怪。我希望模拟针对每个时间间隔分两个主要的、单独的步骤进行:
- 计算模拟中在时间间隔开始时作用在每个物体上的合力,然后
- 根据每个物体的初始位置和速度以及作用在其上的净力来更新每个物体的速度和位置。
如果您进行碰撞检测(实际上您确实这样做),则可能应该在执行完所有位置更新之后的每个时间间隔执行碰撞检测,而不是与位置更新交错,否则在某些情况下您将比较不同时间的位置。
关于java - N 体模拟 - 在某些情况下不计算物体的力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29039274/