所以我正在对不同的行星进行简单的模拟,这些行星具有各自的速度在太空中飞行并相互绕行。
我计划通过将每个行星视为投影自己的“重力矢量场”来模拟它们相互之间的拉力。每个时间步我将添加从每个行星单独的向量场方程(V = -xj + (-yj) 或类似的符号)输出的向量,除了在计算中受到影响的那个,并使用受影响的行星位置作为方程的输入。
然而,这将是不准确的,并且不认为引力是连续的和恒定的。如果每个行星都持续影响其他行星,我应该计算我的行星的运动吗?
谢谢!
除了 Blender 写的关于使用牛顿方程的内容之外,您还需要考虑如何在“加速度场”上进行积分(正如您在对他的回答的评论中所说的那样)。
最简单的方法是使用欧拉方法。问题在于它迅速发散,但它具有易于编码和相当快的优点。
如果您正在寻找更好的准确性,并且愿意牺牲一些性能,那么Runge-Kutta 方法之一(可能是 RK4)通常是一个不错的选择。我会提醒你,如果你的“加速场”是动态的(即它随着时间的推移而变化......也许是由于行星在它们的轨道上移动的结果)RK4 将是一个挑战。
更新(基于下面的评论/问题):
如果您想计算在某个时间步 t n应用于特定对象i的力矢量F i (t n ) ,那么您需要使用 Blender 引用的方程式计算模拟中所有其他对象贡献的力。也就是说,对于每个对象i,您会计算出所有其他对象如何拉(施加力),并且这些向量在求和时将是施加到i的总力向量。从算法上看,这看起来像:
对于每个对象i F i (t n ) = 0 对于每个对象j ≠ i F i (t n ) = F i (t n ) + G * m i * m j / | p i (t n )- p j (t n )| 2
其中p i (t n ) 和p j (t n ) 分别是对象i和j在时间 t n的位置, | | 是标准欧几里得 ( l 2 ) 法线...即两个对象之间的欧几里得距离。此外,G 是引力常数。
Euler 方法将模拟分解为离散的时间片。它着眼于当前状态,在您的示例中,考虑所有施加到模拟中所有对象的力,然后在时间片期间将这些力作为常数应用。使用时
一个我(t n ) = F我(t n )/m我
( a i (t n ) = 在时间 t n施加到物体i的加速度矢量,F i (t n ) 是在时间t n施加到物体i的力矢量,并且 m i是物体i的质量),力矢量(因此加速度矢量)在时间片的持续时间内保持不变。在您的情况下,如果您确实有另一种计算加速度的方法,则不需要计算力,而是可以直接计算加速度。在任一情况下,在加速度保持恒定的情况下,时间 t n+1的位置,物体的p (t n+1 ) 和时间 t n+1的速度v (t n+1 ) 将由下式给出:
p i (t n+1 ) = 0.5* a i (t n )*(t n+1 -t n ) 2 + v i (t n )*(t n+1 -t n )+ p i (t n ) v i (t n+1 ) = a i (t n+1 )*(t n+1 -t n ) + v i (t n )
RK4 方法将您的系统驱动程序拟合到一个 2 次多项式,该多项式可以更好地逼近其行为。详细信息在我上面引用的 wikipedia 站点上,您应该能够在网络上找到许多其他资源。基本思想是,不是为特定时间片选择单个力值,而是在特定时间计算四个力向量,然后将力向量拟合到二次多项式。如果您的力矢量场在时间片之间没有变化,那很好。如果您使用重力来导出矢量场,并且作为重力源的物体移动,那么您需要计算它们在四个子间隔中的每一个的位置,以便计算力矢量。可以办到,但是你的表现会比使用欧拉的方法差很多。从好的方面来说,您可以获得更准确的对象相对于彼此的运动。因此,从某种意义上说,这是一个挑战,因为它的计算成本很高,而且在迭代的时间片中找出四个样本的所有对象应该在哪里有点痛苦。
与计算机打交道时没有“连续”之类的东西,因此您必须以非常小的时间间隔来近似连续性。
话虽如此,您为什么要使用矢量场?牛顿怎么了?
物体上的力的总和就是上面的方程。将两者相等并求解a
所以你只需要一个一个地遍历所有对象并找到它的加速度。