Пример #1
0
 /// <summary>
 /// Calculates lunar eclipse map
 /// </summary>
 /// <param name="eclipse">Eclipse general details</param>
 /// <param name="elements">Besselian elements for the eclipse</param>
 /// <returns>Eclipse map</returns>
 public static LunarEclipseMap EclipseMap(LunarEclipse eclipse, PolynomialLunarEclipseElements elements)
 {
     return(new LunarEclipseMap()
     {
         PenumbralBegin = !double.IsNaN(eclipse.JulianDayFirstContactPenumbra) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayFirstContactPenumbra)) : null,
         PartialBegin = !double.IsNaN(eclipse.JulianDayFirstContactUmbra) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayFirstContactUmbra)) : null,
         TotalBegin = !double.IsNaN(eclipse.JulianDayTotalBegin) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayTotalBegin)) : null,
         TotalEnd = !double.IsNaN(eclipse.JulianDayTotalEnd) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayTotalEnd)) : null,
         PartialEnd = !double.IsNaN(eclipse.JulianDayLastContactUmbra) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayLastContactUmbra)) : null,
         PenumbralEnd = !double.IsNaN(eclipse.JulianDayLastContactPenumbra) ? FindCurvePoints(elements.GetInstantBesselianElements(eclipse.JulianDayLastContactPenumbra)) : null,
     });
 }
Пример #2
0
 public static LunarEclipseLocalCircumstances LocalCircumstances(LunarEclipse eclipse, PolynomialLunarEclipseElements e, CrdsGeographical g)
 {
     return(new LunarEclipseLocalCircumstances()
     {
         Location = g,
         PenumbralBegin = GetLocalCircumstancesContactPoint(eclipse.JulianDayFirstContactPenumbra, eclipse, e, g),
         PartialBegin = GetLocalCircumstancesContactPoint(eclipse.JulianDayFirstContactUmbra, eclipse, e, g),
         TotalBegin = GetLocalCircumstancesContactPoint(eclipse.JulianDayTotalBegin, eclipse, e, g),
         Maximum = GetLocalCircumstancesContactPoint(eclipse.JulianDayMaximum, eclipse, e, g),
         TotalEnd = GetLocalCircumstancesContactPoint(eclipse.JulianDayTotalEnd, eclipse, e, g),
         PartialEnd = GetLocalCircumstancesContactPoint(eclipse.JulianDayLastContactUmbra, eclipse, e, g),
         PenumbralEnd = GetLocalCircumstancesContactPoint(eclipse.JulianDayLastContactPenumbra, eclipse, e, g),
     });
 }
Пример #3
0
        /// <summary>
        /// Calculates nearest lunar eclipse (next or previous) for the provided lunation number.
        /// </summary>
        /// <param name="lunationNumber">Meeus lunation number of interest.</param>
        /// <param name="next">Flag indicating searching direction. True means searching next eclipse, false means previous.</param>
        public static LunarEclipse NearestEclipse(int lunationNumber, bool next)
        {
            double k = lunationNumber + 0.5;

            bool eclipseFound;

            double T  = k / 1236.85;
            double T2 = T * T;
            double T3 = T2 * T;
            double T4 = T3 * T;

            LunarEclipse eclipse = new LunarEclipse();

            do
            {
                // Moon's argument of latitude (mean dinstance of the Moon from its ascending node)
                double F = 160.7108 + 390.67050284 * k
                           - 0.0016118 * T2
                           - 0.00000227 * T3
                           + 0.000000011 * T4;

                F            = To360(F);
                eclipseFound = Abs(Sin(ToRadians(F))) <= 0.36;

                if (eclipseFound)
                {
                    double jdMeanPhase = 2451550.09766 + 29.530588861 * k
                                         + 0.00015437 * T2
                                         - 0.000000150 * T3
                                         + 0.00000000073 * T4;

                    // Sun's mean anomaly
                    double M = 2.5534 + 29.10535670 * k
                               - 0.0000014 * T2
                               - 0.00000011 * T3;
                    M = To360(M);
                    M = ToRadians(M);

                    // Moon's mean anomaly
                    double M_ = 201.5643 + 385.81693528 * k
                                + 0.0107582 * T2
                                + 0.00001238 * T3
                                - 0.000000058 * T4;
                    M_ = To360(M_);
                    M_ = ToRadians(M_);

                    // Mean longitude of ascending node
                    double Omega = 124.7746 - 1.56375588 * k
                                   + 0.0020672 * T2
                                   + 0.00000215 * T3;

                    Omega = To360(Omega);
                    Omega = ToRadians(Omega);

                    // Multiplier related to the eccentricity of the Earth orbit
                    double E = 1 - 0.002516 * T - 0.0000074 * T2;

                    double F1 = ToRadians(F - 0.02665 * Sin(Omega));
                    double A1 = ToRadians(To360(299.77 + 0.107408 * k - 0.009173 * T2));

                    double jdMax =
                        jdMeanPhase
                        - 0.4065 * Sin(M_)
                        + 0.1727 * E * Sin(M)
                        + 0.0161 * Sin(2 * M_)
                        - 0.0097 * Sin(2 * F1)
                        + 0.0073 * E * Sin(M_ - M)
                        - 0.0050 * E * Sin(M_ + M)
                        - 0.0023 * Sin(M_ - 2 * F1)
                        + 0.0021 * E * Sin(2 * M)
                        + 0.0012 * Sin(M_ + 2 * F1)
                        + 0.0006 * E * Sin(2 * M_ + M)
                        - 0.0004 * Sin(3 * M_)
                        - 0.0003 * E * Sin(M + 2 * F1)
                        + 0.0003 * Sin(A1)
                        - 0.0002 * E * Sin(M - 2 * F1)
                        - 0.0002 * E * Sin(2 * M_ - M)
                        - 0.0002 * Sin(Omega);

                    double P =
                        0.2070 * E * Sin(M)
                        + 0.0024 * E * Sin(2 * M)
                        - 0.0392 * Sin(M_)
                        + 0.0116 * Sin(2 * M_)
                        - 0.0073 * E * Sin(M_ + M)
                        + 0.0067 * E * Sin(M_ - M)
                        + 0.0118 * Sin(2 * F1);

                    double Q =
                        5.2207 - 0.0048 * E * Cos(M)
                        + 0.0020 * E * Cos(2 * M)
                        - 0.3299 * Cos(M_)
                        - 0.0060 * E * Cos(M_ + M)
                        + 0.0041 * E * Cos(M_ - M);

                    double W = Abs(Cos(F1));

                    double gamma = (P * Cos(F1) + Q * Sin(F1)) * (1 - 0.0048 * W);

                    double u = 0.0059
                               + 0.0046 * E * Cos(M)
                               - 0.0182 * Cos(M_)
                               + 0.0004 * Cos(2 * M_)
                               - 0.0005 * E * Cos(M + M_);

                    double rho   = 1.2848 + u;
                    double sigma = 0.7403 - u;

                    double mag = (1.0128 - u - Abs(gamma)) / 0.5450;

                    if (mag >= 1)
                    {
                        eclipse.EclipseType = LunarEclipseType.Total;
                    }
                    if (mag > 0 && mag < 1)
                    {
                        eclipse.EclipseType = LunarEclipseType.Partial;
                    }

                    // Check if elipse is penumbral only
                    if (mag < 0)
                    {
                        eclipse.EclipseType = LunarEclipseType.Penumbral;
                        mag = (1.5573 + u - Abs(gamma)) / 0.5450;
                    }

                    // No eclipse, if both phases is less than 0.
                    // Examine other lunation
                    if (mag < 0)
                    {
                        eclipseFound = false;
                    }
                    // Eclipse found
                    else
                    {
                        eclipse.JulianDayMaximum = jdMax;
                        eclipse.Magnitude        = mag;
                        eclipse.Rho   = rho;
                        eclipse.Gamma = gamma;
                        eclipse.Sigma = sigma;

                        double p = 1.0128 - u;
                        double t = 0.4678 - u;
                        double n = 1.0 / (24 * (0.5458 + 0.04 * Cos(M_)));
                        double h = 1.5573 + u;

                        double sdPartial  = n * Sqrt(p * p - gamma * gamma);
                        double sdTotal    = n * Sqrt(t * t - gamma * gamma);
                        double sdPenumbra = n * Sqrt(h * h - gamma * gamma);

                        eclipse.JulianDayFirstContactPenumbra = jdMax - sdPenumbra;
                        eclipse.JulianDayFirstContactUmbra    = jdMax - sdPartial;
                        eclipse.JulianDayTotalBegin           = jdMax - sdTotal;
                        eclipse.JulianDayTotalEnd             = jdMax + sdTotal;
                        eclipse.JulianDayLastContactUmbra     = jdMax + sdPartial;
                        eclipse.JulianDayLastContactPenumbra  = jdMax + sdPenumbra;
                        eclipse.Saros = Saros(jdMax);
                        eclipse.MeeusLunationNumber = (int)Round(k - 0.5);
                    }
                }

                if (!eclipseFound)
                {
                    if (next)
                    {
                        k++;
                    }
                    else
                    {
                        k--;
                    }
                }
            }while (!eclipseFound);

            return(eclipse);
        }
Пример #4
0
 private static LunarEclipseLocalCircumstancesContactPoint GetLocalCircumstancesContactPoint(double jd, LunarEclipse eclipse, PolynomialLunarEclipseElements e, CrdsGeographical g)
 {
     if (!double.IsNaN(jd))
     {
         return(new LunarEclipseLocalCircumstancesContactPoint(e.GetInstantBesselianElements(jd), g));
     }
     else
     {
         return(null);
     }
 }