重力和许多粒子

时间:2014-05-26 21:00:22

标签: c# physics

我在太空中有很多粒子。

每个粒子都知道它在空间中的位置以及质量,速度和加速度等等。

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? (这似乎不是一个好主意)。

3 个答案:

答案 0 :(得分:1)

在模拟中的每个时间步,计算每个粒子上的总矢量力,并使用等于总力量除以粒子质量的加速度移动该粒子。

要找到每个粒子上的总力,计算粒子与其他每个粒子之间的重力,并将它们全部加起来。注意,当你计算每个力时,它必须是矢量力,即一个具有等式中的力的力,以及朝向另一个粒子的方向。 (也就是说,使用这个版本的牛顿引力定律:http://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation#Vector_form

除了力量之外,这里的一切都应该使用矢量来完成:位置,速度,加速度和力,都是矢量。正如你所描述的那样,群众是你唯一的标量。 (也就是说,在你的Particle类中,质量可以是浮点数,但速度和加速度需要是向量,包含x,y和z分量。)

答案 1 :(得分:1)

这应该是一个很好的起点:

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

答案 2 :(得分:0)

实际上,引力定律仅适用于2个物体。这是对太空或地表上的地球和物体的一般研究。

https://en.wikipedia.org/wiki/Newton's_law_of_universal_gravitation

如果您有5个质量,那么您可以做的是使一个质量静止或相对。那将是M1然后测试相对于它的所有质量发现每个重力。也许在这里你也需要某种foreach循环。

在太空中使用5具尸体,即使是牛顿先生也很困难,这就是为什么他给你一个2个身体的等式。与彼此相互关联。你可以使用这两个身体,并检查每个身体的重力。将它们相互关联,因为最初它们并不相关。