private static MoonPosition GetMoonPosition(DateTime date, double lat, double lng, Celestial cel) { //Set UTC date integrity date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc); double d = JulianConversions.GetJulian_Epoch2000(date); //Ch 47 double JDE = JulianConversions.GetJulian(date); //Get julian double T = (JDE - 2451545) / 36525; //Get dynamic time. double[] LDMNF = Get_Moon_LDMNF(T); CelCoords c = GetMoonCoords(d, cel, LDMNF, T); Distance dist = GetMoonDistance(date); double lw = rad * -lng; double phi = rad * lat; double H = rad * Get_Sidereal_Time(JDE, lw) - lw - c.ra; double ra = c.ra; //Adjust current RA formula to avoid needless RAD conversions double dec = c.dec; //Adjust current RA formula to avoid needless RAD conversions //Adjust for parallax (low accuracry increases may not be worth cost) //Investigate double pSinE = Get_pSinE(dec, dist.Meters) * Math.PI / 180; double pCosE = Get_pCosE(dec, dist.Meters) * Math.PI / 180; double cRA = Parallax_RA(dist.Meters, H, pCosE, dec, ra); double tDEC = Parallax_Dec(dist.Meters, H, pCosE, pSinE, dec, cRA); double tRA = ra - cRA; dec = tDEC; ra = tRA; //Get true altitude double h = altitude(H, phi, dec); // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. double pa = Math.Atan2(Math.Sin(H), Math.Tan(phi) * Math.Cos(dec) - Math.Sin(dec) * Math.Cos(H)); //altitude correction for refraction h = h + astroRefraction(h); MoonPosition mp = new MoonPosition(); mp.Azimuth = azimuth(H, phi, dec); mp.Altitude = h / Math.PI * 180; mp.Distance = dist; mp.ParallacticAngle = pa; double horParal = 8.794 / (dist.Meters / 149.59787E6); // horizontal parallax (arcseconds), Meeus S. 263 double p = Math.Asin(Math.Cos(h) * Math.Sin(horParal / 3600)); // parallax in altitude (degrees) p *= 1000; mp.ParallaxCorection = p; mp.Altitude *= rad; return(mp); }
static MoonPosition GetMoonPosition(DateTime date, double lat, double lng) { double d = toDays(date); CelCoords c = GetMoonCoords(d); double lw = rad * -lng; double phi = rad * lat; double H = siderealTime(d, lw) - c.ra; double h = altitude(H, phi, c.dec); // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. double pa = Math.Atan2(Math.Sin(H), Math.Tan(phi) * Math.Cos(c.dec) - Math.Sin(c.dec) * Math.Cos(H)); h = h + astroRefraction(h); // altitude correction for refraction MoonPosition mp = new MoonPosition(); mp.Azimuth = azimuth(H, phi, c.dec); mp.Altitude = h; mp.Distance = c.dist; mp.ParallacticAngle = pa; return(mp); }
/// <summary> /// Gets Moon Times, Altitude and Azimuth /// </summary> /// <param name="date">Date</param> /// <param name="lat">Latitude</param> /// <param name="lng">Longitude</param> /// <param name="c">Celestial</param> /// <param name="offset">Offset hours</param> public static void GetMoonTimes(DateTime date, double lat, double lng, Celestial c, double offset) { //Get current Moon Position to populate passed Alt / Azi for user specified date offset *= -1; //REVERSE OFFSET FOR POSITIONING //Get current moon position and coordinate MoonPosition mp = GetMoonPosition(date, lat, lng, c, offset, true); double altRad = mp.Altitude / Math.PI * 180; //Convert alt to degrees c.moonAltitude = (altRad - mp.ParallaxCorection); //Set altitude with adjusted parallax c.moonAzimuth = mp.Azimuth / Math.PI * 180 + 180; //Azimuth in degrees + 180 for E by N. ////New Iterations for Moon set / rise bool moonRise = false; bool moonSet = false; //Start at beginning of day DateTime t = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc); //Get start of day Moon Pos MoonPosition moonPos = GetMoonPosition(t, lat, lng, c, offset, false); double alt1 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); DateTime?setTime = null; DateTime?riseTime = null; double hz = -.3 * rad;//Horizon degrees at -.3 for appearant rise / set //Iterate for each hour of the day for (int x = 1; x <= 24; x++) { moonPos = GetMoonPosition(t.AddHours(x), lat, lng, c, offset, false);//Get the next hours altitude for comparison double alt2 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); //If hour 1 is below horizon and hour 2 is above if (alt1 < hz && alt2 >= hz) { //Moon Rise Occurred moonRise = true; DateTime dt1 = t.AddHours(x - 1); moonPos = GetMoonPosition(dt1, lat, lng, c, offset, false);//Get the next hours altitude for comparison double altM1 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); //Iterate through each minute to determine at which minute the horizon is crossed. //Interpolation is more efficient, but yielded results with deviations up to 5 minutes. //Investigate formula efficiency for (int y = 1; y <= 60; y++) { DateTime dt2 = t.AddHours(x - 1).AddMinutes(y); moonPos = GetMoonPosition(dt2, lat, lng, c, offset, false);//Get the next hours altitude for comparison double altM2 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); if (altM1 < hz && altM2 >= hz) { //interpolate seconds double p = 60 * ((hz - altM1) / (altM2 - altM1)); riseTime = dt1.AddMinutes(y - 1).AddSeconds(p); break; } altM1 = altM2; } } //if hour 2 is above horizon and hour 1 below if (alt1 >= hz && alt2 < hz) { //Moon Set Occurred moonSet = true; DateTime dt1 = t.AddHours(x - 1); moonPos = GetMoonPosition(dt1, lat, lng, c, offset, false);//Get the next hours altitude for comparison double altM1 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); //Iterate through each minute to determine at which minute the horizon is crossed. //Interpolation is more efficient, but yielded results with deviations up to 5 minutes. //Investigate formula efficiency for (int y = 1; y <= 60; y++) { DateTime dt2 = t.AddHours(x - 1).AddMinutes(y); moonPos = GetMoonPosition(dt2, lat, lng, c, offset, false);//Get the next hours altitude for comparison double altM2 = moonPos.Altitude - (moonPos.ParallaxCorection * rad); if (altM1 >= hz && altM2 < hz) { //Interpolate seconds double p = 60 * ((hz - altM2) / (altM1 - altM2)); setTime = dt1.AddMinutes(y).AddSeconds(-p); break; } altM1 = altM2; } } alt1 = alt2; if (moonRise && moonSet) { break; } } c.moonSet = setTime; c.moonRise = riseTime; if (moonRise && moonSet) { c.moonCondition = CelestialStatus.RiseAndSet; } else { if (!moonRise && !moonSet) { if (alt1 >= 0) { c.moonCondition = CelestialStatus.UpAllDay; } else { c.moonCondition = CelestialStatus.DownAllDay; } } if (!moonRise && moonSet) { c.moonCondition = CelestialStatus.NoRise; } if (moonRise && !moonSet) { c.moonCondition = CelestialStatus.NoSet; } } }