N体模拟 - 在某些情况下不计算身体的力量

时间:2015-03-13 18:17:51

标签: java

我正在进行n体模拟。出于某种原因,当我有两个相互绕行的物体并且我添加了第三个物体时,两个初始物体停止相互绕行。

示例:

http://i.imgur.com/6zlKPMv.png - 地球绕太阳运行,当我添加火星时,http://i.imgur.com/gybHGZE.png,地球和火星不绕太阳运行,两者都沿着直线行进。几乎没有在身体上根本没有计算力量。怎么会这样?

以下是相关代码:

更新

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);
}

这可能是所有相关的代码,请问我是否需要查看整个程序或有任何其他问题。我真的可以使用你的帮助,项目即将到期。请记住,我只是在高中,我不是一个经验丰富的程序员。

1 个答案:

答案 0 :(得分:2)

昨天有一个关于非常相似的代码的问题:n-body simulation - IndexOutOfBoundsException occurring randomly。你会想要阅读答案,因为你的答案似乎容易受到那里报告的同样问题的影响。

但是,您的特定问题似乎是调用resetForces()。由于该方法不参数,因此必须重置模拟中所有实体的力。因此,您应该每个步骤调用一次。相反,你每个身体都会调用一次,所以每次你考虑一个新的身体时,你也会擦除为所有其他身体计算的所有力。

此外,您似乎很奇怪,您正在通过力计算来混合位置更新。我希望模拟在每个时间间隔内以两个主要的单独的步骤进行:

  1. 计算在间隔开始时模拟中每个物体上的净力,然后
  2. 根据每个身体的初始位置和速度以及作用于其上的净力来更新每个身体的速度和位置。
  3. 如果您进行碰撞检测(确实如此),它可能应该在 all 执行位置更新后的每个时间间隔执行,而不是与位置更新交错,否则在某些情况下你将比较不同时间的位置。