private double JupiterMoonCentralMeridian(SkyContext c, int m) { // planetocentric rectangular coordinates of the moon CrdsRectangular r = c.Get(JupiterMoonRectangular, m); return(GalileanMoons.MoonCentralMeridian(r, m - 1)); }
private CrdsEquatorial JupiterMoon_Equatorial(SkyContext c, int m) { CrdsEquatorial jupiterEq = c.Get(Planet_Equatorial, Planet.JUPITER); CrdsRectangular planetocentric = c.Get(JupiterMoon_Rectangular, m); PlanetAppearance appearance = c.Get(Planet_Appearance, Planet.JUPITER); double semidiameter = c.Get(Planet_Semidiameter, Planet.JUPITER); return(planetocentric.ToEquatorial(jupiterEq, appearance.P, semidiameter)); }
private CrdsEquatorial SaturnMoon_Equatorial(SkyContext c, int m) { CrdsEquatorial saturnEq = c.Get(Planet_Equatorial, Planet.SATURN); CrdsRectangular planetocentric = c.Get(SaturnMoon_Rectangular, m); PlanetAppearance appearance = c.Get(Planet_Appearance, Planet.SATURN); double semidiameter = c.Get(Planet_Semidiameter, Planet.SATURN); return(planetocentric.ToEquatorial(saturnEq, appearance.P, semidiameter)); }
public void EclipticalToRectangular() { CrdsEcliptical ecl = new CrdsEcliptical(199.907347, 0.62 / 3600.0, 0.99760775); CrdsRectangular rect = ecl.ToRectangular(23.4402297); Assert.AreEqual(-0.9379952, rect.X, 1e-7); Assert.AreEqual(-0.3116544, rect.Y, 1e-7); Assert.AreEqual(-0.1351215, rect.Z, 1e-7); }
/// <summary> /// Calculates Sun rectangular coordinates for J2000 epoch /// </summary> private CrdsRectangular Sun_RectangularJ2000(SkyContext c) { // Heliocentrical coordinates of Earth CrdsHeliocentrical hEarth = c.Get(Earth_HeliocentricalJ2000); // transform to ecliptical coordinates of the Sun CrdsEcliptical eclSun = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R); // Sun rectangular coordinates, J2000.0 epoch CrdsRectangular rSun = eclSun.ToRectangular(epsilonJ2000); return(rSun); }
/// <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); }
/// <summary> /// Calculates heliocentrical coordinates of Pluto for J2000 epoch /// </summary> private CrdsHeliocentrical Pluto_HeliocentricalJ2000(SkyContext c) { // 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; // Sun rectangular coordinates, J2000.0 epoch CrdsRectangular rSun = c.Get(Sun_RectangularJ2000); // Heliocentrical coordinates of Pluto CrdsHeliocentrical plutoHeliocentrial = null; // Iterative process to find heliocentrical coordinates of planet while (Math.Abs(tau - tau0) > deltaTau) { // Heliocentrical coordinates of Pluto plutoHeliocentrial = PlutoPosition.Position(c.JulianDay - tau); // Rectangular heliocentrical coordinates of Pluto CrdsRectangular rPluto = new CrdsEcliptical(plutoHeliocentrial.L, plutoHeliocentrial.B, plutoHeliocentrial.R).ToRectangular(epsilonJ2000); double x = rPluto.X + rSun.X; double y = rPluto.Y + rSun.Y; double z = rPluto.Z + rSun.Z; double dist = Math.Sqrt(x * x + y * y + z * z); tau0 = tau; tau = PlanetPositions.LightTimeEffect(dist); } return(plutoHeliocentrial); }
private double JupiterMoon_CentralMeridian(SkyContext c, int m) { CrdsRectangular r = c.Get(JupiterMoon_Rectangular, m); return(GalileanMoons.MoonCentralMeridian(r)); }
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); } } }
public void Position() { // Mean obliquity of the ecliptic for J2000.0 epoch const double epsilonJ2000 = 23.4392912510; double jd = 2448908.5; double tau = 0; double tau0 = 1; int iteration = 1; // final difference to stop iteration process, 1 second of time double deltaTau = TimeSpan.FromSeconds(1).TotalDays; CrdsHeliocentrical posPluto = null; CrdsHeliocentrical hEarth = null; while (Math.Abs(tau - tau0) > deltaTau) { posPluto = PlutoPosition.Position(jd - tau); if (iteration == 1) { Assert.AreEqual(232.74071, posPluto.L, 1e-5); Assert.AreEqual(14.58782, posPluto.B, 1e-5); Assert.AreEqual(29.711111, posPluto.R, 1e-6); } else if (iteration == 2) { Assert.AreEqual(232.73949, posPluto.L, 1e-5); Assert.AreEqual(14.58801, posPluto.B, 1e-5); Assert.AreEqual(29.711094, posPluto.R, 1e-6); } // get Earth coordinates hEarth = PlanetPositions.GetPlanetCoordinates(3, jd, highPrecision: false, epochOfDate: false); // transform to ecliptical coordinates of the Sun CrdsEcliptical eclSun = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R); CrdsRectangular rSun = eclSun.ToRectangular(epsilonJ2000); if (iteration == 1) { Assert.AreEqual(-0.9373959, rSun.X, 1e-6); Assert.AreEqual(-0.3131679, rSun.Y, 1e-6); Assert.AreEqual(-0.1357792, rSun.Z, 1e-6); } var rPluto = new CrdsEcliptical(posPluto.L, posPluto.B, posPluto.R).ToRectangular(epsilonJ2000); if (iteration == 1) { Assert.AreEqual(-17.4079141, rPluto.X, 1e-5); Assert.AreEqual(-23.9730804, rPluto.Y, 1e-5); Assert.AreEqual(-2.2374228, rPluto.Z, 1e-5); } else if (iteration == 2) { Assert.AreEqual(-17.4083780, rPluto.X, 1e-5); Assert.AreEqual(-23.9727452, rPluto.Y, 1e-5); Assert.AreEqual(-2.2371797, rPluto.Z, 1e-5); } double x = rPluto.X + rSun.X; double y = rPluto.Y + rSun.Y; double z = rPluto.Z + rSun.Z; double dist = Math.Sqrt(x * x + y * y + z * z); if (iteration == 1) { Assert.AreEqual(30.528746, dist, 1e-5); } else if (iteration == 2) { Assert.AreEqual(30.528739, dist, 1e-5); } tau0 = tau; tau = PlanetPositions.LightTimeEffect(dist); if (iteration == 1 || iteration == 2) { Assert.AreEqual(0.17632, tau, 1e-5); } iteration++; } // should be only 2 iterations Assert.AreEqual(2, iteration - 1); // ecliptical coordinates of Pluto, J2000.0 epoch var eclPluto = posPluto.ToRectangular(hEarth).ToEcliptical(); // geocentric astrometric equatorial coordinates of Pluto, J2000.0 epoch var eqPluto2000 = eclPluto.ToEquatorial(epsilonJ2000); // check coordinates with possible error with 1 arcsecond Assert.AreEqual(new HMS("15h 31m 43.8s").ToDecimalAngle(), eqPluto2000.Alpha, 1 / 3600.0); Assert.AreEqual(new DMS("-4* 27' 29''").ToDecimalAngle(), eqPluto2000.Delta, 1 / 3600.0); }
private void RenderJupiterMoonShadow(IMapContext map, SizeableCelestialObject eclipsedBody, CrdsRectangular rect = null) { if (rect == null) { rect = new CrdsRectangular(); } // collect moons than can produce a shadow var ecliptingMoons = planetsCalc.JupiterMoons.Where(m => m.RectangularS.Z < rect.Z); if (ecliptingMoons.Any()) { Planet jupiter = planetsCalc.Planets.ElementAt(Planet.JUPITER - 1); float rotation = map.GetRotationTowardsNorth(jupiter.Equatorial) + 360 - (float)jupiter.Appearance.P; // Jupiter radius, in pixels float sd = map.GetDiskSize(jupiter.Semidiameter) / 2; // Center of eclipsed body PointF pBody = map.Project(eclipsedBody.Horizontal); // elipsed body size, in pixels float szB = map.GetDiskSize(eclipsedBody.Semidiameter); foreach (var moon in ecliptingMoons) { // umbra and penumbra radii, in acrseconds var shadow = GalileanMoons.Shadow(jupiter.Ecliptical.Distance, jupiter.DistanceFromSun, moon.Number - 1, moon.RectangularS, rect); // umbra and penumbra size, in pixels float szU = map.GetDiskSize(shadow.Umbra); float szP = map.GetDiskSize(shadow.Penumbra); // coordinates of shadow relative to eclipsed body CrdsRectangular shadowRelative = moon.RectangularS - rect; // Center of shadow PointF p = new PointF((float)shadowRelative.X * sd, -(float)shadowRelative.Y * sd); map.Graphics.TranslateTransform(pBody.X, pBody.Y); map.Graphics.RotateTransform(rotation); // shadow has enough size to be rendered if ((int)szP > 0) { var gpB = new GraphicsPath(); var gpP = new GraphicsPath(); var gpU = new GraphicsPath(); gpU.AddEllipse(p.X - szU / 2, p.Y - szU / 2, szU, szU); gpP.AddEllipse(p.X - szP / 2, p.Y - szP / 2, szP, szP); gpB.AddEllipse(-szB / 2 - 0.5f, -szB / 2 - 0.5f, szB + 1, szB + 1); var regionP = new Region(gpP); regionP.Intersect(gpB); if (!regionP.IsEmpty(map.Graphics)) { float f1 = 1 - (szU + szP) / 2 / szP; float f2 = 1 - szU / szP; var brushP = new PathGradientBrush(gpP); brushP.CenterPoint = p; brushP.CenterColor = clrJupiterMoonShadowLight; brushP.InterpolationColors = new ColorBlend() { Colors = new[] { Color.Transparent, clrJupiterMoonShadowDark, clrJupiterMoonShadowLight, clrJupiterMoonShadowLight }, Positions = new float[] { 0, f1, f2, 1 } }; var regionU = new Region(gpU); regionU.Intersect(gpB); var brushU = new SolidBrush(clrJupiterMoonShadowLight); map.Graphics.FillRegion(brushP, regionP); map.Graphics.FillRegion(brushU, regionU); // outline circles if (settings.Get <bool>("JupiterMoonsShadowOutline") && szP > 20) { map.Graphics.DrawEllipse(penShadowOutline, p.X - (szP + szU) / 4, p.Y - (szP + szU) / 4, (szP + szU) / 2, (szP + szU) / 2); map.Graphics.DrawEllipse(penShadowOutline, p.X - szU / 2, p.Y - szU / 2, szU, szU); PointF[] points = new PointF[] { new PointF(p.X, p.Y) }; map.Graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, points); map.Graphics.ResetTransform(); map.DrawObjectCaption(fontShadowLabel, brushShadowLabel, moon.ShadowName, points[0], szP); } } } map.Graphics.ResetTransform(); } } }