예제 #1
0
        public void NearestPhase()
        {
            // 1 second error
            double error = 1.0 / (24 * 60 * 60);

            {
                // New Moon takes place in February 1977
                Date   date = new Date(1977, 2, 15);
                double jd   = date.ToJulianEphemerisDay();

                double jdNewMoon = LunarEphem.NearestPhase(jd, MoonPhase.NewMoon);

                Assert.AreEqual(2443192.65118, jdNewMoon, error);
            }

            {
                // First last quarter of 2044
                Date   date = new Date(2044, 1, 1);
                double jd   = date.ToJulianEphemerisDay();

                double jdLastQuarter = LunarEphem.NearestPhase(jd, MoonPhase.LastQuarter);

                Assert.AreEqual(2467636.49186, jdLastQuarter, error);
            }
        }
예제 #2
0
        /// <summary>
        /// Calculates instants of first sighting of lunar crescent on the evening sky, i.e. noumenia events.
        /// </summary>
        /// <remarks>
        /// The method is based on work of B.D.Yallop,
        /// see the work there: https://webspace.science.uu.nl/~gent0113/islam/downloads/naotn_69.pdf.
        /// As it noted in the work (see page 12):
        /// From observers reports it has been found that in general q = 0
        /// is close to the lower limit for first visibility under
        /// perfect atmospheric conditions at sea level without requiring optical aid.
        /// Also lunar altitude should be checked: 2 degrees above horizon is an empyric value.
        /// So, the condition of the event used there is "q > 0 && alt > 0"
        /// </remarks>
        private ICollection <AstroEvent> Noumenia(AstroEventsContext context)
        {
            List <AstroEvent> events = new List <AstroEvent>();
            double            jd     = 0;

            jd = context.From;
            while (jd < context.To)
            {
                if (context.CancelToken?.IsCancellationRequested == true)
                {
                    return(new AstroEvent[0]);
                }
                else
                {
                    double jdNewMoon = LunarEphem.NearestPhase(jd, MoonPhase.NewMoon);

                    for (int day = 0; day <= 7; day++)
                    {
                        var ctx = new SkyContext(jdNewMoon + day, context.GeoLocation, preferFast: true);

                        double jdMidnight = ctx.JulianDayMidnight;

                        var rtsSun  = ctx.Get(solarCalc.RiseTransitSet);
                        var rtsMoon = ctx.Get(lunarCalc.RiseTransitSet);

                        var sunSet  = double.IsNaN(rtsSun.Set) ? 1 : rtsSun.Set;
                        var moonSet = double.IsNaN(rtsMoon.Set) ? 1 : rtsMoon.Set;

                        double jdBestTime = jdMidnight + sunSet + 4.0 / 9.0 * (moonSet - sunSet);
                        ctx = new SkyContext(jdBestTime, context.GeoLocation, preferFast: true);

                        double alt = ctx.Get(lunarCalc.Horizontal).Altitude;
                        double q   = ctx.Get(lunarCalc.CrescentQ);

                        if (q > 0 && alt > 2)
                        {
                            events.Add(new AstroEvent(jdBestTime, Text.Get("MoonEvents.Noumenia.Text"), lunarCalc.Moon));
                            break;
                        }
                    }

                    jd = jdNewMoon + LunarEphem.SINODIC_PERIOD;
                }
            }

            return(events);
        }
예제 #3
0
        /// <summary>
        /// Calculates dates of lunar phases within specified range
        /// </summary>
        private ICollection <AstroEvent> Phases(AstroEventsContext context)
        {
            List <AstroEvent> events = new List <AstroEvent>();
            double            jd     = 0;

            jd = context.From;
            while (jd < context.To)
            {
                jd = LunarEphem.NearestPhase(jd, MoonPhase.NewMoon);
                events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.NewMoon"), lunarCalc.Moon));
                jd += LunarEphem.SINODIC_PERIOD;
            }

            jd = context.From;
            while (jd < context.To)
            {
                jd = LunarEphem.NearestPhase(jd, MoonPhase.FirstQuarter);
                events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.FirstQuarter"), lunarCalc.Moon));
                jd += LunarEphem.SINODIC_PERIOD;
            }

            jd = context.From;
            while (jd < context.To)
            {
                jd = LunarEphem.NearestPhase(jd, MoonPhase.FullMoon);
                events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.FullMoon"), lunarCalc.Moon));
                jd += LunarEphem.SINODIC_PERIOD;
            }

            jd = context.From;
            while (jd < context.To)
            {
                jd = LunarEphem.NearestPhase(jd, MoonPhase.LastQuarter);
                events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.LastQuarter"), lunarCalc.Moon));
                jd += LunarEphem.SINODIC_PERIOD;
            }

            return(events);
        }
예제 #4
0
        /// <summary>
        /// Calculates dates of lunar phases within specified range
        /// </summary>
        private ICollection <AstroEvent> Phases(AstroEventsContext context)
        {
            List <AstroEvent> events = new List <AstroEvent>();
            double            jd     = 0;

            jd = context.From;
            while (jd < context.To)
            {
                if (context.CancelToken?.IsCancellationRequested == true)
                {
                    return(new AstroEvent[0]);
                }
                else
                {
                    jd = LunarEphem.NearestPhase(jd, MoonPhase.NewMoon);
                    events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.NewMoon"), lunarCalc.Moon));
                    jd += LunarEphem.SINODIC_PERIOD;
                }
            }

            jd = context.From;
            while (jd < context.To)
            {
                if (context.CancelToken?.IsCancellationRequested == true)
                {
                    return(new AstroEvent[0]);
                }
                else
                {
                    jd = LunarEphem.NearestPhase(jd, MoonPhase.FirstQuarter);
                    events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.FirstQuarter"), lunarCalc.Moon));
                    jd += LunarEphem.SINODIC_PERIOD;
                }
            }

            jd = context.From;
            while (jd < context.To)
            {
                if (context.CancelToken?.IsCancellationRequested == true)
                {
                    return(new AstroEvent[0]);
                }
                else
                {
                    jd = LunarEphem.NearestPhase(jd, MoonPhase.FullMoon);
                    events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.FullMoon"), lunarCalc.Moon));
                    jd += LunarEphem.SINODIC_PERIOD;
                }
            }

            jd = context.From;
            while (jd < context.To)
            {
                if (context.CancelToken?.IsCancellationRequested == true)
                {
                    return(new AstroEvent[0]);
                }
                else
                {
                    jd = LunarEphem.NearestPhase(jd, MoonPhase.LastQuarter);
                    events.Add(new AstroEvent(jd, Text.Get("MoonEvents.Phases.LastQuarter"), lunarCalc.Moon));
                    jd += LunarEphem.SINODIC_PERIOD;
                }
            }

            return(events);
        }
예제 #5
0
파일: LunarCalc.cs 프로젝트: t9mike/ADK
 /// <summary>
 /// Gets nearest phase date
 /// </summary>
 private Date NearestPhase(SkyContext c, MoonPhase p)
 {
     return(c.GetDate(LunarEphem.NearestPhase(c.JulianDay, p)));
 }