在过去的几周里,我一直在尝试模拟太阳系模拟中的轨道,我正在将其作为大学模块的一部分。简而言之,我的模拟使用Ogre3D渲染引擎用C ++编写。我曾尝试使用牛顿万有引力定律实现轨道运动,这使得我的行星朝着太阳直线前进,穿过太阳然后回到它的起始位置。我还尝试了这个维基百科article中“位置作为时间函数”部分的步骤,但这对我来说也不起作用。
我使用简单的Euler积分方法驱动模拟。如果有人对这种模拟有任何经验,或者只是对这些物理定律有很多了解,那么任何帮助或指向我正确的方向将不胜感激。
答案 0 :(得分:11)
参考项目“Moving stars around”,有一个旧的C和一个现代化的Ruby版本。 (现在是C ++版本?)
简短建议:欧拉方法对节能不利。显性欧拉增加能量,隐含欧拉减少能量。只需检查谐振子y''+ y = 0的相空间图。
使用辛积分器,最简单和最着名的是已经牛顿用于推理行星运动的Leapfrog or Verlet method。
答案 1 :(得分:6)
你必须给行星初始速度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的因子)以保持稳定,否则它们会爆炸。
答案 2 :(得分:2)
你可以尝试Runge Kutta 4,但是在轨道上仍会有一些“漂移”。为了稳定系统,需要保持系统的总能量不变,但我不确定如何做到这一点。 celestial mechanics的更好方法是symplectic integrator。