Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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));
            }
        }