//////////////////////////////////////////////////////////////// // // 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)); }
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); }
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); }
/*********************************************************************/ /* */ /* 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); }
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); }
/// <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)); }
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))); }
//================================================================================== // //================================================================================== 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))); }
/// <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))); }
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); }
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; } }
/*********************************************************************/ /* 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); }
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); }
/*********************************************************************/ /* */ /* 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)); }
/// <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; }
/////////////////////////////////////////////////////////////////////// // 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); }
// 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); }