你需要使用向量方程:
// init values (per object)
double ax=0.0,ay=0.0,az=0.0; // acceleration [m/s^2]
double vx=0.0,vy=0.0,vz=0.0; // velocity [m/s]
double x=0.0, y=0.0, z=0.0; // position [m]
double m=1.0; // mass [kg]
// iteration inside some timer (dt [seconds] period) ...
int i; double a,dx,dy,dz; // first compute acceleration
for (ax=0.0,ay=0.0,az=0.0,i=0;i<obj.num;i++)
if (obj[i]!=this) // ignore gravity from itself
{
dx=obj[i].x-x;
dy=obj[i].y-y;
dz=obj[i].z-z;
a=sqrt((dx*dx)+(dy*dy)+(dz*dz)); // a=distance to obj[i]
a=6.67384e-11*(obj[i].m*m)/(a*a*a); // a=acceleration/distance to make dx,dy,dz unit vector
ax+=a*dx; // ax,ay,az = actual acceleration vector (integration)
ay+=a*dy;
az+=a*dz;
}
vx+=ax*dt; // update speed via integration of acceleration
vy+=ay*dt;
vz+=az*dt;
x+=vx*dt; // update position via integration of velocity
y+=vy*dt;
z+=vz*dt;
代码取自here
-
obj[] 是您所有对象的列表
-
obj.num 是他们的数量
我建议使用(ax,ay,az,...m) 中的所有变量创建对象类,将它们初始化一次,然后在某个计时器中不断更新(迭代)。如果您想要更高的精度,那么您应该首先计算所有对象的ax,ay,az,并且仅在更新速度和位置之后(以避免在重力计算期间改变对象的位置)。如果您想驱动一个对象(例如使用 truster),只需将其加速度添加到 ax,ay,az 向量)
现在只设置一个轨道:
-
放置行星对象
必须足够大,并将其position / velocity 设置为您想要的
-
放置卫星
初始位置应该在行星附近的某个地方。它不应该太大。初始化还具有与轨道轨迹相切方向的速度矢量。如果速度太低,它会坍缩成行星,如果速度太高,它会逃离行星,否则会绕轨道运行(圆形或椭圆形)
-
计时器
模拟的间隔越小越好,通常10ms 是可以的,但对于大而远的物体也是100ms 和更多的。如果您想要粒子或其他东西,请使用1ms(非常动态的场景)。
我强烈推荐阅读这篇相关的QA:
特别是[edit3]关于积分精度和创建轨道数据。