Пример #1
0
        /// <summary>
        /// Gets heliocentrical coordinates of planet
        /// </summary>
        private CrdsHeliocentrical Planet_Heliocentrical(SkyContext c, int p)
        {
            // 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;

            // Heliocentrical coordinates of planet
            CrdsHeliocentrical planetHeliocentrial = null;

            // Heliocentrical coordinates of Earth
            CrdsHeliocentrical hEarth = c.Get(Earth_Heliocentrial);

            // Iterative process to find heliocentrical coordinates of planet
            while (Math.Abs(tau - tau0) > deltaTau)
            {
                // Heliocentrical coordinates of planet
                planetHeliocentrial = PlanetPositions.GetPlanetCoordinates(p, c.JulianDay - tau, !c.PreferFastCalculation);

                // Ecliptical coordinates of planet
                var planetEcliptical = planetHeliocentrial.ToRectangular(hEarth).ToEcliptical();

                tau0 = tau;
                tau  = PlanetPositions.LightTimeEffect(planetEcliptical.Distance);
            }

            return(planetHeliocentrial);
        }
Пример #2
0
        public void GetSolarCoordinatesLP()
        {
            double jde = 2448908.5;

            // get Earth coordinates
            CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(Planet.Earth, jde, highPrecision: false);

            Assert.AreEqual(19.907372, crds.L, 1e-6);
            Assert.AreEqual(-0.644, crds.B * 3600, 1e-3);
            Assert.AreEqual(0.99760775, crds.R, 1e-8);

            // transform to ecliptical coordinates of the Sun
            CrdsEcliptical ecl = new CrdsEcliptical(Angle.To360(crds.L + 180), -crds.B, crds.R);

            // get FK5 system correction
            CrdsEcliptical corr = PlanetPositions.CorrectionForFK5(jde, ecl);

            Assert.AreEqual(-0.09033, corr.Lambda * 3600, 1e-5);
            Assert.AreEqual(-0.023, corr.Beta * 3600, 1e-3);

            // correct solar coordinates to FK5 system
            ecl += corr;

            Assert.AreEqual(199.907347, ecl.Lambda, 1e-6);
            Assert.AreEqual(0.62, ecl.Beta * 3600, 1e-2);
            Assert.AreEqual(0.99760775, ecl.Distance, 1e-8);

            var nutation = Nutation.NutationElements(jde);

            // True obliquity
            double epsilon = Date.TrueObliquity(jde, nutation.deltaEpsilon);

            // accuracy is 0.5"
            Assert.AreEqual(15.908, nutation.deltaPsi * 3600, 0.5);

            // accuracyis 0.1"
            Assert.AreEqual(-0.308, nutation.deltaEpsilon * 3600, 0.1);

            // accuracy is 0.1"
            Assert.AreEqual(23.4401443, epsilon, 0.1 / 3600.0);

            // add nutation effect
            ecl += Nutation.NutationEffect(nutation.deltaPsi);

            // calculate aberration effect
            CrdsEcliptical aberration = Aberration.AberrationEffect(ecl.Distance);

            Assert.AreEqual(-20.539, aberration.Lambda * 3600.0, 1e-3);

            // add aberration effect
            ecl += aberration;

            // convert ecliptical to equatorial coordinates
            CrdsEquatorial eq = ecl.ToEquatorial(epsilon);

            // check apparent equatorial coordinates
            // assume an accuracy of 0.5'' is sufficient
            Assert.AreEqual(198.378178, eq.Alpha, 1.0 / 3600 * 0.5);
            Assert.AreEqual(-7.783871, eq.Delta, 1.0 / 3600 * 0.5);
        }
Пример #3
0
        public void GetPlanetCoordinatesLP()
        {
            // Example 32.a from AA
            {
                CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(Planet.Venus, 2448976.5, highPrecision: false);
                Assert.AreEqual(26.11428, crds.L, 1e-5);
                Assert.AreEqual(-2.62070, crds.B, 1e-5);
                Assert.AreEqual(0.724603, crds.R, 1e-6);
            }

            // Test low-precision implementation from AA2 book
            foreach (VSOP87DTestData testValue in testData)
            {
                CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(testValue.Planet, testValue.JDE, highPrecision: false);

                double deltaL = Math.Abs(testValue.L - crds.L) * SECONDS_IN_DEGREE;
                double deltaB = Math.Abs(testValue.B - crds.B) * SECONDS_IN_DEGREE;
                double deltaR = Math.Abs(testValue.R - crds.R);

                // difference in L should be less than 4" of arc
                Assert.IsTrue(deltaL < 4);

                // difference in B should be less than 4" of arc
                Assert.IsTrue(deltaB < 4);

                // difference in R should be less than 1e-3 AU
                Assert.IsTrue(deltaR < 1e-3);
            }
        }
Пример #4
0
        public void CalculatePlanetApparentPlaceLP()
        {
            double jde = 2448976.5;

            double         tau = 0;
            CrdsEcliptical ecl = null;

            for (int i = 0; i < 2; i++)
            {
                CrdsHeliocentrical hEarth = PlanetPositions.GetPlanetCoordinates(3, jde - tau, highPrecision: false);

                CrdsHeliocentrical hVenus = PlanetPositions.GetPlanetCoordinates(2, jde - tau, highPrecision: false);

                var rect = hVenus.ToRectangular(hEarth);

                ecl = rect.ToEcliptical();

                tau = PlanetPositions.LightTimeEffect(ecl.Distance);
            }

            // Correction for FK5 system
            CrdsEcliptical corr = PlanetPositions.CorrectionForFK5(jde, ecl);

            ecl += corr;
            ecl += Nutation.NutationEffect(16.749 / 3600.0);

            CrdsEquatorial eq = ecl.ToEquatorial(23.439669);

            Assert.AreEqual(new HMS("21h 04m 41.459s"), new HMS(eq.Alpha));
            Assert.AreEqual(new DMS("-18* 53' 16.66''"), new DMS(eq.Delta));
        }
Пример #5
0
        /// <summary>
        /// Gets ecliptical coordinates of Sun for J2000.0 epoch
        /// </summary>
        private CrdsEcliptical SunEcliptical(SkyContext c)
        {
            CrdsHeliocentrical hEarth = PlanetPositions.GetPlanetCoordinates(3, c.JulianDay, !c.PreferFastCalculation, false);

            var eSun = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R);

            // Corrected solar coordinates to FK5 system
            // NO correction for nutation and aberration should be performed here (ch. 26, p. 171)
            eSun += PlanetPositions.CorrectionForFK5(c.JulianDay, eSun);

            return(eSun);
        }
        private CrdsEcliptical UranusMoon_Ecliptical(SkyContext c, int m)
        {
            var ecliptical = c.Get(UranusMoons_Positions)[m - 1].ToEcliptical();

            // Correction for FK5 system
            ecliptical += PlanetPositions.CorrectionForFK5(c.JulianDay, ecliptical);

            // Take nutation into account
            ecliptical += Nutation.NutationEffect(c.NutationElements.deltaPsi);

            return(ecliptical);
        }
        private CrdsRectangular SunRectangular(double jd, double epsilon)
        {
            CrdsHeliocentrical hEarth = PlanetPositions.GetPlanetCoordinates(3, jd, true, false);

            var eSun = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R);

            // Corrected solar coordinates to FK5 system
            // NO correction for nutation and aberration should be performed here (ch. 26, p. 171)
            eSun += PlanetPositions.CorrectionForFK5(jd, eSun);

            return(eSun.ToRectangular(epsilon));
        }
Пример #8
0
        public void SaturnRings()
        {
            double jd = 2448972.5 + 0.00068;

            CrdsHeliocentrical earth  = PlanetPositions.GetPlanetCoordinates(3, jd, true);
            CrdsHeliocentrical saturn = PlanetPositions.GetPlanetCoordinates(6, jd, true);

            RingsAppearance rings = PlanetEphem.SaturnRings(jd, saturn, earth, 23.43971);

            Assert.AreEqual(35.87, rings.a, 1e-2);
            Assert.AreEqual(10.15, rings.b, 1e-2);
            Assert.AreEqual(16.442, rings.B, 1e-3);
            Assert.AreEqual(4.198, rings.DeltaU, 1e-3);
            Assert.AreEqual(6.741, rings.P, 1e-3);
        }
Пример #9
0
 public Dictionary <string, object> ToDictionary(int day)
 {
     return(new Dictionary <string, object> {
         ["id"] = $"{day + 1}",
         ["day"] = day,
         ["weather"] = Weather,
         ["trianglePerimeter"] = TrianglePerimeter,
         ["planetPositions"] = PlanetPositions.ToDictionary(p => p.Key, p => new { x = p.Value.X, y = p.Value.Y }),
         ["planets"] = Planets.Select(p => new {
             name = p.Name,
             speedDegPerDay = p.SpeedDegPerDay,
             distanceToSunInKm = p.DistanceToSunInKm,
             isClockWiseRotation = p.IsClockWiseRotation
         }).ToList()
     });
 }
Пример #10
0
        /// <summary>
        /// Gets ecliptical coordinates of Sun
        /// </summary>
        public CrdsEcliptical Sun_Ecliptical(SkyContext c)
        {
            CrdsHeliocentrical hEarth = c.Get(Earth_Heliocentrial);
            var sunEcliptical         = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R);

            // Corrected solar coordinates to FK5 system
            sunEcliptical += PlanetPositions.CorrectionForFK5(c.JulianDay, sunEcliptical);

            // Add nutation effect to ecliptical coordinates of the Sun
            sunEcliptical += Nutation.NutationEffect(c.NutationElements.deltaPsi);

            // Add aberration effect, so we have an final ecliptical coordinates of the Sun
            sunEcliptical += Aberration.AberrationEffect(sunEcliptical.Distance);

            return(sunEcliptical);
        }
Пример #11
0
        public void CalculatePlanetApparentPlaceHP()
        {
            double jde = 2448976.5;

            // time taken by the light to reach the Earth
            double tau = 0;

            // previous value of tau to calculate the difference
            double tau0 = 1;

            // final difference to stop iteration process, 1 second of time
            double deltaTau = TimeSpan.FromSeconds(1).TotalDays;

            // Ecliptical coordinates of Venus
            CrdsEcliptical ecl = null;

            // Iterative process to find ecliptical coordinates of Venus
            while (Math.Abs(tau - tau0) > deltaTau)
            {
                // Heliocentrical coordinates of Earth
                var hEarth = PlanetPositions.GetPlanetCoordinates(3, jde - tau, highPrecision: true);

                // Heliocentrical coordinates of Venus
                var hVenus = PlanetPositions.GetPlanetCoordinates(2, jde - tau, highPrecision: true);

                // Ecliptical coordinates of Venus
                ecl = hVenus.ToRectangular(hEarth).ToEcliptical();

                tau0 = tau;
                tau  = PlanetPositions.LightTimeEffect(ecl.Distance);
            }

            // Correction for FK5 system
            ecl += PlanetPositions.CorrectionForFK5(jde, ecl);

            // Take nutation into account
            ecl += Nutation.NutationEffect(16.749 / 3600.0);

            // Apparent equatorial coordinates of Venus
            CrdsEquatorial eq = ecl.ToEquatorial(23.439669);

            Assert.AreEqual(new HMS("21h 04m 41.454s"), new HMS(eq.Alpha));
            Assert.AreEqual(new DMS("-18* 53' 16.84''"), new DMS(eq.Delta));
        }
Пример #12
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);
        }
Пример #13
0
        /// <summary>
        /// Gets ecliptical coordinates of planet
        /// </summary>
        public CrdsEcliptical Planet_Ecliptical(SkyContext c, int p)
        {
            // Heliocentrical coordinates of planet
            CrdsHeliocentrical heliocentrical = c.Get(Planet_Heliocentrical, p);

            // Heliocentrical coordinates of Earth
            CrdsHeliocentrical hEarth = c.Get(Earth_Heliocentrial);

            // Ecliptical coordinates of planet
            var ecliptical = heliocentrical.ToRectangular(hEarth).ToEcliptical();

            // Correction for FK5 system
            ecliptical += PlanetPositions.CorrectionForFK5(c.JulianDay, ecliptical);

            // Take nutation into account
            ecliptical += Nutation.NutationEffect(c.NutationElements.deltaPsi);

            return(ecliptical);
        }
Пример #14
0
        /// <summary>
        /// Gets apparent geocentrical ecliptical coordinates of the Sun
        /// </summary>
        private CrdsEcliptical SunEcliptical(SkyContext c)
        {
            // get Earth coordinates
            CrdsHeliocentrical hEarth = c.Get(EarthHeliocentrical);

            // transform to ecliptical coordinates of the Sun
            CrdsEcliptical sunEcliptical = new CrdsEcliptical(Angle.To360(hEarth.L + 180), -hEarth.B, hEarth.R);

            // correct solar coordinates to FK5 system
            sunEcliptical += PlanetPositions.CorrectionForFK5(c.JulianDay, sunEcliptical);

            // add nutation effect to ecliptical coordinates of the Sun
            sunEcliptical += Nutation.NutationEffect(c.NutationElements.deltaPsi);

            // add aberration effect, so we have an final ecliptical coordinates of the Sun
            sunEcliptical += Aberration.AberrationEffect(sunEcliptical.Distance);

            return(sunEcliptical);
        }
Пример #15
0
        public void GetPlanetCoordinatesHP()
        {
            // Test high-precision implementation from original VSOP87 theory.
            foreach (VSOP87DTestData testValue in testData)
            {
                CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(testValue.Planet, testValue.JDE, highPrecision: true, epochOfDate: testValue.IsEpochOfDate);

                double deltaL = Math.Abs(testValue.L - crds.L) * SECONDS_IN_DEGREE;
                double deltaB = Math.Abs(testValue.B - crds.B) * SECONDS_IN_DEGREE;
                double deltaR = Math.Abs(testValue.R - crds.R);

                // difference in L should be less than 1" of arc
                Assert.IsTrue(deltaL < 1);

                // difference in B should be less than 1" of arc
                Assert.IsTrue(deltaB < 1);

                // difference in R should be less than 1e-5 AU
                Assert.IsTrue(deltaR < 1e-5);
            }
        }
Пример #16
0
        public CrdsEcliptical Ecliptical(SkyContext c)
        {
            // get Earth coordinates
            CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(Planet.EARTH, c.JulianDay, highPrecision: true);

            // transform to ecliptical coordinates of the Sun
            var ecl = new CrdsEcliptical(Angle.To360(crds.L + 180), -crds.B, crds.R);

            // get FK5 system correction
            CrdsEcliptical corr = PlanetPositions.CorrectionForFK5(c.JulianDay, ecl);

            // correct solar coordinates to FK5 system
            ecl += corr;

            // add nutation effect
            ecl += Nutation.NutationEffect(c.NutationElements.deltaPsi);

            // add aberration effect
            ecl += Aberration.AberrationEffect(ecl.Distance);

            return(ecl);
        }
Пример #17
0
        public void GetSolarCoordinatesLP()
        {
            double jde = 2448908.5;

            // get Earth coordinates
            CrdsHeliocentrical crds = PlanetPositions.GetPlanetCoordinates(3, jde, highPrecision: false);

            // transform to ecliptical coordinates of the Sun
            CrdsEcliptical ecl = new CrdsEcliptical(Angle.To360(crds.L + 180), -crds.B, crds.R);

            // get FK5 system correction
            CrdsEcliptical corr = PlanetPositions.CorrectionForFK5(jde, ecl);

            // correct solar coordinates to FK5 system
            ecl += corr;

            var nutation = Nutation.NutationElements(jde);

            // True obliquity
            double epsilon = Date.TrueObliquity(jde, nutation.deltaEpsilon);

            // add nutation effect
            ecl += Nutation.NutationEffect(nutation.deltaPsi);

            // calculate aberration effect
            CrdsEcliptical aberration = Aberration.AberrationEffect(ecl.Distance);

            // add aberration effect
            ecl += aberration;

            // convert ecliptical to equatorial coordinates
            CrdsEquatorial eq = ecl.ToEquatorial(epsilon);

            // check apparent equatorial coordinates
            // assume an accuracy of 0.5'' is sufficient
            Assert.AreEqual(198.378178, eq.Alpha, 1.0 / 3600 * 0.5);
            Assert.AreEqual(-7.783871, eq.Delta, 1.0 / 3600 * 0.5);
        }
Пример #18
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);
        }
Пример #19
0
        public async Task SetDate(Date date, CrdsGeographical geoLocation)
        {
            await Task.Run(() =>
            {
                double jd0  = date.ToJulianEphemerisDay();
                daysInMonth = Date.DaysInMonth(date.Year, date.Month);

                var eL = new PointF[5];
                var eB = new PointF[5];
                var eR = new PointF[5];
                var jL = new PointF[5];
                var jB = new PointF[5];
                var jR = new PointF[5];

                var earth   = new CrdsHeliocentrical[5];
                var jupiter = new CrdsHeliocentrical[5];

                // calculate heliocentrical positions of Earth and Jupiter for 5 instants
                // and find least squares approximation model of planets position
                // to quick calculation of Galilean moons postions.
                for (int i = 0; i < 5; i++)
                {
                    double jd  = jd0 + (i / 4.0) * daysInMonth;
                    earth[i]   = PlanetPositions.GetPlanetCoordinates(3, jd);
                    jupiter[i] = PlanetPositions.GetPlanetCoordinates(5, jd);
                }

                double[] earthL = earth.Select(x => x.L).ToArray();
                double[] earthB = earth.Select(x => x.B).ToArray();
                double[] earthR = earth.Select(x => x.R).ToArray();

                double[] jupiterL = jupiter.Select(x => x.L).ToArray();
                double[] jupiterB = jupiter.Select(x => x.B).ToArray();
                double[] jupiterR = jupiter.Select(x => x.R).ToArray();

                // it's important to align longitudes (avoid 0 degrees crossing)
                // before applying least squares method
                earthL   = Angle.Align(earthL);
                jupiterL = Angle.Align(jupiterL);

                for (int i = 0; i < 5; i++)
                {
                    eL[i] = new PointF(i, (float)earthL[i]);
                    eB[i] = new PointF(i, (float)earthB[i]);
                    eR[i] = new PointF(i, (float)earthR[i]);
                    jL[i] = new PointF(i, (float)jupiterL[i]);
                    jB[i] = new PointF(i, (float)jupiterB[i]);
                    jR[i] = new PointF(i, (float)jupiterR[i]);
                }

                Begin       = jd0;
                End         = jd0 + daysInMonth;
                GeoLocation = geoLocation;
                this.eL     = LeastSquares.FindCoeffs(eL, 3);
                this.eB     = LeastSquares.FindCoeffs(eB, 3);
                this.eR     = LeastSquares.FindCoeffs(eR, 3);
                this.jL     = LeastSquares.FindCoeffs(jL, 3);
                this.jB     = LeastSquares.FindCoeffs(jB, 3);
                this.jR     = LeastSquares.FindCoeffs(jR, 3);
            });
        }
Пример #20
0
 /// <summary>
 /// Gets helipcentrical coordinates of Earth
 /// </summary>
 private CrdsHeliocentrical EarthHeliocentrical(SkyContext c)
 {
     return(PlanetPositions.GetPlanetCoordinates(Planet.EARTH, c.JulianDay, highPrecision: true));
 }
Пример #21
0
 /// <summary>
 /// Get heliocentrical coordinates of Earth
 /// </summary>
 private CrdsHeliocentrical Earth_Heliocentrial(SkyContext c)
 {
     return(PlanetPositions.GetPlanetCoordinates(Planet.EARTH, c.JulianDay, !c.PreferFastCalculation));
 }
Пример #22
0
 /// <summary>
 /// Calculates heliocentrical coordinates of Earth for J2000 epoch
 /// </summary>
 private CrdsHeliocentrical Earth_HeliocentricalJ2000(SkyContext c)
 {
     return(PlanetPositions.GetPlanetCoordinates(Planet.EARTH, c.JulianDay, highPrecision: !c.PreferFastCalculation, epochOfDate: false));
 }
Пример #23
0
        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);
                }
            }
        }
Пример #24
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);
        }