/// <summary> /// Creates a hyperbolic orbit around the given celestial body. /// </summary> /// <returns>The newly created orbit, with state vectors anchored to its periapsis.</returns> /// <param name="body">The celestial body at the focus of the orbit.</param> /// <param name="periapsis">The periapsis (from the body center), in meters. Must not be /// negative.</param> /// <param name="vInf">The excess speed associated with the orbit, in meters per second. /// Must be positive.</param> /// <param name="utPeri">The absolute time of periapsis passage.</param> /// /// <exception cref="ArgumentException">Thrown if either <c>periapsis</c> or <c>vInf</c> /// are out of bounds.</exception> static Orbit createHyperbolicOrbit (CelestialBody body, double periapsis, double vInf, double utPeri) { if (vInf <= 0.0) { throw new ArgumentException ( Localizer.Format ("#autoLOC_CustomAsteroids_ErrorHyperBadVInf", vInf), nameof (vInf)); } if (periapsis < 0.0) { throw new ArgumentException ( Localizer.Format ("#autoLOC_CustomAsteroids_ErrorHyperBadPeri", periapsis), nameof (periapsis)); } double a = -body.gravParameter / (vInf * vInf); double e = 1.0 - periapsis / a; // Random orientation, to be consistent with CreateRandomOrbitFlyBy double i = RandomDist.drawIsotropic (); double lAn = RandomDist.drawAngle (); double aPe = RandomDist.drawAngle (); Debug.Log ($"[CustomAsteroids]: " + Localizer.Format ("#autoLOC_CustomAsteroids_LogHyperOrbit", body.bodyName, a, e, i, aPe, lAn)); return new Orbit (i, e, a, lAn, aPe, 0.0, utPeri, body); }
/// <summary> /// Generates a random number consistent with the distribution. The program state shall be /// unchanged in the event of an exception. /// </summary> /// <returns>The desired random variate. The distribution depends on this object's internal /// data.</returns> /// /// <exception cref="ArgumentException">Thrown if the parameters are inappropriate /// for the distribution.</exception> /// <exception cref="InvalidOperationException">Thrown if the distribution is /// invalid.</exception> internal double draw() { switch (dist) { case Distribution.Uniform: return(RandomDist.drawUniform(min, max)); case Distribution.LogUniform: return(RandomDist.drawLogUniform(min, max)); case Distribution.Gaussian: case Distribution.Normal: return(RandomDist.drawNormal(avg, stdDev)); case Distribution.LogNormal: if (avg <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorLogNormMean", avg)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorLogNormStd", stdDev)); } double quad = Math.Sqrt(avg * avg + stdDev * stdDev); double mu = Math.Log(avg * avg / quad); double sigma = Math.Sqrt(2 * Math.Log(quad / avg)); return(RandomDist.drawLognormal(mu, sigma)); case Distribution.Rayleigh: return(RandomDist.drawRayleigh(avg * Math.Sqrt(2.0 / Math.PI))); case Distribution.Exponential: return(RandomDist.drawExponential(avg)); case Distribution.Gamma: if (avg <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorGammaMean", avg)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorGammaStd", stdDev)); } double k = (avg / stdDev); k = k * k; double theta = stdDev * stdDev / avg; return(RandomDist.drawGamma(k, theta)); case Distribution.Beta: if (avg <= min || avg >= max) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBetaMean", min, avg, max)); } if (stdDev <= 0.0) { throw new ArgumentException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBetaStd", stdDev)); } double scaledMean = (avg - min) / (max - min); double scaledStdDev = stdDev / (max - min); double scaledVar = scaledStdDev * scaledStdDev; double factor = (scaledMean - scaledMean * scaledMean - scaledVar) / scaledVar; double alpha = scaledMean * factor; double beta = (1.0 - scaledMean) * factor; return(min + (max - min) * RandomDist.drawBeta(alpha, beta)); case Distribution.Isotropic: return(RandomDist.drawIsotropic()); default: throw new InvalidOperationException( Localizer.Format("#autoLOC_CustomAsteroids_ErrorBadDistribution", dist)); } }