public GCEquatorialCoords getTopocentricEquatorial(GCEarthData obs, double jdate) { double u, h, delta_alpha; double rho_sin, rho_cos; const double b_a = 0.99664719; GCEquatorialCoords tec = new GCEquatorialCoords(); double altitude = 0; // geocentric position of observer on the earth surface // 10.1 - 10.3 u = GCMath.arcTanDeg(b_a * b_a * GCMath.tanDeg(obs.latitudeDeg)); rho_sin = b_a * GCMath.sinDeg(u) + altitude / 6378140.0 * GCMath.sinDeg(obs.latitudeDeg); rho_cos = GCMath.cosDeg(u) + altitude / 6378140.0 * GCMath.cosDeg(obs.latitudeDeg); // equatorial horizontal paralax // 39.1 double parallax = GCMath.arcSinDeg(GCMath.sinDeg(8.794 / 3600) / (radius / GCMath.AU)); // geocentric hour angle of the body h = GCEarthData.SiderealTimeGreenwich(jdate) + obs.longitudeDeg - rightAscension; // 39.2 delta_alpha = GCMath.arcTanDeg( (-rho_cos * GCMath.sinDeg(parallax) * GCMath.sinDeg(h)) / (GCMath.cosDeg(this.declination) - rho_cos * GCMath.sinDeg(parallax) * GCMath.cosDeg(h))); tec.rightAscension = rightAscension + delta_alpha; tec.declination = declination + GCMath.arcTanDeg( ((GCMath.sinDeg(declination) - rho_sin * GCMath.sinDeg(parallax)) * GCMath.cosDeg(delta_alpha)) / (GCMath.cosDeg(declination) - rho_cos * GCMath.sinDeg(parallax) * GCMath.cosDeg(h))); return(tec); }
public static GCHourTime CalcSunrise(GregorianDateTime vct, GCEarthData earth) { double tempSunrise = 180.0; GCSunData sun = new GCSunData(); for (int i = 0; i < 3; i++) { sun.SunPosition(vct, earth, tempSunrise - 180.0); double x; // definition of event double eventdef = 0.01454; /* switch(ed.obs) * { * case 1: // civil twilight * eventdef = 0.10453; * break; * case 2: // nautical twilight * eventdef = 0.20791; * break; * case 3: // astronomical twilight * eventdef = 0.30902; * break; * default:// center of the sun on the horizont * eventdef = 0.01454; * break; * }*/ eventdef = (eventdef / GCMath.cosDeg(earth.latitudeDeg)) / GCMath.cosDeg(sun.declinationDeg); x = GCMath.tanDeg(earth.latitudeDeg) * GCMath.tanDeg(sun.declinationDeg) + eventdef; if ((x >= -1.0) && (x <= 1.0)) { // time of sunrise tempSunrise = 90.0 - earth.longitudeDeg - GCMath.arcSinDeg(x) + sun.equationOfTime; } else { // initial values for the case // that no rise no set for that day tempSunrise = -360.0; break; } } GCHourTime result = new GCHourTime(); result.longitude = sun.longitudeDeg; result.SetDegTime(tempSunrise + earth.OffsetUtcHours * 15.0); return(result); }
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); }
public static GCHourTime CalcSunset(GregorianDateTime vct, GCEarthData earth) { double tempSunset = 180.0; GCSunData sun = new GCSunData(); for (int i = 0; i < 3; i++) { sun.SunPosition(vct, earth, tempSunset - 180.0); double x; // definition of event double eventdef = GCSunData.RiseAngleLevel; eventdef = (eventdef / GCMath.cosDeg(earth.latitudeDeg)) / GCMath.cosDeg(sun.declinationDeg); x = GCMath.tanDeg(earth.latitudeDeg) * GCMath.tanDeg(sun.declinationDeg) + eventdef; if ((x >= -1.0) && (x <= 1.0)) { // time of sunset tempSunset = 270.0 - earth.longitudeDeg + GCMath.arcSinDeg(x) + sun.equationOfTime; } else { // initial values for the case // that no rise no set for that day tempSunset = -360.0; break; } } GCHourTime result = new GCHourTime(); result.longitude = sun.longitudeDeg; result.SetDegTime(tempSunset + earth.OffsetUtcHours * 15.0); return(result); }
public void CorrectEqatorialWithParallax(double jdate, double latitude, double longitude, double height) { double u, hourAngleBody, delta_alpha; double rho_sin, rho_cos; const double b_a = 0.99664719; // calculate geocentric longitude and latitude of observer u = GCMath.arcTanDeg(b_a * b_a * GCMath.tanDeg(latitude)); rho_sin = b_a * GCMath.sinDeg(u) + height / 6378140.0 * GCMath.sinDeg(latitude); rho_cos = GCMath.cosDeg(u) + height / 6378140.0 * GCMath.cosDeg(latitude); // calculate paralax this.parallax = GCMath.arcSinDeg(GCMath.sinDeg(8.794 / 3600) / (MoonDistance(jdate) / GCMath.AU)); // calculate correction of equatorial coordinates hourAngleBody = GCEarthData.SiderealTimeGreenwich(jdate) + longitude - this.rightAscension; delta_alpha = GCMath.arcTan2Deg(-rho_cos * GCMath.sinDeg(this.parallax) * GCMath.sinDeg(hourAngleBody), GCMath.cosDeg(this.declination) - rho_cos * GCMath.sinDeg(this.parallax) * GCMath.cosDeg(hourAngleBody)); this.rightAscension += delta_alpha; this.declination += GCMath.arcTan2Deg( (GCMath.sinDeg(this.declination) - rho_sin * GCMath.sinDeg(this.parallax)) * GCMath.cosDeg(delta_alpha), GCMath.cosDeg(this.declination) - rho_cos * GCMath.sinDeg(this.parallax) * GCMath.cosDeg(hourAngleBody)); }
// 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); }