Exemplo n.º 1
0
        /// <summary>
        /// Gets longitude of ascending node of Lunar orbit for given instant.
        /// </summary>
        /// <param name="jd">Julian Day</param>
        /// <param name="trueAscendingNode">True if position of true ascending node is needed, false for mean position</param>
        /// <returns>Longitude of ascending node of Lunar orbit, in degrees.</returns>
        private static double AscendingNode(double jd, bool trueAscendingNode)
        {
            double T = (jd - 2451545.0) / 36525.0;

            double T2 = T * T;
            double T3 = T2 * T;
            double T4 = T3 * T;

            double Omega = 125.0445479 - 1934.1362891 * T + 0.0020754 * T2 + T3 / 467441.0 - T4 / 60616000.0;

            if (trueAscendingNode)
            {
                // Mean elongation of the Moon
                double D = 297.8501921 + 445267.1114034 * T - 0.0018819 * T2 + T3 / 545868.0 - T4 / 113065000.0;

                // Sun's mean anomaly
                double M = 357.5291092 + 35999.0502909 * T - 0.0001536 * T2 + T3 / 24490000.0;

                // Moon's mean anomaly
                double M_ = 134.9633964 + 477198.8675055 * T + 0.0087414 * T2 + T3 / 69699.0 - T4 / 14712000.0;

                // Moon's argument of latitude (mean dinstance of the Moon from its ascending node)
                double F = 93.2720950 + 483202.0175233 * T - 0.0036539 * T2 - T3 / 3526000.0 + T4 / 863310000.0;

                Omega +=
                    -1.4979 * Math.Sin(Angle.ToRadians(2 * (D - F)))
                    - 0.1500 * Math.Sin(Angle.ToRadians(M))
                    - 0.1226 * Math.Sin(Angle.ToRadians(2 * D))
                    + 0.1176 * Math.Sin(Angle.ToRadians(2 * F))
                    - 0.0801 * Math.Sin(Angle.ToRadians(2 * (M_ - F)));
            }

            return(Angle.To360(Omega));
        }
Exemplo n.º 2
0
        public static CrdsHorizontal WithRefraction(this CrdsHorizontal h0)
        {
            //if (h0.Altitude < 0) return h0;
            double R = 1.02 / Math.Tan(Angle.ToRadians(h0.Altitude + 10.3 / (h0.Altitude + 5.11)));

            return(new CrdsHorizontal(h0.Azimuth, h0.Altitude + R / 60));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Performs reduction of equatorial coordinates from one epoch to another
        /// with using of precessional elements.
        /// </summary>
        /// <param name="eq0">Equatorial coordinates for initial epoch.</param>
        /// <param name="p">Precessional elements for reduction from initial epoch to target (final) epoch.</param>
        /// <returns>Equatorial coordinates for target (final) epoch.</returns>
        /// <remarks>
        /// This method is taken from AA(I), formula 20.4.
        /// </remarks>
        public static CrdsEquatorial GetEquatorialCoordinates(CrdsEquatorial eq0, PrecessionalElements p)
        {
            CrdsEquatorial eq = new CrdsEquatorial();

            double sinDelta0     = Math.Sin(Angle.ToRadians(eq0.Delta));
            double cosDelta0     = Math.Cos(Angle.ToRadians(eq0.Delta));
            double sinTheta      = Math.Sin(Angle.ToRadians(p.theta));
            double cosTheta      = Math.Cos(Angle.ToRadians(p.theta));
            double sinAlpha0Zeta = Math.Sin(Angle.ToRadians(eq0.Alpha + p.zeta));
            double cosAlpha0Zeta = Math.Cos(Angle.ToRadians(eq0.Alpha + p.zeta));

            double A = cosDelta0 * sinAlpha0Zeta;
            double B = cosTheta * cosDelta0 * cosAlpha0Zeta - sinTheta * sinDelta0;
            double C = sinTheta * cosDelta0 * cosAlpha0Zeta + cosTheta * sinDelta0;

            eq.Alpha = Angle.ToDegrees(Math.Atan2(A, B)) + p.z;
            eq.Alpha = Angle.To360(eq.Alpha);

            if (Math.Abs(C) == 1)
            {
                eq.Delta = Angle.ToDegrees(Math.Acos(A * A + B * B));
            }
            else
            {
                eq.Delta = Angle.ToDegrees(Math.Asin(C));
            }

            return(eq);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Calculates aberration elements for given instant.
        /// </summary>
        /// <param name="jde">Julian Ephemeris Day, corresponding to the given instant.</param>
        /// <returns>Aberration elements for the given instant.</returns>
        /// <remarks>
        /// AA(II), pp. 151, 163, 164
        /// </remarks>
        public static AberrationElements AberrationElements(double jde)
        {
            double T  = (jde - 2451545.0) / 36525.0;
            double T2 = T * T;

            double e  = 0.016708634 - 0.000042037 * T - 0.0000001267 * T2;
            double pi = 102.93735 + 1.71946 * T + 0.00046 * T2;

            // geometric true longitude of the Sun
            double L0 = 280.46646 + 36000.76983 * T + 0.0003032 * T2;

            // mean anomaly of the Sun
            double M = 357.52911 + 35999.05029 * T - 0.0001537 * T2;

            M = Angle.ToRadians(M);

            // Sun's equation of the center
            double C = (1.914602 - 0.004817 * T - 0.000014 * T2) * Math.Sin(M)
                       + (0.019993 - 0.000101 * T) * Math.Sin(2 * M)
                       + 0.000289 * Math.Sin(3 * M);

            return(new AberrationElements()
            {
                e = e,
                pi = pi,
                lambda = Angle.To360(L0 + C)
            });
        }
Exemplo n.º 5
0
        /// <summary>
        /// Converts heliocentrical coordinates to rectangular topocentrical coordinates.
        /// </summary>
        /// <param name="planet">Heliocentrical coordinates of a planet</param>
        /// <param name="earth">Heliocentrical coordinates of Earth</param>
        /// <returns>Rectangular topocentrical coordinates of a planet.</returns>
        public static CrdsRectangular ToRectangular(this CrdsHeliocentrical planet, CrdsHeliocentrical earth)
        {
            CrdsRectangular rect = new CrdsRectangular();

            double B = Angle.ToRadians(planet.B);
            double L = Angle.ToRadians(planet.L);
            double R = planet.R;

            double B0 = Angle.ToRadians(earth.B);
            double L0 = Angle.ToRadians(earth.L);
            double R0 = earth.R;

            double cosL = Math.Cos(L);
            double sinL = Math.Sin(L);
            double cosB = Math.Cos(B);
            double sinB = Math.Sin(B);

            double cosL0 = Math.Cos(L0);
            double sinL0 = Math.Sin(L0);
            double cosB0 = Math.Cos(B0);
            double sinB0 = Math.Sin(B0);

            rect.X = R * cosB * cosL - R0 * cosB0 * cosL0;
            rect.Y = R * cosB * sinL - R0 * cosB0 * sinL0;
            rect.Z = R * sinB - R0 * sinB0;

            return(rect);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets magnitude of the Moon by its phase angle.
        /// </summary>
        /// <param name="phaseAngle">Phase angle value, in degrees, from 0 to 180.</param>
        /// <returns>Moon magnitude</returns>
        /// <remarks>
        /// Formula is taken from <see href="https://astronomy.stackexchange.com/questions/10246/is-there-a-simple-analytical-formula-for-the-lunar-phase-brightness-curve"/>
        /// </remarks>
        public static double Magnitude(double phaseAngle)
        {
            double psi  = Angle.ToRadians(phaseAngle);
            double psi4 = Math.Pow(psi, 4);

            return(-12.73 + 1.49 * Math.Abs(psi) + 0.043 * psi4);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Gets geocentric elongation angle of the Moon from Sun
        /// </summary>
        /// <param name="sun">Ecliptical geocentrical coordinates of the Sun</param>
        /// <param name="moon">Ecliptical geocentrical coordinates of the Moon</param>
        /// <returns>Geocentric elongation angle, in degrees, from 0 to 180.</returns>
        /// <remarks>
        /// AA(II), formula 48.2
        /// </remarks>
        public static double Elongation(CrdsEcliptical sun, CrdsEcliptical moon)
        {
            double beta    = Angle.ToRadians(moon.Beta);
            double lambda  = Angle.ToRadians(moon.Lambda);
            double lambda0 = Angle.ToRadians(sun.Lambda);

            return(Angle.ToDegrees(Math.Acos(Math.Cos(beta) * Math.Cos(lambda - lambda0))));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Calculates the aberration effect for a celestial body (star or planet) for given instant.
        /// </summary>
        /// <param name="ecl">Ecliptical coordinates of the body (not corrected).</param>
        /// <param name="ae">Aberration elements needed for calculation of aberration correction.</param>
        /// <returns>Returns aberration correction values for ecliptical coordinates.</returns>
        /// <remarks>
        /// AA(II), formula 23.2
        /// </remarks>
        public static CrdsEcliptical AberrationEffect(CrdsEcliptical ecl, AberrationElements ae)
        {
            double thetaLambda = Angle.ToRadians(ae.lambda - ecl.Lambda);
            double piLambda    = Angle.ToRadians(ae.pi - ecl.Lambda);
            double beta        = Angle.ToRadians(ecl.Beta);

            double dLambda = (-k * Math.Cos(thetaLambda) + ae.e * k * Math.Cos(piLambda)) / Math.Cos(beta);
            double dBeta   = -k *Math.Sin(beta) * (Math.Sin(thetaLambda) - ae.e * Math.Sin(piLambda));

            return(new CrdsEcliptical(dLambda / 3600, dBeta / 3600));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Calculates phase angle of the Moon
        /// </summary>
        /// <param name="psi">Geocentric elongation of the Moon.</param>
        /// <param name="R">Distance Earth-Sun, in kilometers</param>
        /// <param name="Delta">Distance Earth-Moon, in kilometers</param>
        /// <returns>Phase angle, in degrees, from 0 to 180</returns>
        /// <remarks>
        /// AA(II), formula 48.3.
        /// </remarks>
        public static double PhaseAngle(double psi, double R, double Delta)
        {
            psi = Angle.ToRadians(Math.Abs(psi));
            double phaseAngle = Angle.ToDegrees(Math.Atan(R * Math.Sin(psi) / (Delta - R * Math.Cos(psi))));

            if (phaseAngle < 0)
            {
                phaseAngle += 180;
            }
            return(phaseAngle);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Returns nutation corrections for equatorial coordiantes.
        /// </summary>
        /// <param name="eq">Initial (not corrected) equatorial coordiantes.</param>
        /// <param name="ne">Nutation elements for given instant.</param>
        /// <param name="epsilon">True obliquity of the ecliptic (ε), in degrees.</param>
        /// <returns>Nutation corrections for equatorial coordiantes.</returns>
        /// <remarks>AA(II), formula 23.1</remarks>
        public static CrdsEquatorial NutationEffect(CrdsEquatorial eq, NutationElements ne, double epsilon)
        {
            CrdsEquatorial correction = new CrdsEquatorial();

            epsilon = Angle.ToRadians(epsilon);
            double alpha = Angle.ToRadians(eq.Alpha);
            double delta = Angle.ToRadians(eq.Delta);

            correction.Alpha = (Math.Cos(epsilon) + Math.Sin(epsilon) * Math.Sin(alpha) * Math.Tan(delta)) * ne.deltaPsi - (Math.Cos(alpha) * Math.Tan(delta)) * ne.deltaEpsilon;
            correction.Delta = Math.Sin(epsilon) * Math.Cos(alpha) * ne.deltaPsi + Math.Sin(alpha) * ne.deltaEpsilon;
            return(correction);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Calculates appearance of Saturn rings
        /// </summary>
        /// <param name="jd">Julian date to calculate for</param>
        /// <param name="saturn">Heliocentric coordinates of Saturn.</param>
        /// <param name="earth">Heliocentric coordinates of Earth.</param>
        /// <param name="epsilon">True obliquity of ecliptic.</param>
        /// <returns>
        /// Appearance data for Saturn rings.
        /// </returns>
        /// <remarks>
        /// Method is taken from AA(II), chapter 45.
        /// </remarks>
        public static RingsAppearance SaturnRings(double jd, CrdsHeliocentrical saturn, CrdsHeliocentrical earth, double epsilon)
        {
            RingsAppearance rings = new RingsAppearance();
            double          T     = (jd - 2451545.0) / 36525.0;
            double          T2    = T * T;

            double i     = 28.075216 - 0.012998 * T + 0.000004 * T2;
            double Omega = 169.508470 + 1.394681 * T + 0.000412 * T2;

            double lambda0 = Omega - 90;
            double beta0   = 90 - i;

            i     = Angle.ToRadians(i);
            Omega = Angle.ToRadians(Omega);

            CrdsEcliptical ecl = saturn.ToRectangular(earth).ToEcliptical();

            double beta   = Angle.ToRadians(ecl.Beta);
            double lambda = Angle.ToRadians(ecl.Lambda);

            rings.B = Angle.ToDegrees(Math.Asin(Math.Sin(i) * Math.Cos(beta) * Math.Sin(lambda - Omega) - Math.Cos(i) * Math.Sin(beta)));
            rings.a = 375.35 / ecl.Distance;
            rings.b = rings.a * Math.Sin(Math.Abs(Angle.ToRadians(rings.B)));

            double N  = 113.6655 + 0.8771 * T;
            double l_ = Angle.ToRadians(saturn.L - 0.01759 / saturn.R);
            double b_ = Angle.ToRadians(saturn.B - 0.000764 * Math.Cos(Angle.ToRadians(saturn.L - N)) / saturn.R);

            double U1 = Angle.ToDegrees(Math.Atan((Math.Sin(i) * Math.Sin(b_) + Math.Cos(i) * Math.Cos(b_) * Math.Sin(l_ - Omega)) / (Math.Cos(b_) * Math.Cos(l_ - Omega))));
            double U2 = Angle.ToDegrees(Math.Atan((Math.Sin(i) * Math.Sin(beta) + Math.Cos(i) * Math.Cos(beta) * Math.Sin(lambda - Omega)) / (Math.Cos(beta) * Math.Cos(lambda - Omega))));

            rings.DeltaU = Math.Abs(U1 - U2);

            CrdsEcliptical eclPole = new CrdsEcliptical();

            eclPole.Set(lambda0, beta0);

            CrdsEquatorial eq     = ecl.ToEquatorial(epsilon);
            CrdsEquatorial eqPole = eclPole.ToEquatorial(epsilon);

            double alpha  = Angle.ToRadians(eq.Alpha);
            double delta  = Angle.ToRadians(eq.Delta);
            double alpha0 = Angle.ToRadians(eqPole.Alpha);
            double delta0 = Angle.ToRadians(eqPole.Delta);

            double y = Math.Cos(delta0) * Math.Sin(alpha0 - alpha);
            double x = Math.Sin(delta0) * Math.Cos(delta) - Math.Cos(delta0) * Math.Sin(delta) * Math.Cos(alpha0 - alpha);

            rings.P = Angle.ToDegrees(Math.Atan2(y, x));

            return(rings);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Calculates visible appearance of planet for given date.
        /// </summary>
        /// <param name="jd">Julian day</param>
        /// <param name="planet">Planet number to calculate appearance, 1 = Mercury, 2 = Venus and etc.</param>
        /// <param name="eq">Equatorial coordinates of the planet</param>
        /// <param name="distance">Distance from the planet to the Earth</param>
        /// <returns>Appearance parameters of the planet</returns>
        /// <remarks>
        /// This method is based on book "Practical Ephemeris Calculations", Montenbruck.
        /// See topic 6.4, pp. 88-92.
        /// </remarks>
        public static PlanetAppearance PlanetAppearance(double jd, int planet, CrdsEquatorial eq, double distance)
        {
            PlanetAppearance a = new PlanetAppearance();

            double d = jd - 2451545.0;
            double T = d / 36525.0;

            // coordinates of the point to which the north pole of the planet is pointing.
            CrdsEquatorial eq0 = new CrdsEquatorial();

            eq0.Alpha = Angle.To360(cAlpha0[planet - 1][0] + cAlpha0[planet - 1][1] * T + cAlpha0[planet - 1][2] * T);
            eq0.Delta = cDelta0[planet - 1][0] + cDelta0[planet - 1][1] * T + cDelta0[planet - 1][2] * T;

            // take light time effect into account
            d -= PlanetPositions.LightTimeEffect(distance);
            T  = d / 36525.0;

            // position of null meridian
            double W = Angle.To360(cW[planet - 1][0] + cW[planet - 1][1] * d + cW[planet - 1][2] * T);

            double delta = Angle.ToRadians(eq.Delta);
            double alpha = Angle.ToRadians(eq.Alpha);

            double delta0  = Angle.ToRadians(eq0.Delta);
            double dAlpha0 = Angle.ToRadians(eq0.Alpha - eq.Alpha);

            double sinD = -Math.Sin(delta0) * Math.Sin(delta) - Math.Cos(delta0) * Math.Cos(delta) * Math.Cos(dAlpha0);

            // planetographic latitude of the Earth
            a.D = Angle.ToDegrees(Math.Asin(sinD));

            double cosD = Math.Cos(Angle.ToRadians(a.D));

            double sinP = Math.Cos(delta0) * Math.Sin(dAlpha0) / cosD;
            double cosP = (Math.Sin(delta0) * Math.Cos(delta) - Math.Cos(delta0) * Math.Sin(delta) * Math.Cos(dAlpha0)) / cosD;

            // position angle of the axis
            a.P = Angle.To360(Angle.ToDegrees(Math.Atan2(sinP, cosP)));

            double sinK = (-Math.Cos(delta0) * Math.Sin(delta) + Math.Sin(delta0) * Math.Cos(delta) * Math.Cos(dAlpha0)) / cosD;

            double cosK = Math.Cos(delta) * Math.Sin(dAlpha0) / cosD;

            double K = Angle.ToDegrees(Math.Atan2(sinK, cosK));

            // planetographic longitude of the central meridian
            a.CM = planet == 5 ?
                   JupiterCM2(jd) :
                   Angle.To360(Math.Sign(W) * (W - K));

            return(a);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Calculates longitude of Central Meridian of Jupiter in System II.
        /// </summary>
        /// <param name="jd">Julian Day</param>
        /// <returns>Longitude of Central Meridian of Jupiter in System II, in degrees.</returns>
        /// <remarks>
        /// This method is based on formula described here: <see href="https://www.projectpluto.com/grs_form.htm"/>
        /// </remarks>
        private static double JupiterCM2(double jd)
        {
            double jup_mean   = (jd - 2455636.938) * 360.0 / 4332.89709;
            double eqn_center = 5.55 * Math.Sin(Angle.ToRadians(jup_mean));
            double angle      = (jd - 2451870.628) * 360.0 / 398.884 - eqn_center;
            double correction = 11 * Math.Sin(Angle.ToRadians(angle))
                                + 5 * Math.Cos(Angle.ToRadians(angle))
                                - 1.25 * Math.Cos(Angle.ToRadians(jup_mean)) - eqn_center;

            double cm = 181.62 + 870.1869147 * jd + correction;

            return(Angle.To360(cm));
        }
Exemplo n.º 14
0
        /// <summary>
        /// Gets correction for ecliptical coordinates obtained by VSOP87 theory,
        /// needed for conversion to standard FK5 system.
        /// This correction should be used only for high-precision version of VSOP87.
        /// </summary>
        /// <param name="jde">Julian Ephemeris Day</param>
        /// <param name="ecl">Non-corrected ecliptical coordinates of the body.</param>
        /// <returns>Corrections values for longutude and latitude, in degrees.</returns>
        /// <remarks>
        /// AA(II), formula 32.3.
        /// </remarks>
        public static CrdsEcliptical CorrectionForFK5(double jde, CrdsEcliptical ecl)
        {
            double T = (jde - 2451545) / 36525.0;

            double L_ = Angle.ToRadians(ecl.Lambda - 1.397 * T - 0.00031 * T * T);

            double sinL_ = Math.Sin(L_);
            double cosL_ = Math.Cos(L_);

            double deltaL = -0.09033 + 0.03916 * (cosL_ + sinL_) * Math.Tan(Angle.ToRadians(ecl.Beta));
            double deltaB = 0.03916 * (cosL_ - sinL_);

            return(new CrdsEcliptical(deltaL / 3600, deltaB / 3600));
        }
Exemplo n.º 15
0
        /// <summary>
        /// Converts ecliptical coordinates to equatorial.
        /// </summary>
        /// <param name="ecl">Pair of ecliptical cooordinates.</param>
        /// <param name="epsilon">Obliquity of the ecliptic, in degrees.</param>
        /// <returns>Pair of equatorial coordinates.</returns>
        public static CrdsEquatorial ToEquatorial(this CrdsEcliptical ecl, double epsilon)
        {
            CrdsEquatorial eq = new CrdsEquatorial();

            epsilon = Angle.ToRadians(epsilon);
            double lambda = Angle.ToRadians(ecl.Lambda);
            double beta   = Angle.ToRadians(ecl.Beta);

            double Y = Math.Sin(lambda) * Math.Cos(epsilon) - Math.Tan(beta) * Math.Sin(epsilon);
            double X = Math.Cos(lambda);

            eq.Alpha = Angle.To360(Angle.ToDegrees(Math.Atan2(Y, X)));
            eq.Delta = Angle.ToDegrees(Math.Asin(Math.Sin(beta) * Math.Cos(epsilon) + Math.Cos(beta) * Math.Sin(epsilon) * Math.Sin(lambda)));

            return(eq);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Converts equatorial coordinates (for equinox B1950.0) to galactical coordinates.
        /// </summary>
        /// <param name="eq">Equatorial coordinates for equinox B1950.0</param>
        /// <returns>Galactical coordinates.</returns>
        public static CrdsGalactical ToGalactical(this CrdsEquatorial eq)
        {
            CrdsGalactical gal = new CrdsGalactical();

            double alpha0_alpha = Angle.ToRadians(192.25 - eq.Alpha);
            double delta        = Angle.ToRadians(eq.Delta);
            double delta0       = Angle.ToRadians(27.4);

            double Y    = Math.Sin(alpha0_alpha);
            double X    = Math.Cos(alpha0_alpha) * Math.Sin(delta0) - Math.Tan(delta) * Math.Cos(delta0);
            double sinb = Math.Sin(delta) * Math.Sin(delta0) + Math.Cos(delta) * Math.Cos(delta0) * Math.Cos(alpha0_alpha);

            gal.l = Angle.To360(303 - Angle.ToDegrees(Math.Atan2(Y, X)));
            gal.b = Angle.ToDegrees(Math.Asin(sinb));
            return(gal);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Converts equatorial coordinates to ecliptical coordinates.
        /// </summary>
        /// <param name="eq">Pair of equatorial coordinates.</param>
        /// <param name="epsilon">Obliquity of the ecliptic, in degrees.</param>
        /// <returns></returns>
        public static CrdsEcliptical ToEcliptical(this CrdsEquatorial eq, double epsilon)
        {
            CrdsEcliptical ecl = new CrdsEcliptical();

            epsilon = Angle.ToRadians(epsilon);
            double alpha = Angle.ToRadians(eq.Alpha);
            double delta = Angle.ToRadians(eq.Delta);

            double Y = Math.Sin(alpha) * Math.Cos(epsilon) + Math.Tan(delta) * Math.Sin(epsilon);
            double X = Math.Cos(alpha);

            ecl.Lambda = Angle.ToDegrees(Math.Atan2(Y, X));
            ecl.Beta   = Angle.ToDegrees(Math.Asin(Math.Sin(delta) * Math.Cos(epsilon) - Math.Cos(delta) * Math.Sin(epsilon) * Math.Sin(alpha)));

            return(ecl);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Converts galactical coodinates to equatorial, for equinox B1950.0.
        /// </summary>
        /// <param name="gal">Galactical coodinates.</param>
        /// <returns>Equatorial coodinates, for equinox B1950.0.</returns>
        public static CrdsEquatorial ToEquatorial(this CrdsGalactical gal)
        {
            CrdsEquatorial eq = new CrdsEquatorial();

            double l_l0   = Angle.ToRadians(gal.l - 123.0);
            double delta0 = Angle.ToRadians(27.4);
            double b      = Angle.ToRadians(gal.b);

            double Y        = Math.Sin(l_l0);
            double X        = Math.Cos(l_l0) * Math.Sin(delta0) - Math.Tan(b) * Math.Cos(delta0);
            double sinDelta = Math.Sin(b) * Math.Sin(delta0) + Math.Cos(b) * Math.Cos(delta0) * Math.Cos(l_l0);

            eq.Alpha = Angle.To360(Angle.ToDegrees(Math.Atan2(Y, X)) + 12.25);
            eq.Delta = Angle.ToDegrees(Math.Asin(sinDelta));
            return(eq);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Converts local horizontal coordinates to equatorial coordinates.
        /// </summary>
        /// <param name="hor">Pair of local horizontal coordinates.</param>
        /// <param name="geo">Geographical of the observer</param>
        /// <param name="theta0">Local sidereal time.</param>
        /// <returns>Pair of equatorial coordinates</returns>
        public static CrdsEquatorial ToEquatorial(this CrdsHorizontal hor, CrdsGeographical geo, double theta0)
        {
            CrdsEquatorial eq  = new CrdsEquatorial();
            double         A   = Angle.ToRadians(hor.Azimuth);
            double         h   = Angle.ToRadians(hor.Altitude);
            double         phi = Angle.ToRadians(geo.Latitude);

            double Y = Math.Sin(A);
            double X = Math.Cos(A) * Math.Sin(phi) + Math.Tan(h) * Math.Cos(phi);

            double H = Angle.ToDegrees(Math.Atan2(Y, X));

            eq.Alpha = Angle.To360(theta0 - geo.Longitude - H);
            eq.Delta = Angle.ToDegrees(Math.Asin(Math.Sin(phi) * Math.Sin(h) - Math.Cos(phi) * Math.Cos(h) * Math.Cos(A)));

            return(eq);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Converts equatorial coodinates to local horizontal
        /// </summary>
        /// <param name="eq">Pair of equatorial coodinates</param>
        /// <param name="geo">Geographical coordinates of the observer</param>
        /// <param name="theta0">Local sidereal time</param>
        /// <remarks>
        /// Implementation is taken from AA(I), formulae 12.5, 12.6.
        /// </remarks>
        public static CrdsHorizontal ToHorizontal(this CrdsEquatorial eq, CrdsGeographical geo, double theta0)
        {
            double H     = Angle.ToRadians(HourAngle(theta0, geo.Longitude, eq.Alpha));
            double phi   = Angle.ToRadians(geo.Latitude);
            double delta = Angle.ToRadians(eq.Delta);

            CrdsHorizontal hor = new CrdsHorizontal();

            double Y = Math.Sin(H);
            double X = Math.Cos(H) * Math.Sin(phi) - Math.Tan(delta) * Math.Cos(phi);

            hor.Altitude = Angle.ToDegrees(Math.Asin(Math.Sin(phi) * Math.Sin(delta) + Math.Cos(phi) * Math.Cos(delta) * Math.Cos(H)));

            hor.Azimuth = Angle.ToDegrees(Math.Atan2(Y, X));
            hor.Azimuth = Angle.To360(hor.Azimuth);

            return(hor);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Calculates topocentric equatorial coordinates of celestial body
        /// with taking into account correction for parallax.
        /// </summary>
        /// <param name="eq">Geocentric equatorial coordinates of the body</param>
        /// <param name="geo">Geographical coordinates of the body</param>
        /// <param name="theta0">Apparent sidereal time at Greenwich</param>
        /// <param name="pi">Parallax of a body</param>
        /// <returns>Topocentric equatorial coordinates of the celestial body</returns>
        /// <remarks>
        /// Method is taken from AA(II), formulae 40.6-40.7.
        /// </remarks>
        public static CrdsEquatorial ToTopocentric(this CrdsEquatorial eq, CrdsGeographical geo, double theta0, double pi)
        {
            double H     = Angle.ToRadians(HourAngle(theta0, geo.Longitude, eq.Alpha));
            double delta = Angle.ToRadians(eq.Delta);
            double sinPi = Math.Sin(Angle.ToRadians(pi));

            double A = Math.Cos(delta) * Math.Sin(H);
            double B = Math.Cos(delta) * Math.Cos(H) - geo.RhoCosPhi * sinPi;
            double C = Math.Sin(delta) - geo.RhoSinPhi * sinPi;

            double q = Math.Sqrt(A * A + B * B + C * C);

            double H_ = Angle.ToDegrees(Math.Atan2(A, B));

            double alpha_ = Angle.To360(theta0 - geo.Longitude - H_);
            double delta_ = Angle.ToDegrees(Math.Asin(C / q));

            return(new CrdsEquatorial(alpha_, delta_));
        }
Exemplo n.º 22
0
        /// <summary>
        /// Calculates the aberration effect for a celestial body (star or planet) for given instant.
        /// </summary>
        /// <param name="eq">Equatorial coordinates of the body (not corrected).</param>
        /// <param name="ae">Aberration elements needed for calculation of aberration correction.</param>
        /// <returns>Returns aberration correction values for equatorial coordinates.</returns>
        /// <remarks>AA(II), formula 23.3</remarks>
        public static CrdsEquatorial AberrationEffect(CrdsEquatorial eq, AberrationElements ae, double epsilon)
        {
            double a     = Angle.ToRadians(eq.Alpha);
            double d     = Angle.ToRadians(eq.Delta);
            double theta = Angle.ToRadians(ae.lambda);
            double pi    = Angle.ToRadians(ae.pi);

            epsilon = Angle.ToRadians(epsilon);

            double da = -k * (Math.Cos(a) * Math.Cos(theta) * Math.Cos(epsilon) + Math.Sin(a) * Math.Sin(theta)) / Math.Cos(d)
                        + epsilon * k * (Math.Cos(a) * Math.Cos(pi) * Math.Cos(epsilon) + Math.Sin(a) * Math.Sin(pi)) / Math.Cos(d);

            double m = Math.Tan(epsilon) * Math.Cos(d) - Math.Sin(a) * Math.Sin(d);

            double dd = -k * (Math.Cos(theta) * Math.Cos(epsilon) * m
                              + Math.Cos(a) * Math.Sin(d) * Math.Sin(theta))
                        + epsilon * k * (Math.Cos(pi) * Math.Cos(epsilon) * m + Math.Cos(a) * Math.Sin(d) * Math.Sin(pi));

            return(new CrdsEquatorial(da / 3600, dd / 3600));
        }
Exemplo n.º 23
0
        public static CrdsEquatorial ToEquatorial(this CrdsRectangular m, CrdsEquatorial planet, double P, double semidiameter)
        {
            // convert to polar coordinates

            // radius-vector of moon, in planet's equatorial radii
            double r = Math.Sqrt(m.X * m.X + m.Y * m.Y);

            // rotation angle
            double theta = Angle.ToDegrees(Math.Atan2(m.Y, m.X));

            // rotate with position angle of the planet
            theta += P;

            // convert back to rectangular coordinates, but rotated with P angle:
            double x = r * Math.Cos(Angle.ToRadians(theta));
            double y = r * Math.Sin(Angle.ToRadians(theta));

            double dAlpha = (1 / Math.Cos(Angle.ToRadians(planet.Delta))) * x * semidiameter / 3600;
            double dDelta = y * semidiameter / 3600;

            return(new CrdsEquatorial(planet.Alpha - dAlpha, planet.Delta + dDelta));
        }
Exemplo n.º 24
0
        /// <summary>
        /// Converts ecliptical coordinates to rectangular coordinates.
        /// </summary>
        /// <param name="ecl">Ecliptical coordinates</param>
        /// <param name="epsilon">Obliquity of the ecliptic, in degrees.</param>
        /// <returns>Rectangular coordinates.</returns>
        public static CrdsRectangular ToRectangular(this CrdsEcliptical ecl, double epsilon)
        {
            CrdsRectangular rect = new CrdsRectangular();

            double beta   = Angle.ToRadians(ecl.Beta);
            double lambda = Angle.ToRadians(ecl.Lambda);
            double R      = ecl.Distance;

            epsilon = Angle.ToRadians(epsilon);

            double cosBeta    = Math.Cos(beta);
            double sinBeta    = Math.Sin(beta);
            double sinLambda  = Math.Sin(lambda);
            double cosLambda  = Math.Cos(lambda);
            double sinEpsilon = Math.Sin(epsilon);
            double cosEpsilon = Math.Cos(epsilon);

            rect.X = R * cosBeta * cosLambda;
            rect.Y = R * (cosBeta * sinLambda * cosEpsilon - sinBeta * sinEpsilon);
            rect.Z = R * (cosBeta * sinLambda * sinEpsilon + sinBeta * cosEpsilon);
            return(rect);
        }
Exemplo n.º 25
0
        /// <summary>
        /// Gets geocentric elongation angle of the celestial body
        /// </summary>
        /// <param name="sun">Ecliptical geocentrical coordinates of the Sun</param>
        /// <param name="body">Ecliptical geocentrical coordinates of the body</param>
        /// <returns>Geocentric elongation angle, in degrees, from -180 to 180.
        /// Negative sign means western elongation, positive eastern.
        /// </returns>
        /// <remarks>
        /// AA(II), formula 48.2
        /// </remarks>
        // TODO: tests
        public static double Elongation(CrdsEcliptical sun, CrdsEcliptical body)
        {
            double beta    = Angle.ToRadians(body.Beta);
            double lambda  = Angle.ToRadians(body.Lambda);
            double lambda0 = Angle.ToRadians(sun.Lambda);

            double s = sun.Lambda;
            double b = body.Lambda;

            if (Math.Abs(s - b) > 180)
            {
                if (s < b)
                {
                    s += 360;
                }
                else
                {
                    b += 360;
                }
            }

            return(Math.Sign(b - s) * Angle.ToDegrees(Math.Acos(Math.Cos(beta) * Math.Cos(lambda - lambda0))));
        }
Exemplo n.º 26
0
        /// <summary>
        /// Calculates nutation elements for given instant.
        /// </summary>
        /// <param name="jd">Julian Day, corresponding to the given instant.</param>
        /// <returns>Aberration elements for the given instant.</returns>
        /// <remarks>
        /// The method is taken from AA(II), page 144.
        /// Accuracy of the method is 0.1" for Δε and 0.5" for Δψ.
        /// </remarks>
        public static NutationElements NutationElements(double jd)
        {
            double T = (jd - 2451545) / 36525.0;

            // Longitude of the ascending node of Moon's mean orbit on the ecliptic,
            // measured from the mean equinox of the date:
            double Omega = 125.04452 - 1934.136261 * T;

            // Mean longutude of Sun
            double L = 280.4665 + 36000.7698 * T;

            // Mean longitude of Moon
            double L_ = 218.3165 + 481267.8813 * T;

            double deltaEpsilon = 9.20 * Math.Cos(Angle.ToRadians(Omega)) + 0.57 * Math.Cos(Angle.ToRadians(2 * L)) + 0.10 * Math.Cos(Angle.ToRadians(2 * L_)) - 0.09 * Math.Cos(Angle.ToRadians(2 * Omega));

            double deltaPsi = -17.20 * Math.Sin(Angle.ToRadians(Omega)) - 1.32 * Math.Sin(Angle.ToRadians(2 * L)) - 0.23 * Math.Sin(Angle.ToRadians(2 * L_)) + 0.21 * Math.Sin(Angle.ToRadians(2 * Omega));

            return(new NutationElements()
            {
                deltaEpsilon = deltaEpsilon / 3600,
                deltaPsi = deltaPsi / 3600
            });
        }
Exemplo n.º 27
0
        /// <summary>
        /// Gets magnitude component of Saturn rings, that should be added to Saturn disk magnitude (see <see cref="PlanetEphem.Magnitude(int, double, double, double)"/>).
        /// </summary>
        /// <returns></returns>
        public float GetRingsMagnitude()
        {
            double sinB = Math.Sin(Angle.ToRadians(B));

            return((float)(0.044 * Math.Abs(DeltaU) - 2.6 * Math.Sin(Angle.ToRadians(Math.Abs(B))) + 1.25 * sinB * sinB));
        }
Exemplo n.º 28
0
Arquivo: Date.cs Projeto: t9mike/ADK
        /// <summary>
        /// Calculates apparent sidereal time at Greenwich for given instant.
        /// </summary>
        /// <param name="jd">Julian Day</param>
        /// <returns>Apparent sidereal time at Greenwich, expressed in degrees.</returns>
        /// <remarks>
        /// AA(II), formula 12.4, with corrections for nutation (chapter 22).
        /// </remarks>
        public static double ApparentSiderealTime(double jd, double deltaPsi, double epsilon)
        {
            double cosEpsilon = Math.Cos(Angle.ToRadians(epsilon));

            return(MeanSiderealTime(jd) + deltaPsi * cosEpsilon);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Calculates instants of rising, transit and setting for non-stationary celestial body for the desired date.
        /// Non-stationary in this particular case means that body has fastly changing celestial coordinates during the day.
        /// </summary>
        /// <param name="eq">Array of three equatorial coordinates of the celestial body correspoding to local midnight, local noon, and local midnight of the following day after the desired date respectively.</param>
        /// <param name="location">Geographical location of the observation point.</param>
        /// <param name="theta0">Apparent sidereal time at Greenwich for local midnight of the desired date.</param>
        /// <param name="pi">Horizontal equatorial parallax of the body.</param>
        /// <param name="sd">Visible semidiameter of the body, expressed in degrees.</param>
        /// <returns>Instants of rising, transit and setting for the celestial body for the desired date.</returns>
        public static RTS RiseTransitSet(CrdsEquatorial[] eq, CrdsGeographical location, double theta0, double pi = 0, double sd = 0)
        {
            if (eq.Length != 3)
            {
                throw new ArgumentException("Number of equatorial coordinates in the array should be equal to 3.");
            }

            double[] alpha = new double[3];
            double[] delta = new double[3];
            for (int i = 0; i < 3; i++)
            {
                alpha[i] = eq[i].Alpha;
                delta[i] = eq[i].Delta;
            }

            Angle.Align(alpha);
            Angle.Align(delta);

            List <CrdsHorizontal> hor = new List <CrdsHorizontal>();

            for (int i = 0; i <= 24; i++)
            {
                double         n       = i / 24.0;
                CrdsEquatorial eq0     = InterpolateEq(alpha, delta, n);
                var            sidTime = InterpolateSiderialTime(theta0, n);
                hor.Add(eq0.ToTopocentric(location, sidTime, pi).ToHorizontal(location, sidTime));
            }

            var result = new RTS();

            for (int i = 0; i < 24; i++)
            {
                double n = (i + 0.5) / 24.0;

                CrdsEquatorial eq0 = InterpolateEq(alpha, delta, n);

                var sidTime = InterpolateSiderialTime(theta0, n);
                var hor0    = eq0.ToTopocentric(location, sidTime, pi).ToHorizontal(location, sidTime);

                if (double.IsNaN(result.Transit) && hor0.Altitude > 0)
                {
                    double r = SolveParabola(Math.Sin(Angle.ToRadians(hor[i].Azimuth)), Math.Sin(Angle.ToRadians(hor0.Azimuth)), Math.Sin(Angle.ToRadians(hor[i + 1].Azimuth)));
                    if (!double.IsNaN(r))
                    {
                        double t = (i + r) / 24.0;

                        eq0     = InterpolateEq(alpha, delta, t);
                        sidTime = InterpolateSiderialTime(theta0, t);

                        result.Transit         = t;
                        result.TransitAltitude = eq0.ToTopocentric(location, sidTime, pi).ToHorizontal(location, sidTime).Altitude;
                    }
                }

                if (double.IsNaN(result.Rise) || double.IsNaN(result.Set))
                {
                    double r = SolveParabola(hor[i].Altitude + sd, hor0.Altitude + sd, hor[i + 1].Altitude + sd);

                    if (!double.IsNaN(r))
                    {
                        double t = (i + r) / 24.0;
                        eq0     = InterpolateEq(alpha, delta, t);
                        sidTime = InterpolateSiderialTime(theta0, t);

                        if (double.IsNaN(result.Rise) && hor[i].Altitude + sd < 0 && hor[i + 1].Altitude + sd > 0)
                        {
                            result.Rise        = t;
                            result.RiseAzimuth = eq0.ToTopocentric(location, sidTime, pi).ToHorizontal(location, sidTime).Azimuth;
                        }

                        if (double.IsNaN(result.Set) && hor[i].Altitude + sd > 0 && hor[i + 1].Altitude + sd < 0)
                        {
                            result.Set        = t;
                            result.SetAzimuth = eq0.ToTopocentric(location, sidTime, pi).ToHorizontal(location, sidTime).Azimuth;
                        }

                        if (!double.IsNaN(result.Transit) && !double.IsNaN(result.Rise) && !double.IsNaN(result.Set))
                        {
                            break;
                        }
                    }
                }
            }

            return(result);
        }
Exemplo n.º 30
0
 /// <summary>
 /// Gets phase value (illuminated fraction of the Moon disk).
 /// </summary>
 /// <param name="phaseAngle">Phase angle of the Moon, in degrees.</param>
 /// <returns>Illuminated fraction of the Moon disk, from 0 to 1.</returns>
 /// <remarks>
 /// AA(II), formula 48.1
 /// </remarks>
 public static double Phase(double phaseAngle)
 {
     return((1 + Math.Cos(Angle.ToRadians(phaseAngle))) / 2);
 }