2015-03-13 2 views
0

Я делаю симуляцию n-тела. По какой-то причине, когда у меня есть два тела, вращающиеся вокруг друг друга, и я добавляю третье тело, два начальных тела останавливают орбитали друг друга.Моделирование N-тела - силы для вычисления тела в некоторых случаях

Пример:

http://i.imgur.com/6zlKPMv.png - земля вращается вокруг солнца, когда я добавляю Марс, http://i.imgur.com/gybHGZE.png, Земля и Марс вращаются не вокруг Солнца, и оба путешествия по прямой линии. Почти так же, как силы не вычисляются вообще на теле. Как это может быть?

Вот соответствующий код:

UPDATE

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

Это, вероятно, весь код, который имеет отношение, пожалуйста, спросите меня, если вы должны смотреть на вся программа или какие-либо другие вопросы. Я мог бы действительно использовать вашу помощь, проект должен скоро. Пожалуйста, имейте в виду, что я только в старшей школе, и я вовсе не опытный программист.

ответ

2

Вчера был другой вопрос о очень похожем коде: n-body simulation - IndexOutOfBoundsException occurring randomly. Вы захотите прочитать ответы, так как ваши взгляды будут восприимчивы к той же проблеме, о которой сообщалось.

Ваша специфическая проблема, однако, заключается в размещении вашего вызова resetForces(). Поскольку этот метод не принимает аргументов, он должен сбросить силы для всех тел в симуляции. Поэтому вы должны ссылаться на него ровно один раз за каждый шаг времени. Вместо этого вы вызываете его один раз на тело, поэтому каждый раз, когда вы рассматриваете новое тело, вы удаляете все силы, рассчитанные для всех других тел.

Странно, кроме того, что вы смешиваете обновления положения с помощью вычислений силы. Я бы ожидать, что моделирование действовать в двух основных, отдельных шагов для каждого временного интервала:

  1. расчета чистой силы, действующие на каждое тело в моделировании в начале интервала, затем
  2. обновления скорости и положения каждого тела на основе его начального положения и скорости и действующей на него чистой силы.

Если вы обнаружение столкновений (как, впрочем, вы делаете), следует, вероятно, выполняется для каждого интервала времени после того, как все обновления позиции были выполнены, не чередуется с обновлениями позиции, либо в некоторых случаях вы будете сравнивать позиции из разных времен.

+0

Несмотря на неэффективность, метод resetForces не является проблемой, так как ускорение также устанавливается при установке силы. Таким образом, даже если сила сброшена на тело, она будет помнить ускорение и двигаться в соответствии с ним. Но я изменил его так, что он только сбрасывает силу индекса в цикле. Не будет ли код длиннее? Есть ли причина не делать то, что я сделал? – Arcthor

+0

Может ли быть какая-нибудь другая проблема? @John Bollinger – Arcthor

+0

Конечно, может возникнуть другая проблема. Вы не представили весь свой код, так как я знаю, что в нем? И нет, это не приглашение. Это не сайт проверки кода. –

Смежные вопросы