Ejemplo n.º 1
0
    public SunAndMoonData GetData(DateTime dt, double lat, double lng, double TimeZoneDifferenceFromUTC)
    {
        SunAndMoonData data = new SunAndMoonData();

        FindSunAndTwilightDataForDate(data, dt, TimeZoneDifferenceFromUTC, lng, lat);
        FindMoonRiseAndSet(data, dt, TimeZoneDifferenceFromUTC, lng, lat);

        TimeSpan ts = data.SunSet - data.SunRise;

        data.SolarNoon = data.SunRise.AddMilliseconds(ts.TotalMilliseconds / 2);

        return(data);
    }
Ejemplo n.º 2
0
        protected internal override void Tick()
        {
            Twilight2 T = new Twilight2();

            Data = T.GetData(DateTime.Now, Settings.Default.Lat, Settings.Default.Lng, (DateTime.Now - DateTime.UtcNow).TotalHours);


            int Current = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
            int Sunrise = Data.SunRise.Hour * 60 + Data.SunRise.Minute;
            int Sunset  = Data.SunSet.Hour * 60 + Data.SunSet.Minute;

            // Messy, but this will lerp the background from night->day->night, with one-hour transitions centered on the sunrise/sunset times.
            if (Current < Sunrise - 30)
            {
                LerpAmt = 0;
            }
            else if (Math.Abs(Current - Sunrise) <= 30)
            {
                int Test = Current - (Sunrise - 30);
                LerpAmt = (float)Test / 60;
            }
            else if (Current < Sunset - 30)
            {
                LerpAmt = 1;
            }
            else if (Math.Abs(Current - Sunset) <= 30)
            {
                int Test = Current - (Sunset - 30);
                LerpAmt = 1 - ((float)Test / 60);
            }
            else
            {
                LerpAmt = 0;
            }

            Vector4 Colour1Day   = new Vector4(0.171875f, 0.37109375f, 0.92578125f, 1.0f);
            Vector4 Colour1Night = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);

            Vector4 Colour2Day   = new Vector4(0.3828125f, 0.765625f, 0.95703125f, 1.0f);
            Vector4 Colour2Night = new Vector4(0.11328125f, 0.01953125f, 0.1015625f, 1.0f);

            Vector4 Colour3Day   = new Vector4(0.23828125f, 0.81640625f, 0.94921875f, 1.0f);
            Vector4 Colour3Night = new Vector4(0.19921875f, 0.0859375f, 0.19140625f, 1.0f);

            // Lerp all positions and colours from day to night (or back)
            float Position1 = Lerp(56f, 76f, LerpAmt);
            float Position2 = Lerp(20f, 30f, LerpAmt);

            Vector4 Colour1 = Colour1Night + (Colour1Day - Colour1Night) * LerpAmt;
            Vector4 Colour2 = Colour2Night + (Colour2Day - Colour2Night) * LerpAmt;
            Vector4 Colour3 = Colour3Night + (Colour3Day - Colour3Night) * LerpAmt;

            // Now set vertex heights/colours
            Vertexes[6].Position.Y = Vertexes[7].Position.Y = Vertexes[8].Position.Y = Vertexes[9].Position.Y = Program.Configuration.Height * Position1 / 100;
            Vertexes[2].Position.Y = Vertexes[3].Position.Y = Vertexes[4].Position.Y = Vertexes[5].Position.Y = Program.Configuration.Height * Position2 / 100;


            Vertexes[0].Color = Vertexes[1].Color = Colour3;
            Vertexes[2].Color = Vertexes[3].Color = Vertexes[4].Color = Vertexes[5].Color = Colour2;
            Vertexes[6].Color = Vertexes[7].Color = Vertexes[8].Color = Vertexes[9].Color = Vertexes[10].Color = Vertexes[11].Color = Colour1;
        }
Ejemplo n.º 3
0
    private string FindMoonRiseAndSet(SunAndMoonData data, DateTime dt, double tz, double glong, double glat)
    {
        //
        //  Im using a separate function for moonrise/set to allow for different tabulations
        //  of moonrise and sun events ie weekly for sun and daily for moon. The logic of
        //  the function is identical to find_sun_and_twi_events_for_date()
        //
        //alert(mjd);
        //alert(tz);
        //alert(glong);
        //alert(glat);

        double mjd = GetJulianDate(dt, 0);

        double sglat, sinho, cglat, date, ym, yz, utrise, utset;
        double yp, nz, hour, z1, z2, xe, ye, rads = 0.0174532925;

        bool rise, sett, above;

        double[] quadout = new double[4];
        //var sinho;
        string outstring = "";

        sinho  = Math.Sin(rads * 8 / 60);       //moonrise taken as centre of moon at +8 arcmin
        sglat  = Math.Sin(rads * glat);
        cglat  = Math.Cos(rads * glat);
        date   = mjd - tz / 24;
        rise   = false;
        sett   = false;
        above  = false;
        hour   = 1.0;
        utrise = 0;
        utset  = 0;
        ym     = sin_alt(1, date, hour - 1.0, glong, cglat, sglat) - sinho;
        if (ym > 0.0)
        {
            above = true;
        }
        while (hour < 25 && (sett == false || rise == false))
        {
            yz      = sin_alt(1, date, hour, glong, cglat, sglat) - sinho;
            yp      = sin_alt(1, date, hour + 1.0, glong, cglat, sglat) - sinho;
            quadout = quad(ym, yz, yp);
            nz      = quadout[0];
            z1      = quadout[1];
            z2      = quadout[2];
            xe      = quadout[3];
            ye      = quadout[4];

            // case when one event is found in the interval
            if (nz == 1)
            {
                if (ym < 0.0)
                {
                    utrise = hour + z1;
                    rise   = true;
                }
                else
                {
                    utset = hour + z1;
                    sett  = true;
                }
            } // end of nz = 1 case

            // case where two events are found in this interval
            // (rare but whole reason we are not using simple iteration)
            if (nz == 2)
            {
                if (ye < 0.0)
                {
                    utrise = hour + z2;
                    utset  = hour + z1;
                }
                else
                {
                    utrise = hour + z1;
                    utset  = hour + z2;
                }
            }

            // set up the next search interval
            ym    = yp;
            hour += 2.0;
        } // end of while loop

        data.MoonRise = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
        data.MoonSet  = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);

        if (rise == true || sett == true)
        {
            if (rise == true)
            {
                outstring += " " + hrsmin(utrise);
            }
            else
            {
                outstring += " No Rise";
            }
            if (sett == true)
            {
                outstring += " " + hrsmin(utset);
            }
            else
            {
                outstring += " No Set";
            }
        }
        else
        {
            if (above == true)
            {
                outstring += "above";
            }
            else
            {
                outstring += "below";
            }
        }
        return(outstring);
    }
Ejemplo n.º 4
0
    private string FindSunAndTwilightDataForDate(SunAndMoonData data, DateTime dt, double tz, double glong, double glat)
    {
        //
        //  this is my attempt to encapsulate most of the program in a function
        //  then this function can be generalised to find all the Sun events.
        //
        //
        double mjd = GetJulianDate(dt, 0);
        double sglat, cglat, date, ym, yz, utrise = 0, utset = 0;
        double yp, nz, hour, xe, ye, z1, z2, rads = 0.0174532925;

        bool rise, sett, above;

        double[] quadout   = new double[4];
        double[] sinho     = new double[4];
        string   outstring = "";

        //
        //  Set up the array with the 4 values of sinho needed for the 4
        //      kinds of sun event
        //
        sinho[0] = Math.Sin(rads * -0.833);     //sunset upper limb simple refraction
        sinho[1] = Math.Sin(rads * -6.0);       //civil twi
        sinho[2] = Math.Sin(rads * -12.0);      //nautical twi
        sinho[3] = Math.Sin(rads * -18.0);      //astro twi
        sglat    = Math.Sin(rads * glat);
        cglat    = Math.Cos(rads * glat);
        date     = mjd - tz / 24;
        //
        //  main loop takes each value of sinho in turn and finds the rise/set
        //      events associated with that altitude of the Sun
        //
        for (int j = 0; j < 4; j++)
        {
            rise  = false;
            sett  = false;
            above = false;
            hour  = 1.0;
            ym    = sin_alt(2, date, hour - 1.0, glong, cglat, sglat) - sinho[j];
            if (ym > 0.0)
            {
                above = true;
            }
            //
            // the while loop finds the sin(alt) for sets of three consecutive
            // hours, and then tests for a single zero crossing in the interval
            // or for two zero crossings in an interval or for a grazing event
            // The flags rise and sett are set accordingly
            //
            nz = 0; z1 = 0; z2 = 0; xe = 0; ye = 0;
            while (hour < 25 && (sett == false || rise == false))
            {
                yz      = sin_alt(2, date, hour, glong, cglat, sglat) - sinho[j];
                yp      = sin_alt(2, date, hour + 1.0, glong, cglat, sglat) - sinho[j];
                quadout = quad(ym, yz, yp);
                nz      = quadout[0];
                z1      = quadout[1];
                z2      = quadout[2];
                xe      = quadout[3];
                ye      = quadout[4];

                // case when one event is found in the interval
                if (nz == 1)
                {
                    if (ym < 0.0)
                    {
                        utrise = hour + z1;
                        rise   = true;
                    }
                    else
                    {
                        utset = hour + z1;
                        sett  = true;
                    }
                } // end of nz = 1 case

                // case where two events are found in this interval
                // (rare but whole reason we are not using simple iteration)
                if (nz == 2)
                {
                    if (ye < 0.0)
                    {
                        utrise = hour + z2;
                        utset  = hour + z1;
                    }
                    else
                    {
                        utrise = hour + z1;
                        utset  = hour + z2;
                    }
                } // end of nz = 2 case

                // set up the next search interval
                ym    = yp;
                hour += 2.0;
            } // end of while loop
              //
              // now search has completed, we compile the string to pass back
              // to the main loop. The string depends on several combinations
              // of the above flag (always above or always below) and the rise
              // and sett flags
              //

            switch (j)
            {
            case 0:     // SunRise/SunSet
                //data.XXX = z2.ToString();
                data.SunRise = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                data.SunSet  = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                break;

            case 1:     // Civial Twilight
                data.CivalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                data.CivalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                break;

            case 2:     // nautical Twilight
                data.NauticalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                data.NauticalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                break;

            case 3:     // Astronomical Twilight
                data.AstronomicalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                data.AstronomicalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                break;
            }

            if (rise == true || sett == true)
            {
                if (rise == true)
                {
                    outstring += " " + hrsmin(utrise);
                }
                else
                {
                    outstring += " No Rise";
                }
                if (sett == true)
                {
                    outstring += " " + hrsmin(utset);
                }
                else
                {
                    outstring += " No Set";
                }
            }
            else
            {
                if (above == true)
                {
                    outstring += "above";
                }
                else
                {
                    outstring += "below";
                }
            }
        } // end of for loop - next condition

        return(outstring);
    }