Пример #1
0
        private static MoonPosition GetMoonPosition(DateTime date, double lat, double lng, Celestial cel)
        {
            //Set UTC date integrity
            date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);

            double d = JulianConversions.GetJulian_Epoch2000(date);

            //Ch 47
            double JDE = JulianConversions.GetJulian(date); //Get julian

            double T = (JDE - 2451545) / 36525;             //Get dynamic time.

            double[]  LDMNF = Get_Moon_LDMNF(T);
            CelCoords c     = GetMoonCoords(d, cel, LDMNF, T);
            Distance  dist  = GetMoonDistance(date);
            double    lw    = rad * -lng;
            double    phi   = rad * lat;

            double H = rad * Get_Sidereal_Time(JDE, lw) - lw - c.ra;

            double ra  = c.ra;  //Adjust current RA formula to avoid needless RAD conversions
            double dec = c.dec; //Adjust current RA formula to avoid needless RAD conversions

            //Adjust for parallax (low accuracry increases may not be worth cost)
            //Investigate
            double pSinE = Get_pSinE(dec, dist.Meters) * Math.PI / 180;
            double pCosE = Get_pCosE(dec, dist.Meters) * Math.PI / 180;
            double cRA   = Parallax_RA(dist.Meters, H, pCosE, dec, ra);
            double tDEC  = Parallax_Dec(dist.Meters, H, pCosE, pSinE, dec, cRA);
            double tRA   = ra - cRA;

            dec = tDEC;
            ra  = tRA;

            //Get true altitude
            double h = altitude(H, phi, dec);

            // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
            double pa = Math.Atan2(Math.Sin(H), Math.Tan(phi) * Math.Cos(dec) - Math.Sin(dec) * Math.Cos(H));

            //altitude correction for refraction
            h = h + astroRefraction(h);

            MoonPosition mp = new MoonPosition();

            mp.Azimuth          = azimuth(H, phi, dec);
            mp.Altitude         = h / Math.PI * 180;
            mp.Distance         = dist;
            mp.ParallacticAngle = pa;

            double horParal = 8.794 / (dist.Meters / 149.59787E6);                // horizontal parallax (arcseconds), Meeus S. 263
            double p        = Math.Asin(Math.Cos(h) * Math.Sin(horParal / 3600)); // parallax in altitude (degrees)

            p *= 1000;

            mp.ParallaxCorection = p;
            mp.Altitude         *= rad;

            return(mp);
        }
Пример #2
0
        public static LunarCoordinates GetMoonCoords(DateTime date, double offset)
        {
            double julianOffset = offset * .04166667;

            //Ch 47
            double oJDE = JulianConversions.GetJulian(date) + julianOffset; //Get julian
            double T    = (oJDE - 2451545) / 36525;                         //Get dynamic time.

            double[] LDMNF = Get_Moon_LDMNF(T);

            return(GetMoonCoords(LDMNF, T, oJDE));
        }
Пример #3
0
        public static SolarCoordinates Get_Solar_Coordinates(DateTime d, double offset)
        {
            double julianOffset = offset * .04166667;
            double JD           = JulianConversions.GetJulian(d) + julianOffset;
            double T            = (JD - 2451545.0) / 36525;                                   //25.1 Time
            double L0           = 280.46646 + 36000.76983 * T + .0003032 * Math.Pow(T, 2);    //25.2 Geometric Mean Longitude
            double M            = 357.52911 + 35999.05029 * T - .0001537 * Math.Pow(T, 2);    //25.3 Mean Anomaly
            double e            = .016708634 - .000042037 * T - .0000001267 * Math.Pow(T, 2); //25.4 Eccentricity
            double C            = +(1.914602 - .004817 * T - .000014 * Math.Pow(T, 2)) * Math.Sin(M.ToRadians()) +
                                  (.019993 - .000101 * T) * Math.Sin(2 * M.ToRadians()) +
                                  .000289 * Math.Sin(3 * M.ToRadians());                                   //25.4 Equation of the center

            double trueLongitude = L0 + C;                                                                 //25.4
            double trueAnomaly   = M + C;                                                                  //25.4 "v"

            double R = (1.000001018 * (1 - Math.Pow(e, 2))) / (1 + e * Math.Cos(trueAnomaly.ToRadians())); //25.5 Radius Vector

            double ascendingNode     = 125.04 - 1934.136 * T;
            double apparentLongitude = trueLongitude - .00569 - .00478 * Math.Sin(ascendingNode.ToRadians());

            double E = Format.ToDegrees(23, 26, 21.488) - (46.8150 / 3600) * T - (.00059 / 3600) * Math.Pow(T, 2) + (.001813 / 3600) * Math.Pow(T, 3); //22.2 Obliquity of the ecliptic

            double tra = Math.Atan2(Math.Cos(E.ToRadians()) * Math.Sin(trueLongitude.ToRadians()), Math.Cos(trueLongitude.ToRadians()));               //25.6 True Right Ascensions. Using Atan2 we can move tan to the right side of the function with Numerator, Denominator

            double tdec = Math.Asin(Math.Sin(E.ToRadians()) * Math.Sin(trueLongitude.ToRadians()));                                                    //25.7 True declination. Asin used in liu of sin.

            double CE = E + .00256 * Math.Cos(ascendingNode.ToRadians());                                                                              //22.2 Obliquity of the ecliptic

            double ara  = Math.Atan2(Math.Cos(CE.ToRadians()) * Math.Sin(apparentLongitude.ToRadians()), Math.Cos(apparentLongitude.ToRadians()));     //25.8 Apparent Right Ascensions. Using Atan2 we can move tan to the right side of the function with Numerator, Denominator
            double adec = Math.Asin(Math.Sin(CE.ToRadians()) * Math.Sin(apparentLongitude.ToRadians()));                                               //25.8 Apparent declination. Asin used in liu of sin.

            SolarCoordinates celC = new SolarCoordinates();

            //Set to degrees
            //celC.trueRightAscension = tra.ToDegrees();
            //celC.trueDeclination = tdec.ToDegrees();
            celC.rightAscension         = ara.ToDegrees().NormalizeDegrees360();
            celC.declination            = adec.ToDegrees();
            celC.julianDayDecimal       = JD - .5 - Math.Floor(JD - .5);
            celC.trueLongitude          = trueLongitude.NormalizeDegrees360();
            celC.longitude              = apparentLongitude.NormalizeDegrees360();
            celC.radiusVector           = R;
            celC.geometricMeanLongitude = L0.NormalizeDegrees360();
            //Latitude is always 0 for sun as perturbations no accounted for in low accuracy formulas
            celC.latitude     = 0;
            celC.trueLatitude = 0;

            return(celC);
        }
Пример #4
0
        private static Distance GetMoonDistance(DateTime d, double[] values)
        {
            //Ch 47
            double JDE = JulianConversions.GetJulian(d); //Get julian
            double T   = (JDE - 2451545) / 36525;        //Get dynamic time.

            double D = values[1];
            double M = values[2];
            double N = values[3];
            double F = values[4];

            double dist = 385000.56 + (MeeusTables.Moon_Periodic_Er(D, M, N, F, T) / 1000);

            return(new Distance(dist));
        }
Пример #5
0
        private static DateTime Get_Soltice_Equinox_From_JDE0(double JDE0, double offset)
        {
            //Get Event Ch 27.
            double   T   = (JDE0 - 2451545.0) / 36525;
            double   W   = (35999.373 * Math.PI / 180) * T - (2.47 * Math.PI / 180);
            double   ang = 1 + .0334 * Math.Cos(W) + .0007 * Math.Cos(2 * W);
            double   sum = MeeusTables.Equinox_Solstice_Sum_of_S(T);
            double   JDE = JDE0 + ((.00001) * sum / ang);
            DateTime?d   = JulianConversions.GetDate_FromJulian(JDE);

            if (d.HasValue)
            {
                return(JulianConversions.GetDate_FromJulian(JDE).Value.AddHours(offset));
            }
            return(new DateTime()); //Julian limit exceeded, return empty DateTime
        }
Пример #6
0
        /// <summary>
        /// Gets moon distance (Ch 47).
        /// </summary>
        /// <param name="d">DateTime</param>
        /// <param name="offset">UTC offset in hours</param>
        /// <returns>Distance</returns>
        public static Distance GetMoonDistance(DateTime d, double offset)
        {
            //Ch 47
            offset *= -1;
            double julianOffset = offset * .04166667;
            double JDE          = JulianConversions.GetJulian(d) + julianOffset; //Get julian
            double T            = (JDE - 2451545) / 36525;                       //Get dynamic time.

            double[] values = Get_Moon_LDMNF(T);

            double D = values[1];
            double M = values[2];
            double N = values[3];
            double F = values[4];

            //Ch 47 distance formula
            double dist = 385000.56 + (MeeusTables.Moon_Periodic_Er(D, M, N, F, T) / 1000);

            return(new Distance(dist));
        }
        /// <summary>
        /// Gets times for additional solar times
        /// </summary>
        private static void getTimes(DateTime date, double lng, double lat, Celestial c)
        {
            //Get Julian
            double d = JulianConversions.GetJulian(date) - j2000 + .5; //LESS PRECISE JULIAN NEEDED

            double lw  = rad * -lng;
            double phi = rad * lat;

            double n  = julianCycle(d, lw);
            double ds = approxTransit(0, lw, n);

            double M = solarMeanAnomaly(ds);

            double L = eclipticLongitude(M);

            double dec = declination(L, 0);

            double Jnoon = solarTransitJ(ds, M, L);

            double Jset;
            double Jrise;

            DateTime?solarNoon = JulianConversions.GetDate_FromJulian(Jnoon);
            DateTime?nadir     = JulianConversions.GetDate_FromJulian(Jnoon - 0.5);

            c.AdditionalSolarTimes = new AdditionalSolarTimes();

            //Dusk and Dawn
            Jset  = GetTime(-6 * rad, lw, phi, dec, n, M, L);
            Jrise = Jnoon - (Jset - Jnoon);

            c.AdditionalSolarTimes.CivilDawn = DayMatch(JulianConversions.GetDate_FromJulian(Jrise), date);
            c.AdditionalSolarTimes.CivilDusk = DayMatch(JulianConversions.GetDate_FromJulian(Jset), date);

            Jset  = GetTime(-12 * rad, lw, phi, dec, n, M, L);
            Jrise = Jnoon - (Jset - Jnoon);

            c.AdditionalSolarTimes.NauticalDawn = DayMatch(JulianConversions.GetDate_FromJulian(Jrise), date);
            c.AdditionalSolarTimes.NauticalDusk = DayMatch(JulianConversions.GetDate_FromJulian(Jset), date);
        }
Пример #8
0
        /// <summary>
        /// Gets time of event based on specified degree below horizon
        /// </summary>
        /// <param name="lw">Observer Longitude in radians</param>
        /// <param name="phi">Observer Latitude in radians</param>
        /// <param name="h">Angle in Degrees</param>
        /// <param name="date">Date of Event</param>
        /// <returns>DateTime?[]{rise, set}</returns>
        private static DateTime?[] Get_Event_Time(double lw, double phi, double h, DateTime date)
        {
            //Create arrays. Index 0 = Day -1, 1 = Day, 2 = Day + 1;
            //These will be used to find exact day event occurs for comparison
            DateTime?[] sets  = new DateTime?[] { null, null, null, null, null };
            DateTime?[] rises = new DateTime?[] { null, null, null, null, null };

            //Iterate starting with day -1;
            for (int x = 0; x < 5; x++)
            {
                double d = JulianConversions.GetJulian(date.AddDays(x - 2)) - j2000 + .5; //LESS PRECISE JULIAN NEEDED

                double n  = julianCycle(d, lw);
                double ds = approxTransit(0, lw, n);

                double M = solarMeanAnomaly(ds);
                double L = eclipticLongitude(M);

                double dec = declination(L, 0);

                double Jnoon = solarTransitJ(ds, M, L);

                double Jset;
                double Jrise;


                DateTime?solarNoon = JulianConversions.GetDate_FromJulian(Jnoon);
                DateTime?nadir     = JulianConversions.GetDate_FromJulian(Jnoon - 0.5);

                //Rise Set
                Jset  = GetTime(h * rad, lw, phi, dec, n, M, L);
                Jrise = Jnoon - (Jset - Jnoon);

                DateTime?rise = JulianConversions.GetDate_FromJulian(Jrise);
                DateTime?set  = JulianConversions.GetDate_FromJulian(Jset);

                rises[x] = rise;
                sets[x]  = set;
            }

            //Compare and send
            DateTime?tRise = null;

            for (int x = 0; x < 5; x++)
            {
                if (rises[x].HasValue)
                {
                    if (rises[x].Value.Day == date.Day)
                    {
                        tRise = rises[x];
                        break;
                    }
                }
            }
            DateTime?tSet = null;

            for (int x = 0; x < 5; x++)
            {
                if (sets[x].HasValue)
                {
                    if (sets[x].Value.Day == date.Day)
                    {
                        tSet = sets[x];
                        break;
                    }
                }
            }
            return(new DateTime?[] { tRise, tSet });
        }
Пример #9
0
        /// <summary>
        /// Gets time of event based on specified degree below specified altitude
        /// </summary>
        /// <param name="lw">Observer Longitude in radians</param>
        /// <param name="phi">Observer Latitude in radians</param>
        /// <param name="h">Angle in Degrees</param>
        /// <param name="date">Date of Event</param>
        /// <param name="offset">Offset hours</param>
        /// <param name="calculateNoon">Should solar noon iterate and return value</param>
        /// <returns>DateTime?[]{rise, set}</returns>
        internal static DateTime?[] Get_Event_Time(double lw, double phi, double h, DateTime date, double offset, bool calculateNoon)
        {
            double julianOffset = offset * .04166667;

            //Create arrays. Index 0 = Day -1, 1 = Day, 2 = Day + 1;
            //These will be used to find exact day event occurs for comparison
            DateTime?[] sets       = new DateTime?[] { null, null, null, null, null };
            DateTime?[] rises      = new DateTime?[] { null, null, null, null, null };
            DateTime?[] solarNoons = new DateTime?[] { null, null, null, null, null };

            //Iterate starting with day -1;
            for (int x = 0; x < 5; x++)
            {
                double d = JulianConversions.GetJulian(date.AddDays(x - 2)) - j2000 + .5; //LESS PRECISE JULIAN NEEDED
                double n = julianCycle(d, lw);

                //var celC = Get_Solar_Coordinates(date); //Change and Test locs!

                double ds = approxTransit(0, lw, n);

                //M = celC.MeanAnomaly.ToRadians();

                double M = solarMeanAnomaly(ds);



                double L = eclipticLongitude(M);

                double dec = declination(L, 0);

                double Jnoon = solarTransitJ(ds, M, L);


                //Rise Set
                double Jset  = GetTime(h * rad, lw, phi, dec, n, M, L);
                double Jrise = Jnoon - (Jset - Jnoon);

                DateTime?rise = JulianConversions.GetDate_FromJulian(Jrise + julianOffset); //Adjusting julian for DT OFFSET MAY HELP WITH LOCAL TIME
                DateTime?set  = JulianConversions.GetDate_FromJulian(Jset + julianOffset);  //Adjusting julian for DT OFFSET MAY HELP WITH LOCAL TIME

                rises[x] = rise;
                sets[x]  = set;

                if (calculateNoon)
                {
                    solarNoons[x] = JulianConversions.GetDate_FromJulian(Jnoon + julianOffset);
                }
            }

            //Compare and send
            DateTime?tRise = Get_Event_Target_Date(rises, date);
            DateTime?tSet  = Get_Event_Target_Date(sets, date);

            DateTime?tNoon = null;

            if (calculateNoon)
            {
                tNoon = Get_Event_Target_Date(solarNoons, date);
            }

            return(new DateTime?[] { tRise, tSet, tNoon });
        }
Пример #10
0
        //v1.1.3 Formulas
        //The following formulas are either additions
        //or conversions of SunCalcs formulas into Meeus

        /// <summary>
        /// Grabs Perigee or Apogee of Moon based on specified time.
        /// Results will return event just before, or just after specified DateTime
        /// </summary>
        /// <param name="d">DateTime</param>
        /// <param name="md">Event Type</param>
        /// <returns>PerigeeApogee</returns>
        private static PerigeeApogee MoonPerigeeOrApogee(DateTime d, MoonDistanceType md)
        {
            //Perigee & Apogee Algorithms from Jean Meeus Astronomical Algorithms Ch. 50

            //50.1
            //JDE = 2451534.6698 + 27.55454989 * k
            //                     -0.0006691 * Math.Pow(T,2)
            //                     -0.000.01098 * Math.Pow(T,3)
            //                     -0.0000000052 * Math.Pow(T,4)

            //50.2
            //K approx = (yv - 1999.97)*13.2555
            //yv is the year + percentage of days that have occured in the year. 1998 Oct 1 is approx 1998.75
            //k ending in .0 represent perigee and .5 apogee. Anything > .5 is an error.

            //50.3
            //T = k/1325.55

            double yt = 365; //days in year

            if (DateTime.IsLeapYear(d.Year))
            {
                yt = 366;
            }                                     //days in year if leap year
            double f  = d.DayOfYear / yt;         //Get percentage of year that as passed
            double yv = d.Year + f;               //add percentage of year passed to year.
            double k  = (yv - 1999.97) * 13.2555; //find approximate k using formula 50.2

            //Set k decimal based on apogee or perigee
            if (md == MoonDistanceType.Apogee)
            {
                k = Math.Floor(k) + .5;
            }
            else
            {
                k = Math.Floor(k);
            }

            //Find T using formula 50.3
            double T = k / 1325.55;
            //Find JDE using formula 50.1
            double JDE = 2451534.6698 + 27.55454989 * k -
                         0.0006691 * Math.Pow(T, 2) -
                         0.00001098 * Math.Pow(T, 3) -
                         0.0000000052 * Math.Pow(T, 4);

            //Find Moon's mean elongation at time JDE.
            double D = 171.9179 + 335.9106046 * k -
                       0.0100383 * Math.Pow(T, 2) -
                       0.00001156 * Math.Pow(T, 3) +
                       0.000000055 * Math.Pow(T, 4);

            //Find Sun's mean anomaly at time JDE
            double M = 347.3477 + 27.1577721 * k -
                       0.0008130 * Math.Pow(T, 2) -
                       0.0000010 * Math.Pow(T, 3);


            //Find Moon's argument of latitude at Time JDE
            double F = 316.6109 + 364.5287911 * k -
                       0.0125053 * Math.Pow(T, 2) -
                       0.0000148 * Math.Pow(T, 3);

            //Normalize DMF to a 0-360 degree number
            D %= 360;
            if (D < 0)
            {
                D += 360;
            }
            M %= 360;
            if (M < 0)
            {
                M += 360;
            }
            F %= 360;
            if (F < 0)
            {
                F += 360;
            }

            //Convert DMF to radians
            D = D * Math.PI / 180;
            M = M * Math.PI / 180;
            F = F * Math.PI / 180;
            double termsA;

            //Find Terms A from Table 50.A
            if (md == MoonDistanceType.Apogee)
            {
                termsA = MeeusTables.ApogeeTermsA(D, M, F, T);
            }
            else
            {
                termsA = MeeusTables.PerigeeTermsA(D, M, F, T);
            }
            JDE += termsA;
            double termsB;

            if (md == MoonDistanceType.Apogee)
            {
                termsB = MeeusTables.ApogeeTermsB(D, M, F, T);
            }
            else
            {
                termsB = MeeusTables.PerigeeTermsB(D, M, F, T);
            }
            //Convert julian back to date
            DateTime date = JulianConversions.GetDate_FromJulian(JDE).Value;
            //Obtain distance
            Distance dist = GetMoonDistance(date);

            PerigeeApogee ap = new PerigeeApogee(date, termsB, dist);

            return(ap);
        }
Пример #11
0
        public static void GetMoonIllumination(DateTime date, Celestial c, double lat, double lng, EagerLoad el, double offset)
        {
            //Moon Illum must be done for both the Moon Name and Phase so either will trigger it to load
            if (el.Extensions.Lunar_Cycle || el.Extensions.Zodiac)
            {
                date    = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);
                offset *= -1;
                double julianOffset = offset * .04166667;

                SolarCoordinates s     = SunCalc.Get_Solar_Coordinates(date, offset);
                double           JDE   = JulianConversions.GetJulian(date) + julianOffset; //Get julian
                double           T     = (JDE - 2451545) / 36525;                          //Get dynamic time.
                double[]         LDMNF = Get_Moon_LDMNF(T);

                LunarCoordinates m = GetMoonCoords(LDMNF, T, JDE);

                double sdist = 149598000,
                       phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians())),
                       inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi)),
                       angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                          Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));


                MoonIllum mi = new MoonIllum();

                mi.Fraction = (1 + Math.Cos(inc)) / 2;
                mi.Phase    = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
                mi.Angle    = angle;


                c.moonIllum = mi;

                string moonName = "";
                int    moonDate = 0;
                //GET PHASE NAME

                //CHECK MOON AT BEGINNING AT END OF DAY TO GET DAY PHASE
                DateTime dMon = new DateTime(date.Year, date.Month, 1);
                for (int x = 1; x <= date.Day; x++)
                {
                    DateTime nDate = new DateTime(dMon.Year, dMon.Month, x, 0, 0, 0, DateTimeKind.Utc);

                    s     = SunCalc.Get_Solar_Coordinates(date, offset);
                    JDE   = JulianConversions.GetJulian(nDate) + julianOffset; //Get julian
                    T     = (JDE - 2451545) / 36525;                           //Get dynamic time.
                    LDMNF = Get_Moon_LDMNF(T);
                    m     = GetMoonCoords(LDMNF, T, JDE);

                    phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));
                    inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi));
                    angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                       Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));

                    double startPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;

                    nDate = new DateTime(dMon.Year, dMon.Month, x, 23, 59, 59, DateTimeKind.Utc);

                    s     = SunCalc.Get_Solar_Coordinates(date, offset);
                    JDE   = JulianConversions.GetJulian(nDate) + julianOffset; //Get julian
                    T     = (JDE - 2451545) / 36525;                           //Get dynamic time.
                    LDMNF = Get_Moon_LDMNF(T);
                    m     = GetMoonCoords(LDMNF, T, JDE);

                    phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));
                    inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi));
                    angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                       Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));

                    double endPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
                    //Determine Moon Name.
                    if (startPhase <= .5 && endPhase >= .5)
                    {
                        moonDate = x;
                        moonName = GetMoonName(dMon.Month, moonName);
                    }
                    //Get Moon Name (month, string);
                    //Get Moon Phase Name
                    if (date.Day == x)
                    {
                        if (startPhase > endPhase)
                        {
                            mi.PhaseName = "New Moon";
                            break;
                        }
                        if (startPhase <= .25 && endPhase >= .25)
                        {
                            mi.PhaseName = "First Quarter";
                            break;
                        }
                        if (startPhase <= .5 && endPhase >= .5)
                        {
                            mi.PhaseName = "Full Moon";
                            break;
                        }
                        if (startPhase <= .75 && endPhase >= .75)
                        {
                            mi.PhaseName = "Last Quarter";
                            break;
                        }

                        if (startPhase > 0 && startPhase < .25 && endPhase > 0 && endPhase < .25)
                        {
                            mi.PhaseName = "Waxing Crescent";
                            break;
                        }
                        if (startPhase > .25 && startPhase < .5 && endPhase > .25 && endPhase < .5)
                        {
                            mi.PhaseName = "Waxing Gibbous";
                            break;
                        }
                        if (startPhase > .5 && startPhase < .75 && endPhase > .5 && endPhase < .75)
                        {
                            mi.PhaseName = "Waning Gibbous";
                            break;
                        }
                        if (startPhase > .75 && startPhase < 1 && endPhase > .75 && endPhase < 1)
                        {
                            mi.PhaseName = "Waning Crescent";
                            break;
                        }
                    }
                }
                if (date.Day == moonDate)
                {
                    if (el.Extensions.Zodiac)
                    {
                        c.AstrologicalSigns.moonName = moonName;
                    }
                }
                else
                {
                    if (el.Extensions.Zodiac)
                    {
                        c.AstrologicalSigns.moonName = "";
                    }
                }
            }
            if (el.Extensions.Lunar_Eclipse)
            {
                CalculateLunarEclipse(date, lat, lng, c);
            }
        }
        public static void CalculateSunTime(double lat, double longi, DateTime date, Celestial c, double offset = 0)
        {
            if (date.Year == 0001)
            {
                return;
            }                                  //Return if date vaue hasn't been established.
            DateTime actualDate = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);

            //Sun Time Calculations
            date = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc);
            double zone = -(int)Math.Round(TimeZone.CurrentTimeZone.GetUtcOffset(date).TotalSeconds / 3600);
            double jd   = JulianConversions.GetJulian(date) - 2451545; // Julian day relative to Jan 1.5, 2000

            double lon = longi / 360;
            double tz  = -1 * offset / 24;
            double ct  = jd / 36525 + 1;                            // centuries since 1900.0
            double t0  = LocalSiderealTimeForTimeZone(lon, jd, tz); // local sidereal time

            // get sun position at start of day
            jd += tz;
            CalculateSunPosition(jd, ct);
            double ra0  = mSunPositionInSkyArr[0];
            double dec0 = mSunPositionInSkyArr[1];

            // get sun position at end of day
            jd += 1;
            CalculateSunPosition(jd, ct);
            double ra1  = mSunPositionInSkyArr[0];
            double dec1 = mSunPositionInSkyArr[1];

            // make continuous
            if (ra1 < ra0)
            {
                ra1 += 2 * Math.PI;
            }

            mIsSunrise = false;
            mIsSunset  = false;

            mRightAscentionArr[0] = ra0;
            mDecensionArr[0]      = dec0;

            // check each hour of this day
            for (int k = 0; k < 25; k++)
            {
                mRightAscentionArr[2] = ra0 + (k + 1) * (ra1 - ra0) / 24;
                mDecensionArr[2]      = dec0 + (k + 1) * (dec1 - dec0) / 24;
                mVHzArr[2]            = TestHour(k, zone, t0, lat);
                // advance to next hour
                mRightAscentionArr[0] = mRightAscentionArr[2];
                mDecensionArr[0]      = mDecensionArr[2];
                mVHzArr[0]            = mVHzArr[2];
            }
            //Times returned for 00:00 may create an hour value of 24 which will throw a DateTime Exception.
            //Reset to 0 and keep same day month as this library is designed to return same day event in Z day only.
            if (mRiseTimeArr[0] >= 24)
            {
                mRiseTimeArr[0] -= 24;
            }
            if (mSetTimeArr[0] >= 24)
            {
                mSetTimeArr[0] -= 24;
            }

            c.SunRise      = new DateTime(date.Year, date.Month, date.Day, mRiseTimeArr[0], mRiseTimeArr[1], 0);
            c.SunSet       = new DateTime(date.Year, date.Month, date.Day, mSetTimeArr[0], mSetTimeArr[1], 0);
            c.SunCondition = CelestialStatus.RiseAndSet;

            // neither sunrise nor sunset
            if ((!mIsSunrise) && (!mIsSunset))
            {
                if (mVHzArr[2] < 0)
                {
                    c.SunCondition = CelestialStatus.DownAllDay;
                    c.SunRise      = null;
                    c.SunSet       = null;
                    // Sun down all day
                }
                else
                {
                    c.SunCondition = CelestialStatus.UpAllDay;
                    c.SunRise      = null;
                    c.SunSet       = null;
                    // Sun up all day
                }
            }
            // sunrise or sunset
            else
            {
                if (!mIsSunrise)
                {
                    // No sunrise this date
                    c.SunCondition = CelestialStatus.NoRise;
                    c.SunRise      = null;
                }
                else if (!mIsSunset)
                {
                    // No sunset this date
                    c.SunCondition = CelestialStatus.NoSet;
                    c.SunSet       = null;
                }
            }

            //Azimuth and Altitude
            CalculateSunAngle(actualDate, longi, lat, c);
        }
Пример #13
0
        public static void GetMoonIllumination(DateTime date, Celestial c, double lat, double lng)
        {
            date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);

            double    d   = JulianConversions.GetJulian_Epoch2000(date);
            CelCoords s   = GetSunCoords(d);
            double    JDE = JulianConversions.GetJulian(date); //Get julian
            double    T   = (JDE - 2451545) / 36525;           //Get dynamic time.

            double[] LDMNF = Get_Moon_LDMNF(T);

            CelCoords m = GetMoonCoords(d, c, LDMNF, T);

            double sdist = 149598000,
                   phi   = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra)),
                   inc   = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi)),
                   angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) -
                                      Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra));


            MoonIllum mi = new MoonIllum();

            mi.Fraction = (1 + Math.Cos(inc)) / 2;
            mi.Phase    = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
            mi.Angle    = angle;


            c.MoonIllum = mi;

            string moonName = "";
            int    moonDate = 0;
            //GET PHASE NAME

            //CHECK MOON AT BEGINNING AT END OF DAY TO GET DAY PHASE
            DateTime dMon = new DateTime(date.Year, date.Month, 1);

            for (int x = 1; x <= date.Day; x++)
            {
                DateTime nDate = new DateTime(dMon.Year, dMon.Month, x, 0, 0, 0, DateTimeKind.Utc);
                d     = JulianConversions.GetJulian_Epoch2000(nDate);
                s     = GetSunCoords(d);
                JDE   = JulianConversions.GetJulian(nDate); //Get julian
                T     = (JDE - 2451545) / 36525;            //Get dynamic time.
                LDMNF = Get_Moon_LDMNF(T);
                m     = GetMoonCoords(d, c, LDMNF, T);

                phi   = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra));
                inc   = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi));
                angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) -
                                   Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra));

                double startPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;

                nDate = new DateTime(dMon.Year, dMon.Month, x, 23, 59, 59, DateTimeKind.Utc);
                d     = JulianConversions.GetJulian_Epoch2000(nDate);
                s     = GetSunCoords(d);
                JDE   = JulianConversions.GetJulian(nDate); //Get julian
                T     = (JDE - 2451545) / 36525;            //Get dynamic time.
                LDMNF = Get_Moon_LDMNF(T);
                m     = GetMoonCoords(d, c, LDMNF, T);

                phi   = Math.Acos(Math.Sin(s.dec) * Math.Sin(m.dec) + Math.Cos(s.dec) * Math.Cos(m.dec) * Math.Cos(s.ra - m.ra));
                inc   = Math.Atan2(sdist * Math.Sin(phi), m.dist - sdist * Math.Cos(phi));
                angle = Math.Atan2(Math.Cos(s.dec) * Math.Sin(s.ra - m.ra), Math.Sin(s.dec) * Math.Cos(m.dec) -
                                   Math.Cos(s.dec) * Math.Sin(m.dec) * Math.Cos(s.ra - m.ra));

                double endPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
                //Determine Moon Name.
                if (startPhase <= .5 && endPhase >= .5)
                {
                    moonDate = x;
                    moonName = GetMoonName(dMon.Month, moonName);
                }
                //Get Moon Name (month, string);
                //Get Moon Phase Name
                if (date.Day == x)
                {
                    if (startPhase > endPhase)
                    {
                        mi.PhaseName = "New Moon";
                        break;
                    }
                    if (startPhase <= .25 && endPhase >= .25)
                    {
                        mi.PhaseName = "First Quarter";
                        break;
                    }
                    if (startPhase <= .5 && endPhase >= .5)
                    {
                        mi.PhaseName = "Full Moon";
                        break;
                    }
                    if (startPhase <= .75 && endPhase >= .75)
                    {
                        mi.PhaseName = "Last Quarter";
                        break;
                    }

                    if (startPhase > 0 && startPhase < .25 && endPhase > 0 && endPhase < .25)
                    {
                        mi.PhaseName = "Waxing Crescent";
                        break;
                    }
                    if (startPhase > .25 && startPhase < .5 && endPhase > .25 && endPhase < .5)
                    {
                        mi.PhaseName = "Waxing Gibbous";
                        break;
                    }
                    if (startPhase > .5 && startPhase < .75 && endPhase > .5 && endPhase < .75)
                    {
                        mi.PhaseName = "Waning Gibbous";
                        break;
                    }
                    if (startPhase > .75 && startPhase < 1 && endPhase > .75 && endPhase < 1)
                    {
                        mi.PhaseName = "Waning Crescent";
                        break;
                    }
                }
            }
            if (date.Day == moonDate)
            {
                c.AstrologicalSigns.MoonName = moonName;
            }
            else
            {
                c.AstrologicalSigns.MoonName = "";
            }
            CalculateLunarEclipse(date, lat, lng, c);
        }