考虑大部分物体都是小质量物体的情形(类似于稳定的恒星系统),在多体模拟中,可以将整个系统划分成多个引力区域,通过二体问题的求解来模拟物体运动。
二体问题是为数不多的能被求解的复杂运动,二体问题的运动微分并不复杂,即最为经典的万有引力公式,在忽略小质量物体的质量后,可以写作
使用迭代计算计算此算式的计算量并不大,但迭代计算最大的问题的运动趋于发散,或是说迭代过程中物体的能量不守恒。当然这可以通过更好的迭代方法缓解。但对于二体问题,其是可以通过运动方程的求解计算其精确解。这意味这物体的运动状态可以被转化为静态参数,通过时间来确定物体的运动矢量(位移与速度)
不过通过方程求解的过程中也存在诸多问题,尤其是方程求解过程中产生分支的情形,这个项目主要是测试二体问题是否能在GPU上被高效求解,以及是否能通过插值的方式使得方程求解的性能优于迭代求解
在这个模型中,大部分物体都是小质量物体,其质量可以被忽略,
使用方程求解运动,将静态参数与运动矢量相互转换,以达到物体互动的效果
graph LR
状态矢量---方程求解-->轨道参数---时间参数
轨道参数---方程求解-->状态矢量
subgraph 轨道力学
方程求解
轨道参数
end
subgraph 迭代计算
动态受力-->状态矢量
状态矢量
碰撞检测-->状态矢量
end
项目地址:
https://github.com/StellarWarp/RestrictedGravitySimulation
为了能与不同的天体产生互动,同时仍不引入多体引力,整个引力系统被划分为多个引力范围。比如一个恒星与一个行星,物体以最小的引力范围为中心环行。
如何定义引力范围的大小?一般来说,当中心天体对物体的摄动大于其卫星时,可以认为卫星的引力已经可以被忽略
卫星轨道偏心率为0的情形下,引力范围(Sphere Of Influence)可以使用如下的公式计算
可以使用碰撞检测的方法来确定物体是否离或进入引力范围
这一部分内容讲述如何,将轨道参数转换为物体的位移与速度,即从时间参数转换为物体的位置与速度
轨道参数一般使用开普勒六参数来描述,开普勒六参数包括
-
$a$ 半长轴 semi-major axis -
$e$ 偏心率 eccentricity -
$i$ 仰角 inclination -
$\Omega$ 赤径 longitude of ascending node -
$\omega$ 近心点幅角 Argument of periapsis -
$\upsilon$ 真近点角 True anomaly
我们需要解决两个问题
- 将轨道参数转换为物体的位移与速度
- 将时间转化为轨道参数
给定轨道参数,求解物体的位置与速度是一个简单的几何问题
快速回顾一下椭圆与双曲线的几何性质
在椭圆中有
在双曲线中有
离心率的定义为
圆锥曲线的统一方程为
其中
这个方程可以表示圆、椭圆、双曲线、抛物线,虽然其在数学上有很好的一致性,但是在计算上会出现一些问题,当$e=1$时,分母为0,无法计算
这里不采用圆锥曲线的统一方程,因为在偏心率趋近于1时(低速状态下)会导致数值发散
参数方程
对于椭圆、圆形轨道,可以使用参数方程来表示
对于双曲线轨道,这里需要引入双曲函数
双曲线的参数方程为
从参数方程求解物体与焦点的距离
由圆锥曲线的定义可知
现在将
带入
有
通过类似的推导过程可以得到,双曲线中的
带入
平面位移
平面速度
在前得到的距离公式为
轨道速度公式为
速度向量
为区分两种轨道、减少分支,双曲轨道的半长轴为负数即
平面位移
平面速度
在前得到的距离公式为
轨道速度公式为
速度向量
其中旋转的计算方法
R = ti.math.rotation3d(0.0, 0.0, W)@ti.math.rotation3d(i, 0.0, 0.0)@ti.math.rotation3d(0.0, 0.0, w)
我们已经知道了如何将轨道参数角转化为空间位置、速度,但是我们需要的是时间与空间位置、速度的关系,所以我们需要将时间转化为轨道参数角。而唯一与时间相关的轨道参数是真近点角
定义平近角
开普勒给出了平近角与偏近点角的关系,这称为 开普勒方程(Kepler's equation)
对于双曲轨道
至此我们可以给出计算的流程
graph LR
t-.t-t0.->τ-.M=n*τ.->M-.Kepler Equation.->E
M-.Kepler Equation.->H
E-->X
E-->V
H-->X
H-->V
对于椭圆轨道下的开普勒方程
$$
M=E-e \sin E\
$$
这里参考美国海军天文台 Marc A. Murison
A Practical Method for Solving the Kepler Equation
使用三阶迭代方程计算椭圆轨道的开普勒方程
推导过程
将其写成方程形式,当$x=0$时即
误差值$ε≡x−E$则有
泰勒展开
取一阶项
误差值写成迭代式
二阶项
将一阶误差值带入
三阶项$x−esinx−M−(1 −ecosx)ε+\frac{1}{2}ε^2esinx−\frac{1}{6}ε^3ecosx$转换带入二阶误差值迭代式,最终有
三阶迭代后,初始值已经与收敛值接近,初始迭代值
下图展示了初始值与收敛值的误差
当离心率接近于1时会有较大的误差
写成递归形式
双曲角
双曲轨道与椭圆轨道的开普勒函数在某种意义上来说是统一的,但是这里还是单独计算双曲轨道的开普勒方程
将其写成方程
求导展开带入上述方法即可得到解
但是很遗憾的是迭代的初值方法对于双曲轨道并不适用,其会导致数值发散,所以,这里采用了比较简陋的方法,采用$\arcsin(M)$作为迭代初值
下图为基准值
下图为初始值的差值
此方法并没有进行验证,双曲线下的迭代次数不一定为最优
进行预计算,将计算结果提前储存在一张贴图中,后续通过查表插值来得到较为接近的初值
对于椭圆轨道,可以进行周期映射,将$E$的范围映射到$[-\pi,\pi)$的区间内进行插值
对于双曲轨道,$M$ 与
并且考虑到开普勒方程的对称性,预计算结果中只需要存储$M>0$或者$M<0$的结果
这里的的公式推导涉及定积分初值的确定,内容已经有点多了,这里直接给出最终的计算方法
对于椭圆轨道
对于双曲轨道
正向
graph LR
t-.t-t0.->τ-.M=n*τ.->M-.Kepler Equation.->E & H
E & H-->r & X & V
从M转换到E或H需要求解开普勒方程,开销高。但是逆向求解的开销并不高
逆向
graph LR
r & X & V-->1[E or H]-->M-->τ-->t
考虑到性能与精度问题,双曲轨道与椭圆轨道所采用计算方式并不统一,为避免在GPU上的分支开销。需要将椭圆轨道的物体与双曲轨道的物体分离计算。
而椭圆轨道与双曲轨道会在某些情况下发生变化,需要考虑两种轨道的转换问题。
项目里采用的方法是将存储物体参数的field分区,因为虽然两种轨道可能互相转换,只要不增加或减少,物体的总数不变
可以采取交换与调整边界的方式将两边的转化参数的类型
通过方程求解状态矢量的计算量较大,但是求解的结果稳定,考虑采用插值的方法来减少计算量
将所有物体的方程求解分布在多帧中,使用插值的方法获取当前帧的位置