public static double CalculateDeltaInclination(Vector3d position, Vector3d DeltaV, double time, double timeinterval, Vessel vessel, CelestialBody body) { double Inc = 0; double Altitude = 0; double Mass = VesselData.FetchMass(vessel); if (Mass == 0) { Mass = vessel.GetTotalMass() * 1000; } Vector3d BodyPosition = new Vector3d(); if (vessel.orbitDriver.orbit.referenceBody == body || (vessel.orbit.referenceBody == body && body == Sun.Instance.sun)) { BodyPosition = new Vector3d(0, 0, 0); } else { BodyPosition = body.orbit.getRelativePositionAtUT(time); } Altitude = Vector3d.Distance(position, body.transform.position); Vector3d AngularMomentum = Vector3d.Cross(position, DeltaV); Vector3d NodeVector = Vector3d.Cross(new Vector3d(0, 1, 0), AngularMomentum); double GravitationalParameter = body.gravParameter; Vector3d EccentricityVector = ((((Math.Pow(DeltaV.magnitude, 2.0) - GravitationalParameter) / position.magnitude) * position) - (Vector3d.Dot(position, DeltaV) * DeltaV)) / GravitationalParameter; Inc = Math.Acos(AngularMomentum.y / AngularMomentum.magnitude); // Remember y & z flipped Fine here! return(Inc); }
public static double DiuralSMAChange(Vessel vessel) { double RateOfChangeOfSMA = 0; double InitialSMA = VesselData.FetchSMA(vessel); double Albedo = 0.12; // Work on something better for this! Currently using Worn Asphalt as a guide... double MeanMotion = 360.0 / vessel.orbitDriver.orbit.period; double Area = VesselData.FetchArea(vessel); double Mass = VesselData.FetchMass(vessel); double Radius = Math.Sqrt(Area / Math.PI); double Volume = 4.0 / 3.0 * Math.PI * Math.Pow(Radius, 3.0); double Density = Mass / Volume; double c = Math.Pow(8.0 * 10, 8); double Altitude = vessel.orbitDriver.orbit.referenceBody == Sun.Instance.sun ? vessel.orbitDriver.orbit.altitude : vessel.orbitDriver.orbit.referenceBody.orbit.altitude; double SolarEnergy = Math.Pow(3.86 * 10.0, 26.0); double SolarConstant = SolarEnergy / (4.0 * Math.PI * Math.Pow(Altitude, 2.0)); // W/m^2 double BoltzmannConstant = Math.Pow(6.68 * 10.0, -11.0); double SolarTemperature = vessel.externalTemperature; // try this! double Epsilon = UnityEngine.Random.Range(0.75f, 0.9f); double LocalForce = 0; LocalForce = Epsilon * BoltzmannConstant * Math.Pow(SolarTemperature, 4.0) / Albedo; double Iota = 3.0 * LocalForce / (4.0 * Radius * Density * c); Vector3d RotationAxis = vessel.upAxis; float ObliquityOfSpinAxis = 0; double AmplitudeOfRotation = 0; double RotationPhase = 0; if (LoadingCheck.PersistentRotationInstalled) { // Add Persistent Rotation Compatibility here! //1.6.0 } else { if (vessel.isActiveVessel) { Quaternion VesselRotation = vessel.srfRelRotation; Vector3 TemporaryAxis; VesselRotation.ToAngleAxis(out ObliquityOfSpinAxis, out TemporaryAxis); Vector3 AngularSpeed = TemporaryAxis * ObliquityOfSpinAxis; // Rotation Per Second? AmplitudeOfRotation = AngularSpeed.magnitude; RotationPhase = Vector3.Angle(RotationAxis, TemporaryAxis); } else { Quaternion VesselRotation = new Quaternion();//.Inverse(); // Issues here work out a background rotational calculation? Vector3 TemporaryAxis; VesselRotation.ToAngleAxis(out ObliquityOfSpinAxis, out TemporaryAxis); Vector3 AngularSpeed = TemporaryAxis * ObliquityOfSpinAxis; // Rotation Per Second? AmplitudeOfRotation = AngularSpeed.magnitude; RotationPhase = Vector3.Angle(RotationAxis, TemporaryAxis); } } double RotationFrequency = AmplitudeOfRotation; double DiuralThermalParameter = 0; double Gamma = 0; double SpecificHeatCapacity = 670; // Lets not model this too far yet... maybe for 1.6.0 using c of Regolith for now double ThermalConductivity = Math.Pow(100.0, 2.0) / (Density * SpecificHeatCapacity); double PenetrationDepth = 0; double X = 0; DiuralThermalParameter = Math.Sqrt(ThermalConductivity * Density * SpecificHeatCapacity * RotationFrequency) / (Epsilon * BoltzmannConstant * Math.Pow(SolarTemperature, 3.0) * Altitude); PenetrationDepth = Math.Sqrt(ThermalConductivity / (Density * SpecificHeatCapacity * RotationFrequency)); X = Radius * Math.Sqrt(2) / PenetrationDepth; Gamma = DiuralThermalParameter / X; double BigOFunctionOfEccentricity = Math.Pow(vessel.orbitDriver.orbit.eccentricity, 0.0); RateOfChangeOfSMA = -8.0 * Albedo / (9.0 * MeanMotion) * Iota * (AmplitudeOfRotation * Math.Sin(RotationPhase) / 1.0 + Gamma) * Math.Cos(ObliquityOfSpinAxis) + 0; if (double.IsNaN(RateOfChangeOfSMA)) { RateOfChangeOfSMA = 0; } return(RateOfChangeOfSMA); }
public static List <Vector3d> InfluencingAccelerationsV(Vessel vessel, double time) { List <Vector3d> InfluencingAccelerations = new List <Vector3d>(); // Position at time foreach (CelestialBody Body in InfluencingBodiesV(vessel)) { double VesselMass = VesselData.FetchMass(vessel); #if false if (VesselMass == 0) // Incase vesselData hasnt caught up! { VesselMass = vessel.GetCorrectVesselMass() * 1000; } #endif double PhaseAngle = FindPhaseAngleBetweenObjects(vessel.orbit, Body.orbit); double InfluencingForce = 0; double BodyMass = Body.Mass; Vector3d BodyPosition = new Vector3d(); if (vessel.orbitDriver.orbit.referenceBody == Body || (vessel.orbitDriver.orbit.referenceBody == Body && Body == Sun.Instance.sun)) // Work out sun position later... { BodyPosition = new Vector3d(0, 0, 0); } else { if (Body == Sun.Instance.sun) { BodyPosition = new Vector3d(0, 0, 0); } else { BodyPosition = Body.orbit.getRelativePositionAtUT(time); } } double DistanceToVessel = Vector3d.Distance(Body.bodyTransform.position, vessel.vesselTransform.position); // Maybe but no time aspect //Vector3d.Distance(BodyPosition, vessel.orbitDriver.orbit.getRelativePositionAtUT(time)); // print("Body " + Body.name + " distance to " + vessel.name + " : " + DistanceToVessel); double BodyMNA = 0; try { // BodyMNA = (Body.orbitDriver.orbit.GetMeanAnomaly(Body.orbitDriver.orbit.E, time)); BodyMNA = OrbitalDecayUtilities.GetMeanAnomalyAtTime(Body.orbitDriver.orbit.meanAnomalyAtEpoch, Body.orbitDriver.orbit.epoch, Body.orbitDriver.orbit.period, time); } catch (NullReferenceException) { BodyMNA = 0; } double MNADifference = UtilMath.DegreesToRadians(PhaseAngle); // Fixed the phasing issues 1.6.0 //print("MNA Difference = " + MNADifference); //print("Distance to Vessel: " + vessel.name + " " + DistanceToVessel); InfluencingForce = (GravitationalConstant * BodyMass * VesselMass) / (DistanceToVessel * DistanceToVessel); InfluencingForce = InfluencingForce * Math.Cos(MNADifference); Vector3d InfluencingAccelerationBodyDirectionVector = new Vector3d(); if (vessel.orbitDriver.orbit.referenceBody == Body || (vessel.orbitDriver.orbit.referenceBody == Body && Body == Sun.Instance.sun)) { InfluencingAccelerationBodyDirectionVector = new Vector3d(0, 0, 0); } else { if (Body == Sun.Instance.sun) { InfluencingAccelerationBodyDirectionVector = Body.position; } else { InfluencingAccelerationBodyDirectionVector = Body.orbit.getRelativePositionAtUT(time); } } InfluencingAccelerationBodyDirectionVector = Body.transform.position; // Vector3d VesselRelativePositionVector = vessel.orbitDriver.orbit.getRelativePositionAtUT(time); VesselRelativePositionVector = vessel.transform.position; // Vector3d InfluencingAccelerationVector = (new Vector3d(-InfluencingAccelerationBodyDirectionVector.x + VesselRelativePositionVector.x, -InfluencingAccelerationBodyDirectionVector.y + VesselRelativePositionVector.y, -InfluencingAccelerationBodyDirectionVector.z + VesselRelativePositionVector.z)) * ((InfluencingForce / VesselMass)); // Always positive? InfluencingAccelerationVector = (new Vector3d(InfluencingAccelerationBodyDirectionVector.x - VesselRelativePositionVector.x, InfluencingAccelerationBodyDirectionVector.y - VesselRelativePositionVector.y, InfluencingAccelerationBodyDirectionVector.z - VesselRelativePositionVector.z)) * ((InfluencingForce / VesselMass)); // Better? //print("Accel Vector Magnitude: " + InfluencingAccelerationVector.magnitude); InfluencingAccelerations.Add(InfluencingAccelerationVector); } return(InfluencingAccelerations); }