public static MoonRiseResult CalculateMoonRiseSet(Coordinate coordinate, DateTime time) { int zone = TimeZone.CurrentTimeZone.ToUniversalTime(time).Hour; //1; // Math.Round(Now.getTimezoneOffset()/60); double jd = time.DtToJulianDay(); // -2451545; // Julian day relative to Jan 1.5, 2000 //if ((sgn(zone) == sgn(lon))&&(zone != 0)) // window.alert("WARNING: time zone and longitude are incompatible!"); double[,] mp = new double[3, 3]; // create a 3x3 array for (int i = 0; i < 3; i++) { //mp[i] = new Array(3); for (int j = 0; j < 3; j++) { mp[i, j] = 0.0; } } double lon = coordinate.LongitudeDeg / 360; var tz = zone / 24; var t0 = CalculateLocalSiderealTime(lon, jd, tz); // local sidereal time jd = jd + tz; // get moon position at start of day for (int k = 0; k < 3; k++) { double[] Sky = CalculateMoon(jd); mp[k, 0] = Sky[0]; mp[k, 1] = Sky[1]; mp[k, 2] = Sky[2]; jd = jd + 0.5; } if (mp[1, 0] <= mp[0, 0]) { mp[1, 0] = mp[1, 0] + 2 * Math.PI; } if (mp[2, 0] <= mp[1, 0]) { mp[2, 0] = mp[2, 0] + 2 * Math.PI; } double[] RAn = new double[3]; double[] Dec = new double[3]; double[] VHz = new double[3]; RAn[0] = mp[0, 0]; Dec[0] = mp[0, 1]; //bool Moonrise = false; // initialize //bool Moonset = false; List <MoonRiseResult> resultArray = new List <MoonRiseResult>(); for (int k = 0; k < 24; k++) // check each hour of this day { double ph = (k + 1) / 24; RAn[2] = Interpolate3values(mp[0, 0], mp[1, 0], mp[2, 0], ph); Dec[2] = Interpolate3values(mp[0, 1], mp[1, 1], mp[2, 1], ph); MoonRiseResult TestMoonHour = test_moon(time, k, zone, t0, coordinate.LatitudeDeg, mp[1, 2]); resultArray.Add(TestMoonHour); VHz[2] = TestMoonHour.Vhz; RAn[0] = RAn[2]; // advance to next hour Dec[0] = Dec[2]; VHz[0] = VHz[2]; } MoonRiseResult result = new MoonRiseResult(); foreach (var moonres in resultArray) { if (moonres.IsMoonRise) { result.IsMoonRise = true; result.RiseTime = moonres.RiseTime; result.RiseAz = moonres.RiseAz; } if (moonres.IsMoonSet) { result.IsMoonSet = true; result.SetTime = moonres.SetTime; result.SetAZ = moonres.SetAZ; } } // display results //calc.moonrise.value = zintstr(Rise_time[0], 2) + ":" + zintstr(Rise_time[1], 2) // + ", az = " + frealstr(Rise_az, 5, 1) + "°"; //calc.moonset.value = zintstr( Set_time[0], 2) + ":" + zintstr( Set_time[1], 2) // + ", az = " + frealstr(Set_az, 5, 1) + "°"; return(result); }
public static MoonRiseResult test_moon(DateTime date, double k, double zone, double t0, double lat, double plx) { MoonRiseResult result = new MoonRiseResult(); double[] ha = new double[3] { 0.0, 0.0, 0.0 }; double a, b, c, d, e, s, z; double hr, min, time; double az, hz, nz, dz; double[] RAn = new double[3]; double[] Dec = new double[3]; double[] VHz = new double[3]; double DR = Math.PI / 180; double K1 = 15 * DR * 1.0027379; if (RAn[2] < RAn[0]) { RAn[2] = RAn[2] + 2 * Math.PI; } ha[0] = t0 - RAn[0] + k * K1; ha[2] = t0 - RAn[2] + k * K1 + K1; ha[1] = (ha[2] + ha[0]) / 2; // hour angle at half hour Dec[1] = (Dec[2] + Dec[0]) / 2; // declination at half hour s = Math.Sin(DR * lat); c = Math.Cos(DR * lat); // refraction + sun semidiameter at horizon + parallax correction z = Math.Cos(DR * (90.567 - 41.685 / plx)); if (k <= 0) // first call of function { VHz[0] = s * Math.Sin(Dec[0]) + c * Math.Cos(Dec[0]) * Math.Cos(ha[0]) - z; } VHz[2] = s * Math.Sin(Dec[2]) + c * Math.Cos(Dec[2]) * Math.Cos(ha[2]) - z; if (Math.Sign(VHz[0]) == Math.Sign(VHz[2])) { result.Vhz = VHz[2]; return(result); // VHz[2]; // no event this hour } VHz[1] = s * Math.Sin(Dec[1]) + c * Math.Cos(Dec[1]) * Math.Cos(ha[1]) - z; a = 2 * VHz[2] - 4 * VHz[1] + 2 * VHz[0]; b = 4 * VHz[1] - 3 * VHz[0] - VHz[2]; d = b * b - 4 * a * VHz[0]; if (d < 0) { result.Vhz = VHz[2]; return(result); // VHz[2]; // no event this hour } d = Math.Sqrt(d); e = (-b + d) / (2 * a); if ((e > 1) || (e < 0)) { e = (-b - d) / (2 * a); } time = k + e + 1 / 120; // time of an event + round up hr = Math.Floor(time); min = Math.Floor((time - hr) * 60); hz = ha[0] + e * (ha[2] - ha[0]); // azimuth of the moon at the event nz = -Math.Cos(Dec[1]) * Math.Sin(hz); dz = c * Math.Sin(Dec[1]) - s * Math.Cos(Dec[1]) * Math.Cos(hz); az = Math.Atan2(nz, dz) / DR; if (az < 0) { az = az + 360; } if ((VHz[0] < 0) && (VHz[2] > 0)) { result.RiseTime = date.Date.AddHours(hr).AddMinutes(min); result.RiseAz = az; result.IsMoonRise = true; result.Vhz = VHz[2]; //Rise_time[0] = hr; //Rise_time[1] = min; //Rise_az = az; //Moonrise = true; } if ((VHz[0] > 0) && (VHz[2] < 0)) { result.SetTime = date.Date.AddHours(hr).AddMinutes(min); result.SetAZ = az; result.IsMoonSet = true; result.Vhz = VHz[2]; //Set_time[0] = hr; //Set_time[1] = min; //Set_az = az; //Moonset = true; } return(result); }