У меня много частиц в космосе.
Каждая частица знает свое положение в пространстве, а также некоторые вещи, такие как масса, скорость и ускорение.
public class Particle
{
float mass;
float velocity;
float acceleration;
}
У меня есть класс, который контролирует гравитацию. Этот класс имеет List
всех Particles
. Я могу рассчитать силу тяжести двух частиц, используя приведенную ниже формулу.
F1 = F2 = G*M1*M2/d^2
Как рассчитать это, когда у меня есть 5 частиц в моем списке? В будущем их будет больше.
Элемент 0 с 1, Элемент 1 с 2, Элемент 2 с 3, Элемент 3 с 4 и Элемент 4 с 0? (Это не кажется хорошей идеей).
Это должно быть хорошей отправной точкой:
namespace SO.NBody
{
public class Particle
{
public double mass;
public double[] position;
public double[] velocity;
public double[] acceleration;
public Particle(double mass)
{
this.mass=mass;
this.position=new double[Simulation.DOF];
this.velocity=new double[Simulation.DOF];
this.acceleration=new double[Simulation.DOF];
}
}
public class Simulation
{
// Degrees of Freedom, Planar Simulation = 2, Spatial Simulation = 3
public static int DOF=2;
// Set Universal Gravity as Needed here
public const double G=100;
public Simulation()
{
Bodies=new List<Particle>();
Time=0;
}
public List<Particle> Bodies { get; private set; }
public double Time { get; set; }
public void CalculateAllAccelerations()
{
for (int i=0; i<Bodies.Count; i++)
{
Bodies[i].acceleration=new double[DOF];
for (int j=0; j<i; j++)
{
// Find relative position, which is needed for
// a) Distance
// b) Direction
double[] step=new double[DOF];
double distance=0;
for (int k=0; k<DOF; k++)
{
step[k]=Bodies[i].position[k]-Bodies[j].position[k];
// distance is |x^2+y^2+..|
distance+=step[k]*step[k];
}
distance=Math.Sqrt(distance);
// Law of gravity
double force=G*Bodies[i].mass*Bodies[j].mass/(distance*distance);
// direction vector from [j] to [i]
double[] direction=new double[DOF];
for (int k=0; k<DOF; k++)
{
direction[k]=step[k]/distance;
}
// Add equal and opposite acceleration components
for (int k=0; k<DOF; k++)
{
Bodies[i].acceleration[k]-=direction[k]*(force/Bodies[i].mass);
Bodies[j].acceleration[k]+=direction[k]*(force/Bodies[j].mass);
}
}
}
}
public void UpdatePositions(double time_step)
{
CalculateAllAccelerations();
// Use symplectic integration
for (int i=0; i<Bodies.Count; i++)
{
for (int k=0; k<DOF; k++)
{
Bodies[i].velocity[k]+=time_step*Bodies[i].acceleration[k];
Bodies[i].position[k]+=time_step*Bodies[i].velocity[k];
}
}
Time+=time_step;
}
public void RunSimulation(double end_time, int steps)
{
double h=(end_time-Time)/steps;
while (Time<end_time)
{
// Trim last step if needed so the sim ends when specified
if (Time+h>end_time) { h=end_time-Time; }
UpdatePositions(h);
}
}
}
class Program
{
static void Main(string[] args)
{
var world=new Simulation();
var sun=new Particle(1000);
var p1=new Particle(1.15)
{
position=new double[] { 100, 0 },
velocity = new double[] { 0, 10 }
};
var p2=new Particle(1.05)
{
position=new double[] { 120, 0 },
velocity=new double[] { 0, 6 }
};
// ...
world.Bodies.Add(sun);
world.Bodies.Add(p1);
world.Bodies.Add(p2);
//...
// Run for t=10.0, with 100 steps
world.RunSimulation(10.0, 100);
}
}
}
На каждой временной отметке в вашей симуляции вычисляйте полную векторную силу на каждой частице и перемещайте эту частицу с ускорением, равным полной силе, деленной на массу частицы.
Чтобы найти полную силу на каждой частице, вычислите гравитационные силы между частицей и каждой из других частиц и добавьте все это. Обратите внимание, что когда вы вычисляете каждую силу, это должна быть векторная сила, то есть сила с величиной, как в вашем уравнении, и направление к другой частице. (То есть, используйте эту версию закона тяготения Ньютона: http://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation#Vector_form)
Наряду с силой все здесь должно быть сделано с использованием векторов: положение, скорость, ускорение и сила, все как векторы. Массы - ваши единственные скаляры, как вы описали проблему. (То есть в вашем классе Particle
масса может быть плавающей, но скорость и ускорение должны быть векторами с компонентами x, y и z).
На самом деле закон гравитации применяется только к двум объектам. Это было как общее исследование Земли и Объекта в космосе или на поверхности.
https://en.wikipedia.org/wiki/Newton's_law_of_universal_gravitation
Здесь, если у вас есть 5 масс, вы можете сделать одну массовую неподвижную или относительную. Который был бы M1
затем проверял бы все массы по отношению к ним, обнаруживая каждую гравитацию. Может быть, здесь вам понадобится какой-то цикл foreach
.
Работать с 5 телами в космосе сложно даже от мистера Ньютона, поэтому он дал вам уравнение для двух тел. Они взаимосвязаны друг с другом. Вы можете использовать эти 2 тела и проверить плотность тела каждого тела. Отнесите их друг другу, потому что изначально они не связаны.