如何在太阳系模拟器中添加月亮?

Pau*_*ian 4 java math physics javafx

我正在尝试用 Java 编写太阳系模拟代码(使用现实世界的值)。首先,我利用牛顿万有引力公式和决定轨道时间的起始速度制作了一颗绕太阳旋转的行星。代码的工作原理如下:我有一个行星列表(假设太阳是一颗行星),在每一帧上我循环遍历该列表,并根据所有其他行星的总力对每个行星应用重力。每个行星在 2D 空间中都有一个速度矢量和一个位置矢量,并且执行最多工作的 2 个函数如下所示:

private Point2D getAttractionForce(Planet planet){
    double distanceX = planet.x-this.x;
    double distanceY = planet.y-this.y;
    double distance = Math.sqrt(Math.pow(distanceX, 2)+Math.pow(distanceY, 2));

    double force = SolarSystem.G*this.mass*planet.mass/Math.pow(distance, 2);
    double angle = Math.atan2(distanceY, distanceX);
    double forceX = force * Math.cos(angle);
    double forceY = force * Math.sin(angle);

    return new Point2D(forceX, forceY);
}

public void updatePosition(List<Planet> planets){
    double totalForceX = 0;
    double totalForceY = 0;

    for (Planet planet : planets){
        if (planet == this) continue;
            Point2D force = getAttractionForce(planet);
            totalForceX += force.getX();
            totalForceY += force.getY();
        }
    }

    this.xVelocity += totalForceX/this.mass*TIMESTEP;
    this.yVelocity += totalForceY/this.mass*TIMESTEP;

    this.x += this.xVelocity*TIMESTEP;
    this.y += this.yVelocity*TIMESTEP;
}
Run Code Online (Sandbox Code Playgroud)

问题

我的问题是,当我在地球附近添加一个月亮时:

Planet moon = new Planet(Color.GRAY, 4, 7.35e22, -(1.50e11+4e8), 0, 0, 1022);
Run Code Online (Sandbox Code Playgroud)

月球受到太阳的吸引,无法按应有的方式绕地球旋转。出于调试目的,我计算了这些值:

Distance moon-sun: 1.504E11
Sun force for moon: 4.313523549126089E20
Distance moon-earth: 4.0E8
Earth force for moon: 1.831019119125E20
Run Code Online (Sandbox Code Playgroud)

我所受到的月球与太阳之间的吸引力是月球与地球之间的吸引力的4倍。我尝试改变月球的初速度,但我得到的只是月球绕太阳旋转。我究竟做错了什么?

这是完整的代码(需要JavaFX):https ://pastebin.com/fiU4m7Te

任何帮助表示赞赏,谢谢

MvG*_*MvG 7

从太阳看来,地球和月球都以几乎相同的速度朝几乎相同的方向运行。太阳对月球施加强大的力是有道理的,但这种力应该主要导致月球与地球一起绕太阳运动,因为两者经历的加速度几乎相同。

只有当你仔细观察时,单独的运动才会变得明显。那里对地球的吸引力较弱,并且由于位置略有不同,朝向太阳的加速度也略有差异。

你们还面临着地月系统中截然不同的速度。如果您的模拟以离散时间步长运行,则可能会导致严重的问题,因为它可能导致地球在一个时间点的位置与下一个时间点的位置有很大不同。

如果您知道哪些卫星围绕哪些行星运行(例如,您不需要模拟如果一颗流氓行星捕获卫星并将其拉走会发生什么),那么也许您可以通过仅关注差异来获得更好的结果。假设月球在很大程度上像行星一样运动。然后计算由于行星的吸引力和与太阳的位置差异而产生的加速度差异,并使用该加速度差异来跟踪位置差异的演变,即以行星为中心的参考系中的轨道。

还有一些方法可以使用更高级的数值积分技术,例如Runge-Kutta辛积分器,但了解它们可能需要一些时间。

  • 如果地球轨道为 1.504E11 米的圆,周期为 365 天,则该行星每天运行 2.589E9 米。这“大大”超过了行星和月球之间的 4E8 距离。因此,单个模拟步骤就已经将行星带到了很远的地方,几乎不会影响月球。也许你正在观察,也许你在计算月球上的力之前更新了行星的位置?无论如何,即使您以不同的顺序进行计算,从中获得任何有意义的轨道也非常困难。 (2认同)
  • 您可能应该计算所有加速度,然后更新所有速度,然后更新所有位置。类似这样,所以你不会比其他对象早一天拥有某些对象。但即便如此,我还是希望有一天会变得太过分。然而,选择一个间隔是很困难的,因为如果你把它设置得太小,那么当你将一个微小的变化添加到一个巨大的幅度时,变化的细节就会丢失。尝试一下,看看什么有效,如果有的话? (2认同)