在C#中实现牛顿万有引力定律

3

我正在尝试使用万有引力定律创建行星运动的(简陋)模拟,利用该定律计算速度,然后将所有速度相加以计算最终运动方向。但是,在尝试实现公式时,我的行星根本不动,而在控制台输出计算出的速度浮点数时,它显示为+无穷大。下面是我使用的算法:

    private void calculateVelocity()
            {
                List<Vector2> Velocities = new List<Vector2>();
                foreach (Planet p in Game1.Planets)
                {
                   
                    
                    Vector2 dir = Vector2.Subtract(p.Position, p.Position);
                    float radius = dir.Length();
                    float power = G * ((Mass * p.Mass) / radius);
                    float acceleration = power / Mass;
                    float velocity = acceleration * deltaTime * 0.1f;
                    //Console.WriteLine(velocity) -- Outputs random numbers and often +infinity !!!
                    dir.Normalize();
                    dir = Vector2.Multiply(Position, velocity);
                    Velocities.Add(dir);
                    
                }
                foreach (Vector2 v in Velocities)
                {
                    Vector2.Add(Velocity, v);
                }
            }

我希望您能帮我解决这个问题。谢谢,Daniel。

编辑

以下是(希望)正常工作的版本,以防有人需要。

private void calculateVelocity()
            {
                List<Vector2> Velocities = new List<Vector2>();
                foreach (Planet p in Game1.Planets)
                {
                    if(p.Identifier != this.Identifier)
                    {
                    Vector2 dir = Vector2.Subtract(p.Position, Position);
                    float radius = dir.Length();
                    float force = G * ((Mass * p.Mass) / ((float)Math.Pow(radius,2));
                    float acceleration = force / Mass;
                    float velocity = acceleration * deltaTime * 0.1f;
                    //Console.WriteLine(velocity) -- Outputs random numbers and often +infinity !!!
                    dir.Normalize();
                    dir = Vector2.Multiply(dir, velocity);
                    Velocities.Add(dir);
                    }
                }
                foreach (Vector2 v in Velocities)
                {
                    Vector2.Add(Velocity, v);
                }
            }
3个回答

5
您有一个零长度的方向:
Vector2 dir = Vector2.Subtract(p.Position, p.Position);

应该是

Vector2 dir = Vector2.Subtract(p.Position, Position);

或者只是
Vector2 dir = p.Position - Position;

如果我应用它,速度仍然输出非常奇怪的数值,包括正无穷。 - tubberd
这些位置彼此不同吗?这些质量有效(即!= 0)吗?顺便说一下,加速度与自身的质量无关。= G * p.Mass / radiusdeltaTime有有效值吗? - Nico Schertler
是的,位置不同。每个物体的质量为1000.0f。不,我的情况不是这样的,因为如果你解决公式 F = m * a,你会得到 a = F / m,这之后我用它来计算速度。deltaTime小于1,但从未为0或负数。 - tubberd
1
然后,您应该记录radiusMassp.Massvelocity,以查看哪些情况下这些值变得不合理。公式是正确的。如果a = F / mF = G * m * m' / r,则a = G * m * m' / (r * m),因此a = G * m' / r。加速度与自身质量无关。 - Nico Schertler

2
你可能需要跳过当前星球。你需要在 foreach 循环内进行测试,以便在计算时跳过 this 。否则,dir 将成为零向量。然后,radius 将为 0。
此外,你混淆了功率和力量。这些在物理学中是非常不同的概念。请为所有人更正这一点。
另外,
float power = G * ((Mass * p.Mass) / radius);

应该是:

float force = G * ((Mass * p.Mass) / radius / radius);

由于重力与距离的平方成反比,因此:

你需要:

dir.Normalize();
dir = Vector2.Multiply(Position, velocity); // This overwrites dir... why normalize it first?

我猜您的意思是:

我猜测您的意思是:

dir.Normalize();
dir = Vector2.Multiply(dir, velocity);

这些应该能让你开始运行。

3
天啊,总是那些我忽略的错误...非常感谢 :) - tubberd
抱歉,德语单词“Kraft”可以翻译为“Power”或“Force”,我选择了“Power”。显然没有考虑到它作为性能/努力的同义词。 - tubberd
这不是问题。英语很难。 - Michael McGuire

1

当除以零发生时,浮点数可能会得到无限大的值。首先检查半径或质量是否为0值...


有时候,速度会有一个有效的值,比如1.6643543或者其他什么值,在这些值之间总是+无穷大。 - tubberd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接