Spaceflight 模拟器如何预测飞行路径?

How does Spaceflight simulator predict flight-paths?

我正在尝试使用 Unity 制作一款游戏,该游戏使用在轨火箭并可以转移到不同的行星,但我需要实时预测火箭路径,具体取决于当前 velocity/direction像 spaceflight simulator 那样分配火箭。

当向刚体添加引力时,我已经设法获得逼真的物理和轨道:

    var sateliteCords = Satelite.transform.position;
    var planetCords = gameObject.transform.position;
    var distance = sateliteCords - planetCords;
    distanceFromSatelite = Vector3.Distance(Satelite.transform.position, gameObject.transform.position);
    F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
    forces = (distance / Mathf.Sqrt(Mathf.Pow(distance.x, 2)+ Mathf.Pow(distance.y, 2)+ Mathf.Pow(distance.z, 2))) * -F;
    Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

但我不知道如何预测未来的时间点来给我轨道形状。

我试过 "speeding up the simulation" 和 Time.timeScale = 50; 但速度不够快。 我在某处读到我需要太阳系的副本 运行 独立形成统一更新,并从那里计算火箭轨迹,但我不知道如何处理。

在物理模拟方面我有点菜鸟所以你们中的一位天才可以帮忙吗?

这是您的代码实际执行的操作:

var sateliteCords = Satelite.transform.position;
var planetCords = gameObject.transform.position;
var distance = sateliteCords - planetCords;
distanceFromSatelite = distance.magnitude;

F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
forces = distance / distanceFromSatellite * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

您可以通过以下方式进一步减少它:

var distance = sateliteCords - planetCords;
distanceSqrMag = distance.sqrMagnitude;

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

现在代码简单多了,我可以找到一个关键错误。 ForceMode.Force 已经将原力乘以 Time.deltaTime。您在这里想要的是切换到 ForceMode.Impulse,或删除 deltaTime。

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Force);

或者更好的是,假设 Mass 是卫星的质量,而引力不是一般常数,而是地球的局部引力。 ForceMode.Force 将力除以它所施加的刚体的质量。

F = Gravity / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Acceleration);

现在一切都结束了,您可以通过执行类似

的操作来进行非常简单的近似
var currentPos = _rigidBody.position;
var prevPos = currentPos;
var currentVelocity = _rigidBody.velocity;
var planetCords = gameObject.transform.position;

for (int i = 0; i < stepCount; i++)
{
    var distance = planetCords - currentPos;

    var forceMag = Gravity / distance.sqrMagnitude;
    forces = distance.normalized * forceMag;
    currentVelocity  += forces * Time.fixedDeltaTime;

    currentPos += currentVelocity * Time.fixedDeltaTime;

    //Replace by a TrailRenderer you reset each frame
    Debug.DrawLine(prevPos, currentPos, Color.Red, Time.deltaTime);
    prevPos = currentPos;
}

请注意,此代码未经测试,我可能在这里或那里犯了错误,但这就是它的要点。

不用担心轨迹有任何差异,这正是 unity 预测位置的方法。当您拥有所需的所有计算能力时,无需花哨的计算。

如果你想要多个单体重力模拟,很简单。要么应用所有行星的引力,要么仅应用最近行星的引力并考虑其质量。如果你的行星少于十几个,我推荐前者。

您不需要圆锥曲线、高等数学或任何其他东西。你不是 kerbal space 程序。有时蛮力是最好的解决方案。