在c#中计算定制太阳能系统

时间:2018-03-28 08:48:16

标签: c# game-physics

我正在尝试为研究项目创建一个自定义太阳能系统,以测试不同的数值方法并查看它们之间的区别。

我们制造自己的太阳系而不是试图模拟地球/太阳,因为这似乎更难。

现在我们有一个太阳M1和地球M2。

  • M1 = 3500
  • M2 = 500
  • 从M1到M2的距离= 200
  • 我们使用不同的G = 0.2

当我们计算它的重力时,它应该是,F = 8.75或-8.75(F = GM1M2 / r ^ 2)

当我们计算恒定速度时,地球应绕地球运行,我们发现v = 2(v = sqrt(G(M1 + M2)/ r))

要计算力的vec2,我们使用以下代码

    static double GravitationalConstant = 0.2f;//6.674e-11;
    static public Vector2f GravitationalForce(SolarObject onObj, SolarObject fromObj)
    {
        Vector2f result = fromObj.OldPosition - onObj.OldPosition;

        float distance = result.Lenght();
        Console.WriteLine(distance);
        result = new Vector2f(result.X / distance, result.Y / distance); // Normalized, but I've the lenght al ready so

        result *= (float)((GravitationalConstant * onObj.Mass * fromObj.Mass) / (distance * distance));

        return result;
    }

要更新位置/速度,我们使用此

public void Update(float dt, List<SolarObject> objects)
    {
        foreach(SolarObject s in objects.Skip(1))
        {
            Vector2f f = Utility.GravitationalForce(s, objects[0]);

            Vector2f a = f / s.Mass;

            s.OldPosition  = s.NewPosition;
            s.NewPosition += dt * s.Velocity
            s.Velocity += dt * a;
        }
    }

物体围绕太阳飞行,但它根本不是轨道。 M1 / M2之间的距离不是恒定的&lt; - &gt;。力也不总是等于8.75f。我们知道欧拉有一个“错误”,但这似乎很大,因为即使在一个圆周轨道上,25%的距离也准备增加。所以某处必须有一个错误。

1 个答案:

答案 0 :(得分:3)

不幸的是,这种行为是欧拉积分所固有的 - 你总是会在某种程度上超越弯曲的路径。使用较小的时间步长可以抑制此效果,即使没有double s:

也可以
  • dt = 0.01

    enter image description here

  • dt = 0.001

    enter image description here

  • dt = 0.0001

    enter image description here

  • dt = 0.00001

    enter image description here

正如您所看到的,Euler方法的准确性随着时间步长的减少而提高。内行星(较小的轨道半径=较大的曲率=更多的超调)开始更加一致地跟随它们的投射轨道(绿色)。对于dt = 0.0001的最内层行星,过冲变为,而dt = 0.00001则完全不可见。

为了改进欧拉方法而不必采用可笑的小时间步长,可以使用例如 Runge-Kutta 集成(4阶变体很受欢迎)。

此外,轨道速度应该是v = sqrt(G*Msun/r))而不是v = sqrt(G(M1+M2)/r)),但对于大的星限,这不应该造成太多问题。

(如果您想要我的测试代码,请告诉我 - 虽然编写得非常糟糕,核心功能与您的相同。)