Exemplo n.º 1
0
        ////////////////////////////////////////////////////////////////
        //
        //  Conversion time from DEGREE fromat to H:M:S:MS format
        //
        //  time - output
        //  time_deg - input time in range 0 deg to 360 deg
        //             where 0 deg = 0:00 AM and 360 deg = 12:00 PM
        //
        public void SetDegTime(double time_deg)
        {
            double time_hr = 0.0;

            time_deg = GCMath.putIn360(time_deg);

            // hour
            time_hr = time_deg / 360 * 24;
            hour    = Convert.ToInt32(Math.Floor(time_hr));

            // minute
            time_hr -= hour;
            time_hr *= 60;
            min      = Convert.ToInt32(Math.Floor(time_hr));

            // second
            time_hr -= min;
            time_hr *= 60;
            sec      = Convert.ToInt32(Math.Floor(time_hr));

            // miliseconds
            time_hr -= sec;
            time_hr *= 1000;
            mili     = Convert.ToInt32(Math.Floor(time_hr));
        }
Exemplo n.º 2
0
        public double GetPlanetHouse(double longitudeTropical, double julianDate, GCEarthData earth)
        {
            double longitudeSidereal = longitudeTropical - GCAyanamsha.GetAyanamsa(julianDate);
            double firstHouseStart   = earth.GetAscendantDegrees(julianDate) - 15.0;

            return(GCMath.putIn360(longitudeSidereal - firstHouseStart) / 30.0);
        }
Exemplo n.º 3
0
        public static int GetNextYogaStart(GCEarthData ed, GregorianDateTime startDate, out GregorianDateTime nextDate)
        {
            double            phi = 40.0 / 3.0;
            double            l1, l2, longitudeSun;
            double            jday = startDate.GetJulianComplete();
            double            xj;
            double            longitudeMoon;
            GregorianDateTime d = new GregorianDateTime();

            d.Set(startDate);
            GregorianDateTime xd        = new GregorianDateTime();
            double            scan_step = 0.5;
            int    prev_tit             = 0;
            int    new_tit   = -1;
            double ayanamsha = GCAyanamsha.GetAyanamsa(jday);

            longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, ed);
            longitudeSun  = GCCoreAstronomy.GetSunLongitude(d, ed);
            l1            = GCMath.putIn360(longitudeMoon + longitudeSun - 2 * ayanamsha);
            prev_tit      = Convert.ToInt32(Math.Floor(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, ed);
                longitudeSun  = GCCoreAstronomy.GetSunLongitude(d, ed);
                l2            = GCMath.putIn360(longitudeMoon + longitudeSun - 2 * ayanamsha);
                new_tit       = Convert.ToInt32(Math.Floor(l2 / phi));

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

            return(new_tit);
        }
Exemplo n.º 4
0
        /*********************************************************************/
        /*                                                                   */
        /*   finds previous time when starts next tithi                      */
        /*                                                                   */
        /*   timezone is not changed                                         */
        /*                                                                   */
        /*   return value: index of tithi 0..29                              */
        /*                 or -1 if failed                                   */
        /*********************************************************************/

        public static int GetPrevTithiStart(GCEarthData ed, GregorianDateTime startDate, out GregorianDateTime nextDate)
        {
            double            phi = 12.0;
            double            l1, l2, longitudeSun, longitudeMoon;
            double            jday = startDate.GetJulianComplete();
            double            xj;
            GregorianDateTime d = new GregorianDateTime();

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

            longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, ed);
            longitudeSun  = GCCoreAstronomy.GetSunLongitude(d, ed);
            l1            = GCMath.putIn360(longitudeMoon - longitudeSun - 180.0);
            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 < 0.0)
                {
                    d.shour += 1.0;
                    d.PreviousDay();
                }

                longitudeSun  = GCCoreAstronomy.GetSunLongitude(d, ed);
                longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, ed);
                l2            = GCMath.putIn360(longitudeMoon - longitudeSun - 180.0);
                new_tit       = GCMath.IntFloor(l2 / phi);

                if (prev_tit != new_tit)
                {
                    jday = xj;
                    d.Set(xd);
                    scan_step *= 0.5;
                    counter++;
                    continue;
                }
                else
                {
                    l1 = l2;
                }
            }
            nextDate = d;
            //	nextDate.shour += startDate.tzone / 24.0;
            //	nextDate.NormalizeValues();
            return(new_tit);
        }
Exemplo n.º 5
0
        public static int GetNextMoonRasi(GCEarthData ed, GregorianDateTime startDate, out GregorianDateTime nextDate)
        {
            double            phi = 30.0;
            double            l1, l2, longitudeMoon;
            double            jday = startDate.GetJulianComplete();
            GregorianDateTime d    = new GregorianDateTime();

            d.Set(startDate);
            double ayanamsa  = GCAyanamsha.GetAyanamsa(jday);
            double scan_step = 0.5;
            int    prev_naks = 0;
            int    new_naks  = -1;

            double            xj;
            GregorianDateTime xd = new GregorianDateTime();

            longitudeMoon = GCCoreAstronomy.GetMoonLongitude(d, ed);
            l1            = GCMath.putIn360(longitudeMoon - ayanamsa);
            prev_naks     = 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, ed);
                l2            = GCMath.putIn360(longitudeMoon - ayanamsa);
                new_naks      = GCMath.IntFloor(l2 / phi);
                if (prev_naks != new_naks)
                {
                    jday = xj;
                    d.Set(xd);
                    scan_step *= 0.5;
                    counter++;
                    continue;
                }
                else
                {
                    l1 = l2;
                }
            }
            nextDate = new GregorianDateTime();
            nextDate.Set(d);
            return(new_naks);
        }
Exemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="julianDateUTC">Time in UT1 or for general use UTC. This should reflect also hours, minutes and seconds. When finding local sidereal time,
        /// this argument should contains time that is observed on Greenwich meridian. Use function GetJulianDetailed or GetGreenwichDateTime</param>
        /// <param name="longitudeDegrees"></param>
        /// <returns></returns>
        public static double SiderealTimeLocal(double julianDateUTC, double longitudeDegrees, double timezoneDegrees)
        {
            double julianDate2000, julianMillenium;
            double delta_phi = 0.0, epsilon = 0.0;

            julianDate2000  = julianDateUTC - 2451545.0;
            julianMillenium = julianDate2000 / 36525.0;
            GCEarthData.CalculateNutations(julianDateUTC, out delta_phi, out epsilon);
            return(GCMath.putIn360(280.46061837 + 360.98564736629 * julianDate2000 +
                                   julianMillenium * julianMillenium * (0.000387933 - julianMillenium / 38710000) +
                                   delta_phi * GCMath.cosDeg(epsilon) + longitudeDegrees - timezoneDegrees));
        }
Exemplo n.º 7
0
        public static double SiderealTimeGreenwich(double date)
        {
            double jd, t;
            double delta_phi = 0.0, epsilon = 0.0;

            jd = date;
            t  = (jd - 2451545.0) / 36525.0;
            GCEarthData.CalculateNutations(date, out delta_phi, out epsilon);
            return(GCMath.putIn360(280.46061837 + 360.98564736629 * (jd - 2451545.0) +
                                   t * t * (0.000387933 - t / 38710000) +
                                   delta_phi * GCMath.cosDeg(epsilon)));
        }
Exemplo n.º 8
0
        //==================================================================================
        //
        //==================================================================================



        public void calc_horizontal(double date, double longitude, double latitude)
        {
            double h;

            h = GCMath.putIn360(GCEarthData.SiderealTimeGreenwich(date) - this.rightAscension + longitude);

            this.azimuth = GCMath.rad2deg(Math.Atan2(GCMath.sinDeg(h),
                                                     GCMath.cosDeg(h) * GCMath.sinDeg(latitude) -
                                                     GCMath.tanDeg(this.declination) * GCMath.cosDeg(latitude)));

            this.elevation = GCMath.rad2deg(Math.Asin(GCMath.sinDeg(latitude) * GCMath.sinDeg(this.declination) +
                                                      GCMath.cosDeg(latitude) * GCMath.cosDeg(this.declination) * GCMath.cosDeg(h)));
        }
Exemplo n.º 9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="julianDateUTC">This contains time UTC, that means time observed on Greenwich meridian. DateTime in other
        /// timezones should be converted into timezone UTC+0h before using in this method.</param>
        /// <returns></returns>
        public double GetAscendantDegrees(double julianDateUTC)
        {
            double A         = GCEarthData.SiderealTimeLocal(julianDateUTC, longitudeDeg, OffsetUtcHours * 15.0);
            double E         = 23.4392911;
            double ascendant = GCMath.arcTan2Deg(-GCMath.cosDeg(A), GCMath.sinDeg(A) * GCMath.cosDeg(E) + GCMath.tanDeg(latitudeDeg) * GCMath.sinDeg(E));

            if (ascendant < 180)
            {
                ascendant += 180;
            }
            else
            {
                ascendant -= 180;
            }
            return(GCMath.putIn360(ascendant - GCAyanamsha.GetAyanamsa(julianDateUTC)));
        }
Exemplo n.º 10
0
        public static GCHorizontalCoords equatorialToHorizontalCoords(GCEquatorialCoords eqc, GCEarthData obs, double date)
        {
            double             localHourAngle;
            GCHorizontalCoords hc;

            localHourAngle = GCMath.putIn360(GCEarthData.SiderealTimeGreenwich(date) - eqc.rightAscension + obs.longitudeDeg);

            hc.azimut = GCMath.rad2deg(Math.Atan2(GCMath.sinDeg(localHourAngle),
                                                  GCMath.cosDeg(localHourAngle) * GCMath.sinDeg(obs.latitudeDeg) -
                                                  GCMath.tanDeg(eqc.declination) * GCMath.cosDeg(obs.latitudeDeg)));

            hc.elevation = GCMath.rad2deg(Math.Asin(GCMath.sinDeg(obs.latitudeDeg) * GCMath.sinDeg(eqc.declination) +
                                                    GCMath.cosDeg(obs.latitudeDeg) * GCMath.cosDeg(eqc.declination) * GCMath.cosDeg(localHourAngle)));

            return(hc);
        }
Exemplo n.º 11
0
        private void CalculatePlanetRasi(int bodyId, GCLocation loc, GregorianDateTime vcEnd, GregorianDateTime vcAdd, GCConfigRatedEvents rec)
        {
            int    nData;
            double JD, JDE;

            JD    = vcAdd.GetJulian() - 0.5 - loc.OffsetUtcHours / 24.0;
            JDE   = vcEnd.GetJulian() + 0.5 - loc.OffsetUtcHours / 24.0;
            nData = GCMath.IntFloor(GCMath.putIn360(GCVSOPAstronomy.GetPlanetLongitude(bodyId, JD) - GCAyanamsha.GetAyanamsa(JD)) / 30.0);

            // initial rasi at the start date 00:00
            AddRating(JD, loc, rec.rateGrahaRasi[bodyId, nData], rec.rateGrahaRasi[bodyId, Prev(nData, 12)]);

            while ((JD = FindNextRasiChange(JD, JDE, bodyId, out nData)) < JDE)
            {
                AddRating(JD, loc, rec.rateGrahaRasi[bodyId, nData], rec.rateGrahaRasi[bodyId, Prev(nData, 12)]);
                JD += 1.0;
            }
        }
Exemplo n.º 12
0
        /*********************************************************************/
        /*  Finds next time when rasi is changed                             */
        /*                                                                   */
        /*  startDate - starting date and time, timezone member must be valid */
        /*  zodiac [out] - found zodiac sign into which is changed           */
        /*                                                                   */
        /*********************************************************************/

        public static GregorianDateTime GetNextSankranti(GregorianDateTime startDate, GCEarthData earth, out int zodiac)
        {
            GregorianDateTime d = new GregorianDateTime();
            double            step = 1.0;
            int               count = 0;
            double            ld, prev;
            int               prev_rasi, new_rasi;
            GregorianDateTime prevday;

            d.Set(startDate);
            //d.ChangeTimeZone(0.0);
            //d.shour = 0.0;
            zodiac = 0;

            prev      = GCMath.putIn360(GCCoreAstronomy.GetSunLongitude(d, earth) - GCAyanamsha.GetAyanamsa(d.GetJulian()));
            prev_rasi = GCMath.IntFloor(prev / 30.0);

            while (count < 20)
            {
                prevday = new GregorianDateTime();
                prevday.Set(d);
                d.shour += step;
                if (d.shour > 1.0)
                {
                    d.shour -= 1.0;
                    d.NextDay();
                }

                ld       = GCMath.putIn360(GCCoreAstronomy.GetSunLongitude(d, earth) - GCAyanamsha.GetAyanamsa(d.GetJulian()));
                new_rasi = GCMath.IntFloor(ld / 30.0);

                if (prev_rasi != new_rasi)
                {
                    zodiac = new_rasi;
                    //v uplynulom dni je sankranti
                    step *= 0.5;
                    d.Set(prevday);
                    count++;
                    continue;
                }
            }

            return(d);
        }
Exemplo n.º 13
0
        public static GCEquatorialCoords eclipticalToEquatorialCoords(ref GCEclipticalCoords ecc, double date)
        {
            //var
            GCEquatorialCoords eqc;

            double epsilon;
            double nutationLongitude;

            GCEarthData.CalculateNutations(date, out nutationLongitude, out epsilon);


            // formula from Chapter 21
            ecc.longitude = GCMath.putIn360(ecc.longitude + nutationLongitude);

            // formulas from Chapter 12
            eqc.rightAscension = GCMath.arcTan2Deg(GCMath.sinDeg(ecc.longitude) * GCMath.cosDeg(epsilon) - GCMath.tanDeg(ecc.latitude) * GCMath.sinDeg(epsilon),
                                                   GCMath.cosDeg(ecc.longitude));

            eqc.declination = GCMath.arcSinDeg(GCMath.sinDeg(ecc.latitude) * GCMath.cosDeg(epsilon) + GCMath.cosDeg(ecc.latitude) * GCMath.sinDeg(epsilon) * GCMath.sinDeg(ecc.longitude));

            return(eqc);
        }
Exemplo n.º 14
0
        /*********************************************************************/
        /*                                                                   */
        /* Calculation of Rasi from sun-logitude and ayanamsa                */
        /*                                                                   */
        /*********************************************************************/

        public static int GetRasi(double SunLongitude, double Ayanamsa)
        {
            return(GCMath.IntFloor(GCMath.putIn360(SunLongitude - Ayanamsa) / 30.0));
        }
Exemplo n.º 15
0
        /// <summary>
        /// This is implementation from Chapter 21, Astronomical Algorithms
        /// Nutation of longitude and Obliquity of ecliptic
        /// </summary>
        /// <param name="julianDateUTC"></param>
        /// <param name="nutationLongitude"></param>
        /// <param name="obliquity"></param>
        public static void CalculateNutations(double julianDateUTC, out double nutationLongitude, out double obliquity)
        {
            double t, omega;
            double d, m, ms, f, s, l, ls;
            int    i;
            double meanObliquity, nutationObliquity;

            t = (julianDateUTC - 2451545.0) / 36525;

            // longitude of rising knot
            omega = GCMath.putIn360(125.04452 + (-1934.136261 + (0.0020708 + 1.0 / 450000 * t) * t) * t);

            if (LowPrecisionNutations)
            {
                // (*@/// delta_phi and delta_epsilon - low accuracy *)
                //(* mean longitude of sun (l) and moon (ls) *)
                l  = 280.4665 + 36000.7698 * t;
                ls = 218.3165 + 481267.8813 * t;

                //(* correction due to nutation *)
                nutationObliquity = 9.20 * GCMath.cosDeg(omega) + 0.57 * GCMath.cosDeg(2 * l) + 0.10 * GCMath.cosDeg(2 * ls) - 0.09 * GCMath.cosDeg(2 * omega);

                //(* longitude correction due to nutation *)
                nutationLongitude = (-17.20 * GCMath.sinDeg(omega) - 1.32 * GCMath.sinDeg(2 * l) - 0.23 * GCMath.sinDeg(2 * ls) + 0.21 * GCMath.sinDeg(2 * omega)) / 3600;
            }
            else
            {
                // mean elongation of moon to sun
                d = GCMath.putIn360(297.85036 + (445267.111480 + (-0.0019142 + t / 189474) * t) * t);

                // mean anomaly of the sun
                m = GCMath.putIn360(357.52772 + (35999.050340 + (-0.0001603 - t / 300000) * t) * t);

                // mean anomaly of the moon
                ms = GCMath.putIn360(134.96298 + (477198.867398 + (0.0086972 + t / 56250) * t) * t);

                // argument of the latitude of the moon
                f = GCMath.putIn360(93.27191 + (483202.017538 + (-0.0036825 + t / 327270) * t) * t);

                nutationLongitude = 0;
                nutationObliquity = 0;

                for (i = 0; i < 31; i++)
                {
                    s = arg_mul[i, 0] * d
                        + arg_mul[i, 1] * m
                        + arg_mul[i, 2] * ms
                        + arg_mul[i, 3] * f
                        + arg_mul[i, 4] * omega;
                    nutationLongitude = nutationLongitude + (arg_phi[i, 0] + arg_phi[i, 1] * t * 0.1) * GCMath.sinDeg(s);
                    nutationObliquity = nutationObliquity + (arg_eps[i, 0] + arg_eps[i, 1] * t * 0.1) * GCMath.cosDeg(s);
                }

                nutationLongitude = nutationLongitude * 0.0001 / 3600;
                nutationObliquity = nutationObliquity * 0.0001;
            }
            // angle of ecliptic
            meanObliquity = 84381.448 + (-46.8150 + (-0.00059 + 0.001813 * t) * t) * t;

            obliquity = (meanObliquity + nutationObliquity) / 3600;
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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);
        }