重力和许多粒子

本文关键字:粒子 许多 | 更新日期: 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个物体的方程。与相互关联。你可以使用这两个物体,并检查每个物体的重力。将它们相互关联起来,因为最初它们没有关联。