示例#1
0
文件: PlanetsCalc.cs 项目: t9mike/ADK
        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));
        }
示例#3
0
        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));
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <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);
                }
            }
        }
示例#10
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);
        }
示例#11
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();
                }
            }
        }