如何在Unity C#中将2D状态向量+引力参数转换为远点、近点、近点自变量和时间

问题描述 投票:0回答:1

我之前问过类似的问题,但一直无法找到答案,所以我将提供更多细节,并希望有人知道我在说什么。

我有一系列函数,它们使用开普勒定律来计算物体在绕某种天体运行时在 2D 空间中“t”时间的位置。这是二体问题的粗略解决方案,我打算在基于物理的 2D 空间游戏中使用它。到目前为止,这是我的代码:

float KeplersEquation(float meanAnomaly, float eccentricAnomaly, float eccentricity)
{
    return eccentricAnomaly - (eccentricity * Mathf.Sin(eccentricAnomaly)) - meanAnomaly;
}

float KeplersEquation_Differentiated(float eccentricAnomaly, float eccentricity)
{
    return 1 - (eccentricity * Mathf.Cos(eccentricAnomaly));
}

float SolveKepler(float meanAnomaly, float eccentricity)
{
    float accuracy = 0.000001f;
    int maxIterations = 100;

    float eccentricAnomaly = eccentricity > 0.8f ? Mathf.PI : meanAnomaly;

    for (int i = 0; i < maxIterations; i++)
    {
        float nextValue = eccentricAnomaly - (KeplersEquation(meanAnomaly, eccentricAnomaly, eccentricity)) / KeplersEquation_Differentiated(eccentricAnomaly, eccentricity);
        float difference = Mathf.Abs(eccentricAnomaly - nextValue);
        eccentricAnomaly = nextValue;

        if (difference < accuracy) break;
    }

    return eccentricAnomaly;
}

/// <summary> Calculates a position on the orbit for a given value of t ranging between 0 and 1 </summary>
public Vector2 CalculatePointOnOrbit(float apoapsis, float periapsis, float argumentOfPeriapsis, float t)
{
    float semiMajorAxis = (apoapsis + periapsis) / 2f;
    float semiMinorAxis = Mathf.Sqrt(apoapsis * periapsis);

    float meanAnomaly = t * Mathf.PI * 2f; // Mean anomaly ranges anywhere from 0 - 2π
    float linearEccentricity = semiMajorAxis - periapsis;
    float eccentricity = linearEccentricity / semiMajorAxis; // Eccentricity ranges from 0 - 1 with values tending to 1 being increasingly elliptical

    float eccentricAnomaly = SolveKepler(meanAnomaly, eccentricity);

    float x = semiMajorAxis * (Mathf.Cos(eccentricAnomaly) - eccentricity);
    float y = semiMinorAxis * Mathf.Sin(eccentricAnomaly);

    Quaternion parametricAngle = Quaternion.AngleAxis(argumentOfPeriapsis, Vector2.up);
    return parametricAngle * new Vector2(x, y);
}

由于这是一个基于物理的游戏,我喜欢能够获取轨道物体的当前位置和速度,以及吸引物体的重力参数,并将它们转换为开普勒元素或我的游戏中使用的简化版本函数(远心点、近心点、近心点和时间的参数),这将允许我在物体与物体碰撞或施加外力时动态改变物体的轨道。我已经阅读了如何在 3D 空间中执行此操作,但我正在努力理解它的概念,因此无法弄清楚如何在 2D 空间中执行此操作。如果有人可以解释如何在 2D 中进行此操作以及您可能有的任何其他技巧,我们将非常感激。

c# unity-game-engine 2d orbital-mechanics
1个回答
0
投票

2D 计算与 3D 计算相同,只是 z 点中有 0。有关这方面的讨论和算法,您可以在这里查看:

https://space.stackexchange.com/questions/19322/converting-orbital-elements-to-cartesian-state-vectors

这将您指向这里:

https://ccar.colorado.edu/asen5070/handouts/cart2kep2002.pdf

© www.soinside.com 2019 - 2024. All rights reserved.