2021-12-26 01:48:02 -05:00

87 lines
3.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using NewHorizons.Utility;
using Logger = NewHorizons.Utility.Logger;
using NewHorizons.External;
namespace NewHorizons.OrbitalPhysics
{
public static class OrbitalHelper
{
public enum FalloffType
{
inverseSquared,
linear,
none
}
public static Vector3 RotateTo(Vector3 vector, KeplerElements elements)
{
// For now, eccentric orbits gotta start at apoapsis and cant be inclined
var rot = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode + elements.TrueAnomaly + elements.ArgumentOfPeriapsis + 180f, Vector3.up);
if (elements.Eccentricity != 0)
{
rot = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode + elements.ArgumentOfPeriapsis + 180f, Vector3.up);
}
var incAxis = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode, Vector3.up) * Vector3.left;
var incRot = Quaternion.AngleAxis(elements.Inclination, incAxis);
return rot * incRot * vector;
}
public static Vector3 RotateTo(Vector3 vector, OrbitModule module)
{
return RotateTo(vector, KeplerElements.FromOrbitModule(module));
}
public static Vector3 VelocityDirection(Vector3 separation, KeplerElements elements)
{
var incAxis = Quaternion.AngleAxis(elements.LongitudeOfAscendingNode, Vector3.up) * Vector3.left;
var incRot = Quaternion.AngleAxis(elements.Inclination, incAxis);
return Vector3.Cross(RotateTo(Vector3.up, elements), separation);
}
public static float GetOrbitalVelocity(float distance, Gravity gravity, KeplerElements kepler)
{
if (kepler.Eccentricity == 0) return GetCircularOrbitVelocity(distance, gravity, kepler);
if (gravity.Exponent == 2)
{
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass * (2f / distance - 1f / kepler.SemiMajorAxis));
}
if(gravity.Exponent == 1)
{
var mu = GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass;
var rp2 = kepler.Periapsis * kepler.Periapsis;
var ra2 = kepler.Apoapsis * kepler.Apoapsis;
float term1 = 0;
if(kepler.Eccentricity < 1)
term1 = mu * Mathf.Log(kepler.Periapsis / kepler.Apoapsis) * rp2 / (rp2 - ra2);
var term2 = mu * Mathf.Log(kepler.Apoapsis / distance);
return Mathf.Sqrt(2 * (term1 + term2));
}
Logger.LogError($"Invalid exponent {gravity.Exponent}");
return 0f;
}
public static float GetCircularOrbitVelocity(float distance, Gravity gravity, KeplerElements kepler)
{
if (gravity.Exponent == 2)
{
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass / distance);
}
if(gravity.Exponent == 1)
{
return Mathf.Sqrt(GravityVolume.GRAVITATIONAL_CONSTANT * gravity.Mass);
}
Logger.LogError($"Invalid exponent {gravity.Exponent}");
return 0f;
}
}
}