Example #1
0
        /*********************************************************************/
        /*                                                                   */
        /*  m1 - previous moon position                                      */
        /*  m2 - next moon position                                          */
        /*  s1 - previous sun position                                       */
        /*  s2 - next sun position                                           */
        /*                                                                   */
        /*  Test for conjunction of the sun and moon                         */
        /*  m1,s1 is in one time moment                                      */
        /*  m2,s2 is in second time moment                                   */
        /*                                                                   */
        /*  this function tests whether conjunction occurs between           */
        /*  these two moments                                                */
        /*                                                                   */
        /*********************************************************************/

        public static bool IsConjunction(double m1, double s1, double s2, double m2)
        {
            if (m2 < m1)
            {
                m2 += 360.0;
            }
            if (s2 < s1)
            {
                s2 += 360.0;
            }
            if ((m1 <= s1) && (s1 < s2) && (s2 <= m2))
            {
                return(true);
            }

            m1 = GCMath.putIn180(m1);
            m2 = GCMath.putIn180(m2);
            s1 = GCMath.putIn180(s1);
            s2 = GCMath.putIn180(s2);

            if ((m1 <= s1) && (s1 < s2) && (s2 <= m2))
            {
                return(true);
            }

            return(false);
        }
Example #2
0
        ///////////////////////////////////////////////////////////////////////
        // GET PREVIOUS CONJUNCTION OF THE SUN AND MOON
        //
        // THIS IS HELP FUNCTION FOR GetPrevConjunction(VCTIME test_date,
        //                                         VCTIME &found, bool this_day, EARTHDATA earth)
        //
        // looking for previous sun-moon conjunction
        // it starts from input day from 12:00 AM (noon) UTC
        // so output can be the same day
        // if output is the same day, then conjunction occurs between 00:00 AM and noon of this day
        //
        // date - input / output
        // earth - input
        // return value - sun longitude in degs
        //
        // error is when return value is greater than 999.0 deg

        public static double GetPrevConjunction(ref GregorianDateTime date, GCEarthData earth)
        {
            int    bCont = 32;
            double prevSun = 0.0, prevMoon = 0.0, prevDiff = 0.0;
            double nowSun = 0.0, nowMoon = 0.0, nowDiff = 0.0;
            //	SUNDATA sun;
            double            jd, longitudeMoon;
            GregorianDateTime d = new GregorianDateTime();

            d.Set(date);
            d.shour         = 0.5;
            d.TimezoneHours = 0.0;
            jd = d.GetJulian();//GetJulianDay(d.year, d.month, d.day);

            // set initial data for input day
            // NOTE: for grenwich
            //SunPosition(d, earth, sun);
            longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, earth);
            prevSun       = GCSunData.GetSunLongitude(d);
            prevMoon      = longitudeMoon;
            prevDiff      = GCMath.putIn180(prevSun - prevMoon);

            do
            {
                // shift to day before
                d.PreviousDay();
                jd -= 1.0;
                // calculation
                //SunPosition(d, earth, sun);
                longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, earth);
                nowSun        = GCSunData.GetSunLongitude(d);
                nowMoon       = longitudeMoon;
                nowDiff       = GCMath.putIn180(nowSun - nowMoon);
                // if difference of previous has another sign than now calculated
                // then it is the case that moon was faster than sun and he
                //printf("        prevsun=%f\nprevmoon=%f\nnowsun=%f\nnowmoon=%f\n", prevSun, prevMoon, nowSun, nowMoon);


                if (IsConjunction(nowMoon, nowSun, prevSun, prevMoon))
                {
                    // now it calculates actual time and zodiac of conjunction
                    double x;
                    if (prevDiff == nowDiff)
                    {
                        return(0);
                    }
                    x = Math.Abs(nowDiff) / Math.Abs(prevDiff - nowDiff);
                    if (x < 0.5)
                    {
                        d.shour = x + 0.5;
                    }
                    else
                    {
                        d.NextDay();
                        d.shour = x - 0.5;
                    }
                    date.Set(d);
                    double other = GCSunData.GetSunLongitude(d);
                    //			double other2 = nowSun + (prevSun - nowSun)*x;
                    GCMath.putIn360(prevSun);
                    GCMath.putIn360(nowSun);
                    if (Math.Abs(prevSun - nowSun) > 10.0)
                    {
                        return(GCMath.putIn180(nowSun) + (GCMath.putIn180(prevSun) - GCMath.putIn180(nowSun)) * x);
                    }
                    else
                    {
                        return(nowSun + (prevSun - nowSun) * x);
                    }
                    //			return other2;
                }
                prevSun  = nowSun;
                prevMoon = nowMoon;
                prevDiff = nowDiff;
                bCont--;
            }while (bCont >= 0);

            return(1000.0);
        }
Example #3
0
        /*********************************************************************/
        /*                                                                   */
        /*                                                                   */
        /*                                                                   */
        /*                                                                   */
        /*                                                                   */
        /*********************************************************************/

        public static double GetNextConjunction(GregorianDateTime test_date, out GregorianDateTime found, bool this_conj, GCEarthData earth)
        {
            double phi = 12.0;
            double l1, l2, longitudeSun, longitudeMoon;

            if (this_conj)
            {
                test_date.shour += 0.2;
                test_date.NormalizeValues();
            }


            double            jday = test_date.GetJulianComplete();
            double            xj;
            GregorianDateTime d = new GregorianDateTime();

            d.Set(test_date);
            GregorianDateTime xd        = new GregorianDateTime();
            double            scan_step = 1.0;
            int prev_tit = 0;
            int new_tit  = -1;

            longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, earth);
            longitudeSun  = GCSunData.GetSunLongitude(d);
            l1            = GCMath.putIn180(longitudeMoon - longitudeSun);
            prev_tit      = GCMath.IntFloor(l1 / phi);

            int counter = 0;

            while (counter < 20)
            {
                xj = jday;
                xd.Set(d);

                jday    += scan_step;
                d.shour += scan_step;
                if (d.shour > 1.0)
                {
                    d.shour -= 1.0;
                    d.NextDay();
                }

                longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, earth);
                longitudeSun  = GCSunData.GetSunLongitude(d);
                l2            = GCMath.putIn180(longitudeMoon - longitudeSun);
                new_tit       = GCMath.IntFloor(l2 / phi);

                if (prev_tit < 0 && new_tit >= 0)
                {
                    jday = xj;
                    d.Set(xd);
                    scan_step *= 0.5;
                    counter++;
                    continue;
                }
                else
                {
                    l1 = l2;
                }

                prev_tit = new_tit;
            }
            found = new GregorianDateTime();
            found.Set(d);
            return(longitudeSun);
        }
Example #4
0
        // this is not used effectovely
        // it is just try to have some alternative function for calculation sun position
        // but it needs to be fixed, because
        // it calculates correct ecliptical coordinates, but when transforming
        // into horizontal coordinates (azimut, elevation) it will do something wrong

        public static GCHorizontalCoords sunPosition(int year, int month, int day, int hour, int min, int sec,
                                                     double lat, double longi)
        {
            double twopi   = GCMath.PI2;
            double deg2rad = GCMath.PI2 / 180;

            int[] month_days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
            for (int y2 = 0; y2 < month; y2++)
            {
                day += month_days[y2];
            }
            if ((year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0)) && (day >= 60) && !(month == 2 & day == 60))
            {
                day++;
            }

            //# Get Julian date - 2400000
            double hourd = hour + min / 60.0 + sec / 3600.0; // hour plus fraction
            double delta = year - 1949;
            double leap  = Math.Floor(delta / 4);            // former leapyears
            double jd    = 32916.5 + delta * 365 + leap + day + hourd / 24.0;

            // The input to the Atronomer's almanach is the difference between
            // the Julian date and JD 2451545.0 (noon, 1 January 2000)
            double time = jd - 51545.0;

            // Ecliptic coordinates

            // Mean longitude
            double mnlong = GCMath.putIn360(280.460 + .9856474 * time);

            // Mean anomaly
            double mnanom = GCMath.putIn360(357.528 + .9856003 * time);
            //mnanom <- mnanom * deg2rad

            // Ecliptic longitude and obliquity of ecliptic
            double eclong = mnlong + 1.915 * GCMath.sinDeg(mnanom) + 0.020 * GCMath.sinDeg(2 * mnanom);

            eclong = GCMath.putIn360(eclong);

            double oblqec = 23.439 - 0.0000004 * time;
            //-- eclong <- eclong * deg2rad
            //-- oblqec <- oblqec * deg2rad

            // Celestial coordinates
            // Right ascension and declination
            double num = GCMath.cosDeg(oblqec) * GCMath.sinDeg(eclong);
            double den = GCMath.cosDeg(eclong);
            double ra  = GCMath.arcTan2Deg(num, den);

            while (ra < 0)
            {
                ra += 180;
            }
            //-- ra[den < 0] <- ra[den < 0] + pi
            if (den >= 0 && num < 0)
            {
                ra += 360;
            }
            double dec = GCMath.arcSinDeg(GCMath.sinDeg(oblqec) * GCMath.sinDeg(eclong));

            // Local coordinates
            // Greenwich mean sidereal time
            double gmst = 6.697375 + .0657098242 * time + hourd;

            gmst = GCMath.putIn24(gmst);

            // Local mean sidereal time
            double lmst = gmst + longi / 15.0;

            lmst = GCMath.putIn24(lmst);
            lmst = lmst * 15.0;

            // Hour angle
            double ha = lmst - ra;

            ha = GCMath.putIn180(ha);

            // Azimuth and elevation
            double el = GCMath.arcSinDeg(GCMath.sinDeg(dec) * GCMath.sinDeg(lat) + GCMath.cosDeg(dec) * GCMath.cosDeg(lat) * GCMath.cosDeg(ha));
            double az = GCMath.arcSinDeg(-GCMath.cosDeg(dec) * GCMath.sinDeg(ha) / GCMath.cosDeg(el));

            //# -----------------------------------------------
            //# New code
            //# Solar zenith angle
            double zenithAngle = GCMath.arccosDeg(GCMath.sinDeg(lat) * GCMath.sinDeg(dec) + GCMath.cosDeg(lat) * GCMath.cosDeg(dec) * GCMath.cosDeg(ha));

            //# Solar azimuth
            az = GCMath.arccosDeg(((GCMath.sinDeg(lat) * GCMath.cosDeg(zenithAngle)) - GCMath.sinDeg(dec)) / (GCMath.cosDeg(lat) * GCMath.sinDeg(zenithAngle)));
            //# -----------------------------------------------

            //# Azimuth and elevation
            el = GCMath.arcSinDeg(GCMath.sinDeg(dec) * GCMath.sinDeg(lat) + GCMath.cosDeg(dec) * GCMath.cosDeg(lat) * GCMath.cosDeg(ha));


            //# -----------------------------------------------
            //# New code
            if (ha > 0)
            {
                az += 180;
            }
            else
            {
                az = 540 - az;
            }
            az = GCMath.putIn360(az);

            // For logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353
            //cosAzPos <- (0 <= sin(dec) - sin(el) * sin(lat))
            //sinAzNeg <- (sin(az) < 0)
            //az[cosAzPos & sinAzNeg] <- az[cosAzPos & sinAzNeg] + twopi
            //az[!cosAzPos] <- pi - az[!cosAzPos]

            /*
             * if (0 < GCMath.sinDeg(dec) - GCMath.sinDeg(el) * GCMath.sinDeg(lat))
             * {
             *   if(GCMath.sinDeg(az) < 0)
             *   {
             *       az = az + 360;
             *   }
             * }
             * else
             * {
             *   az = 180 - az;
             * }
             */

            //el <- el / deg2rad
            //az <- az / deg2rad
            //lat <- lat / deg2rad

            GCHorizontalCoords coords;

            coords.azimut    = az;
            coords.elevation = el;
            return(coords);
        }