/// <summary> /// Gets rectangular heliocentric coordinates of minor body /// </summary> protected CrdsRectangular RectangularH(SkyContext c, T body) { // final difference to stop iteration process, 1 second of time double deltaTau = TimeSpan.FromSeconds(1).TotalDays; // time taken by the light to reach the Earth double tau = 0; // previous value of tau to calculate the difference double tau0 = 1; // Rectangular coordinates of minor body CrdsRectangular rect = null; // Rectangular coordinates of the Sun var sun = c.Get(SunRectangular); // Orbital elements var orbit = c.Get(OrbitalElements, body); double ksi = 0, eta = 0, zeta = 0, Delta = 0; int count = 0; // Iterative process to find rectangular coordinates of minor body while (Math.Abs(tau - tau0) > deltaTau && count++ < 100) { // Rectangular coordinates of minor body rect = MinorBodyPositions.GetRectangularCoordinates(orbit, c.JulianDay - tau, c.Epsilon); ksi = sun.X + rect.X; eta = sun.Y + rect.Y; zeta = sun.Z + rect.Z; // Distance to the Earth Delta = Math.Sqrt(ksi * ksi + eta * eta + zeta * zeta); tau0 = tau; tau = PlanetPositions.LightTimeEffect(Delta); } return(rect); }
private void DoTest(CrdsGeographical location, OrbitalElements oe, string testData, double errorR, double errorEq) { Regex regex = new Regex("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+ \\S+ \\S+) (\\S+ \\S+ \\S+)$"); string[] lines = testData.Split('\n'); foreach (string line in lines) { string dataLine = line.Trim(); if (!string.IsNullOrEmpty(dataLine)) { var match = regex.Match(dataLine); double jd = double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture); double X = double.Parse(match.Groups[2].Value, CultureInfo.InvariantCulture); double Y = double.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture); double Z = double.Parse(match.Groups[4].Value, CultureInfo.InvariantCulture); string ra = match.Groups[5].Value; string dec = match.Groups[6].Value; var eqTest = new CrdsEquatorial(new HMS(ra), new DMS(dec)); var nutation = Nutation.NutationElements(jd); var aberration = Aberration.AberrationElements(jd); // True obliquity double epsilon = Date.TrueObliquity(jd, nutation.deltaEpsilon); // final difference to stop iteration process, 1 second of time double deltaTau = TimeSpan.FromSeconds(1).TotalDays; // time taken by the light to reach the Earth double tau = 0; // previous value of tau to calculate the difference double tau0 = 1; // Rectangular coordinates of minor body CrdsRectangular r = null; // Rectangular coordinates of the Sun var sun = SunRectangular(jd, epsilon); // Distance to the Earth double Delta = 0; // Iterative process to find rectangular coordinates of minor body while (Math.Abs(tau - tau0) > deltaTau) { // Rectangular coordinates of minor body r = MinorBodyPositions.GetRectangularCoordinates(oe, jd - tau, epsilon); double ksi = sun.X + r.X; double eta = sun.Y + r.Y; double zeta = sun.Z + r.Z; // Distance to the Earth Delta = Math.Sqrt(ksi * ksi + eta * eta + zeta * zeta); tau0 = tau; tau = PlanetPositions.LightTimeEffect(Delta); } // Test heliocentric rectangular coordinates Assert.AreEqual(X, r.X, errorR); Assert.AreEqual(Y, r.Y, errorR); Assert.AreEqual(Z, r.Z, errorR); double x = sun.X + r.X; double y = sun.Y + r.Y; double z = sun.Z + r.Z; double alpha = Angle.ToDegrees(Math.Atan2(y, x)); double delta = Angle.ToDegrees(Math.Asin(z / Delta)); var eq0 = new CrdsEquatorial(alpha, delta); var theta0 = Date.ApparentSiderealTime(jd, nutation.deltaPsi, epsilon); var parallax = PlanetEphem.Parallax(Delta); var eq = eq0.ToTopocentric(location, theta0, parallax); // Test equatorial coordinates Assert.AreEqual(eqTest.Alpha, eq.Alpha, errorEq / 3600.0); Assert.AreEqual(eqTest.Delta, eq.Delta, errorEq / 3600.0); } } }