Пример #1
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);
        }