重力和许多粒子
本文关键字:粒子 许多 | 更新日期: 2023-09-27 18:05:09
我在空间中有很多粒子。
每个粒子都知道自己在空间中的位置,以及质量、速度和加速度。
public class Particle
{
float mass;
float velocity;
float acceleration;
}
我有一个控制重力的类。该类具有所有Particles
中的一个List
。我可以用下面的公式计算两个粒子的重力。
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万有引力
这里,如果你有5个质量,你可以做的是使一个质量静止或相对。这将是M1
,然后测试相对于它的所有质量,找到每个质量的重力。也许在这里您也需要某种foreach
循环。
即使牛顿先生也很难在太空中处理5个物体,这就是为什么他给了你一个关于2个物体的方程。与相互关联。你可以使用这两个物体,并检查每个物体的重力。将它们相互关联起来,因为最初它们没有关联。