在过去的几周里,我一直在尝试在作为大学模块的一部分制作的太阳系模拟中模拟轨道。简而言之,我的模拟是使用 Ogre3D 渲染引擎用 C++ 编写的。我试图使用牛顿万有引力定律来实现轨道,它使我的行星直线朝向太阳,穿过太阳,然后回到它的起始位置。我还尝试了这篇维基百科文章的“作为时间函数的位置”部分的步骤,但这对我也不起作用。
我正在使用简单的欧拉积分方法来驱动模拟。如果有人对这种模拟有任何经验,或者只是对这些物理定律有很多了解,那么任何帮助或指出我正确的方向将不胜感激。
在过去的几周里,我一直在尝试在作为大学模块的一部分制作的太阳系模拟中模拟轨道。简而言之,我的模拟是使用 Ogre3D 渲染引擎用 C++ 编写的。我试图使用牛顿万有引力定律来实现轨道,它使我的行星直线朝向太阳,穿过太阳,然后回到它的起始位置。我还尝试了这篇维基百科文章的“作为时间函数的位置”部分的步骤,但这对我也不起作用。
我正在使用简单的欧拉积分方法来驱动模拟。如果有人对这种模拟有任何经验,或者只是对这些物理定律有很多了解,那么任何帮助或指出我正确的方向将不胜感激。
参考项目“ Moving stars around ”,有一个旧的 C 和一个现代化的 Ruby 版本。(现在是 C++ 版本?)
简短的建议:欧拉方法不利于能量守恒。显式欧拉增加能量,隐式欧拉减少能量。只需在谐振子 y''+y=0 的相空间图上查看即可。
使用辛积分器,最简单和最著名的是牛顿已经用来推理行星运动的Leapfrog 或 Verlet 方法。
您必须给行星初始速度 v = (vx, vy, vz) 与所需轨道相切。如果太阳的位置是s,行星是p,那么两者之间总是有一个力作用:行星上的那个指向太阳,向量t=(s - p),反之亦然。这个力的大小是 g Ms Mp / (t dot t),其中“dot”是点积,g 是重力的标准加速度,Ms、Mp 是各自的质量。
如果您正在做一个所有物体都可以对所有其他物体施加拉力的详细模型,那么算法是累积所有成对力以获得作用在每个物体(行星或太阳)上的单个合力矢量。否则,您可能会接受一个近似值,即只有太阳拉动行星,而其他力被认为太小而无关紧要。
所以算法是:
Choose dt, the time step, a small interval.
Set initial positions and velocities
(for planets, velocity is tangent to desired orbit. Sun has velocity zero.)
loop
Accumulate all forces on all bodies with current positions.
For each body position=p, velocity=v, net resultant force=f, mass=m,
update its velocity: v_new = v + f / m dt
update position p_new = p + 0.5 * (v + v_new)
v = v_new; p = p_new
Render
end loop
如前所述,欧拉很简单,但需要非常小的时间步才能获得合理的精度。有时,您可以在系统中引入一点点阻力(将速度乘以仅略低于 1 的因子)以保持事物稳定,否则它们会爆炸。
你可以试试Runge Kutta 4,但轨道上仍然会有一些“漂移”。稳定系统需要保持系统的总能量恒定,但我不确定这是如何完成的。一种更好的天体力学方法是辛积分器。