// METHODES PUBLIQUES
        /// <summary>
        /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher. Les calculs nécessitent un objet Soleil qui est automatiquement
        /// créé par la méthode.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        public void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul)
        {
            Soleil soleil = new Soleil();

            soleil.CalculerNonIteratif(a_lieuEtDateCalcul);
            CalculerNonIteratif(a_lieuEtDateCalcul, soleil);
        }
        /// <summary>
        /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// de façon itérative jusqu'à convergence des heures de lever et de coucher.
        /// Les calculs nécessitent un objet Soleil qui est automatiquement créé par la méthode.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <returns>Résultat du succès (true) ou de l'échec (false) du calcul de convergence des heures de lever et de coucher.</returns>
        public bool CalculerIteratif(PositionTemps a_lieuEtDateCalcul)
        {
            Soleil soleil = new Soleil();

            soleil.CalculerNonIteratif(a_lieuEtDateCalcul);
            return(CalculerIteratif(a_lieuEtDateCalcul, soleil));
        }
Beispiel #3
0
        // Algorithme 26
        /// <summary>
        /// Calcule les corrections dues à la parallaxe à apporter sur les coordonnées équatoriales géocentriques d’un corps céleste à partir des coordonnées rectangulaires géocentriques du lieu d’observation,
        /// des coordonnées équatoriales géocentriques du corps céleste, de l’heure sidérale locale et de la distance du corps céleste à la Terre
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void CalculerCorrectionCoordonneesEquatorialesParallaxe(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double sinpi = 0, H; // variables de calcul
            double x, y;         // variables de calcul

            // Calcul de la parallaxe
            if (type == TypeCorpsCeleste.LUNE)
            {
                sinpi = (6378.14 / r);
            }
            if (type != TypeCorpsCeleste.LUNE)
            {
                sinpi = (Math.Sin(Maths.DegToRad(8.794 / 3600.0)) / r);
            }

            // Calcul de l'angle horaire
            H = Maths.CalculerHeureDecimale(a_lieuEtDateCalcul.HeureSideraleLocale) - ascensionDroiteGeocentrique.Decimale;
            H = Maths.Modulo(H, TypeAngle.ANGLE_HEURES_24);
            H = 15.0 * H; // H en degrés

            // Calcul des corrections à apporter sur les coordonnées équatoriales géocentriques
            y           = -a_lieuEtDateCalcul.LieuObservation.CosPhi * sinpi * Math.Sin(Maths.DegToRad(H));
            x           = Math.Cos(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - a_lieuEtDateCalcul.LieuObservation.CosPhi * sinpi * Math.Cos(Maths.DegToRad(H));
            deltaAlpha6 = Math.Atan2(y, x);
            declinaisonTopocentrique = new Angle(Maths.RadToDeg(Math.Atan(((Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - a_lieuEtDateCalcul.LieuObservation.SinPhi * sinpi) * Math.Cos(deltaAlpha6))
                                                                          / (Math.Cos(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - a_lieuEtDateCalcul.LieuObservation.CosPhi * sinpi * Math.Cos(Maths.DegToRad(H))))), TypeAngle.ANGLE_DEGRES_90);
            deltaDelta6 = declinaisonTopocentrique.Decimale - declinaisonGeocentrique.Decimale;
            deltaAlpha6 = Maths.RadToDeg(deltaAlpha6) / 15.0;
        }
        // Algorithme 14
        /// <summary>
        /// Calcule les coordonnées horizontales topocentriques d’un corps céleste en coordonnées équatoriales topocentriques à partir de latitude et de l’heure sidérale vraie locale.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void ConvertirCoordonneesHorizontalesVersEquatoriales(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double H = 0.0;   // variable de calcul

            // Calcul de la décinaison topocentrique
            double decTop = Math.Asin((Math.Sin(Maths.DegToRad(altitudeTopocentrique.Decimale)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)))
                                      + (Math.Cos(Maths.DegToRad(altitudeTopocentrique.Decimale)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(azimutTopocentrique.Decimale))));

            decTop = Maths.RadToDeg(decTop);
            declinaisonTopocentrique = new Angle(decTop, TypeAngle.ANGLE_DEGRES_90);

            // Calcul de l'angle horaire
            if (Math.Sin(Maths.DegToRad(azimutTopocentrique.Decimale)) <= 0)
            {
                H = Math.Acos((Math.Sin(Maths.DegToRad(altitudeTopocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale))
                               * Math.Sin(Maths.DegToRad(declinaisonTopocentrique.Decimale))) / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(declinaisonTopocentrique.Decimale))));
                H = Maths.RadToDeg(H);
            }
            if (Math.Sin(Maths.DegToRad(azimutTopocentrique.Decimale)) > 0)
            {
                H = Math.Acos((Math.Sin(Maths.DegToRad(altitudeTopocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale))
                               * Math.Sin(Maths.DegToRad(declinaisonTopocentrique.Decimale))) / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(declinaisonTopocentrique.Decimale))));
                H = 360 - Maths.RadToDeg(H);
            }

            // Calcul de l'ascension droite topocentrique
            H = H / 15.0; // Conversion de H en heures

            double alphaTop = Maths.CalculerHeureDecimale(a_lieuEtDateCalcul.HeureSideraleLocale) - H;

            alphaTop = Maths.Modulo(alphaTop, TypeAngle.ANGLE_HEURES_24);
            ascensionDroiteTopocentrique = new Angle(alphaTop, TypeAngle.ANGLE_HEURES_24);
        }
        // ***** ALGORITHME 18P *****
        /// <summary>
        /// Calcule les corrections dues à la précession à apporter sur les coordonnées équatoriales géocentriques géométriques d’un corps céleste rapportées à l’équinoxe J2000
        /// à partir du Jour Julien des Ephémérides correspondant à la date et l’heure considérées, des coordonnées équatoriales géocentriques géométriques du corps céleste à
        /// l’époque J2000 et des corrections dues au mouvement propre.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerCorrectionCoordonneesEquatorialesPrecession(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthodes
            double T, dzeta, z, teta, A, B, C; // variables de calcul

            // Calcul du nombre de siècles depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 36525.0;

            // Calcul de l'angle eta
            dzeta = 2306.2181 * T + 0.30188 * T * T + 0.017998 * T * T * T; // angle en secondes d'arc
            dzeta = dzeta / 3600.0;                                         // angle en degrés

            // Calcul de l'angle pi
            z = 2306.2181 * T + 1.09468 * T * T + 0.018203 * T * T * T; // angle en secondes d'arc
            z = z / 3600.0;                                             // angle en degrés

            // Calcul de l'angle p
            teta = 2004.3109 * T - 0.42665 * T * T - 0.041833 * T * T * T; // angle en secondes d'arc
            teta = teta / 3600.0;                                          // angle en degrés

            // Calcul de l'angle A
            A = Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1)) * Math.Sin(Maths.DegToRad(15.0 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1) + dzeta));

            // Calcul de l'angle B
            B = Math.Cos(Maths.DegToRad(teta)) * Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1)) * Math.Cos(Maths.DegToRad(15.0 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1) + dzeta)) - Math.Sin(Maths.DegToRad(teta)) * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1));

            // Calcul de l'angle C
            C = Math.Sin(Maths.DegToRad(teta)) * Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1)) * Math.Cos(Maths.DegToRad(15.0 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1) + dzeta)) + Math.Cos(Maths.DegToRad(teta)) * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1));

            // Calcul de la correction à apporter sur l'ascension droite géocentrique géométrique rapportée à l'équinoxe J2000
            deltaAlpha2 = (Maths.Modulo(Maths.RadToDeg(Math.Atan2(A, B)) + z, TypeAngle.ANGLE_DEGRES_360) / 15.0) - deltaAlpha1 - objetCielProfond.AlphaJ2000.Decimale;

            // Calcul de la correction à apporter sur la déclinaison géocentrique géométrique rapportée à l'équinoxe J2000
            deltaDelta2 = Maths.RadToDeg(Math.Asin(C)) - deltaDelta1 - objetCielProfond.DeltaJ2000.Decimale;
        }
        // Algorithme 5
        /// <summary>
        /// Calcule l’heure à Greenwich (heure TU) correspondant à une heure sidérale vraie à Greenwich à une date donnée par le Jour Julien à 0h TU
        /// à partir de l’obliquité moyenne et des corrections en nutation
        /// Si TU est proche de 0h TU, l'argument a_essai à 1 permet d'essayer d'incrémenter le temps TU de 23h56min04s.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_essai">Incrémentation de l'heure TU de 23h56min04s lorsque cet argument prend une valeur de 1 pour forcer la 2ème solution possible si l'heure TU est proche de 0h.</param>
        protected void CalculerHeuresTULeverCoucher(PositionTemps a_lieuEtDateCalcul, int a_essai)
        {
            // Déclaration des variables de la méthode
            double GSTm, T, T0, A; // variables de calcul

            // Calcul de l'heure sidérale moyenne à Greenwich du lever
            GSTm = HeureSideraleVraieAGreenwichLever - ((a_lieuEtDateCalcul.NutationLongitude * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite))) / 15.0);
            GSTm = Maths.Modulo(GSTm, TypeAngle.ANGLE_HEURES_24);

            // Calcul de l'heure sidérale moyenne à Greenwich à 0h TU
            T  = (a_lieuEtDateCalcul.JourJulien0h - 2451545.0) / 36525.0; // Calcul du nombre de siècles depuis le 1,5 janvier 2000
            T0 = 6.6973745583 + 2400.0513369072 * T + 0.0000258622 * T * T - (1 / 580645161.0) * T * T * T;
            T0 = Maths.Modulo(T0, TypeAngle.ANGLE_HEURES_24);

            // Calcul de l'heure à Greenwich du lever
            A            = GSTm - T0;
            A            = Maths.Modulo(A, TypeAngle.ANGLE_HEURES_24);
            heureTULever = A * 0.9972695663;

            // Cas où la convergence du calcul itératif du lever à échoué (la fonction appelante passe alors l'argument essai à 1)
            if ((heureTULever < ((3.0 / 60.0) + (56.0 / 3600.0))) && (a_essai == 1))
            {
                heureTULever = heureTULever + (23.0 + (56.0 / 60.0) + (4.0 / 3600.0));
                heureTULever = Maths.Modulo(heureTULever, TypeAngle.ANGLE_HEURES_24);
            }

            // Calcul de l'heure sidérale moyenne à Greenwich du coucher
            GSTm = heureSideraleVraieAGreenwichCoucher - ((a_lieuEtDateCalcul.NutationLongitude * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite))) / 15.0);
            GSTm = Maths.Modulo(GSTm, TypeAngle.ANGLE_HEURES_24);

            // Calcul de l'heure à Greenwich du coucher
            A = GSTm - T0;
            A = Maths.Modulo(A, TypeAngle.ANGLE_HEURES_24);
            heureTUCoucher = A * 0.9972695663;

            // Cas où la convergence du calcul itératif du coucher à échoué (la fonction appelante passe alors l'argument essai à 1)
            if ((heureTUCoucher < ((3.0 / 60.0)) + (56.0 / 3600.0)) && (a_essai == 1))
            {
                heureTUCoucher = heureTUCoucher + (23.0 + (56.0 / 60.0) + (4.0 / 3600.0));
                heureTUCoucher = Maths.Modulo(heureTUCoucher, TypeAngle.ANGLE_HEURES_24);
            }

            // Cas où le corps céleste est TOUJOURS VISIBLE ou TOUJOURS INVISIBLE, forçage de l'heure TU à TOUJOURS_VISIBLE ou TOUJOURS_INVISIBLE
            if (heureSideraleVraieLocaleLever == TOUJOURS_VISIBLE)
            {
                heureTULever = TOUJOURS_VISIBLE;
            }
            if (heureSideraleVraieLocaleLever == TOUJOURS_INVISIBLE)
            {
                heureTULever = TOUJOURS_INVISIBLE;
            }
            if (heureSideraleVraieLocaleCoucher == TOUJOURS_VISIBLE)
            {
                heureTUCoucher = TOUJOURS_VISIBLE;
            }
            if (heureSideraleVraieLocaleCoucher == TOUJOURS_INVISIBLE)
            {
                heureTUCoucher = TOUJOURS_INVISIBLE;
            }
        }
        // ***** ALGORITHME 17 *****
        /// <summary>
        /// Calcule les corrections dues à la précession à apporter sur les coordonnées écliptiques géocentriques géométriques d’un corps céleste rapportées
        /// à l’équinoxe J2000 à partir du Jour Julien des Ephémérides correspondant à la sate et l’heure considérées et des coordonnées écliptiques géocentriques
        /// géométriques du corps céleste rapportées à l’équinoxe J2000.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerPrecessionEcliptiques(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double T, eta, pi, p, A, B, C;      // variables de calcul

            // Calcul du nombre de siècles depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 36525.0;

            // Calcul de l'angle eta
            eta = 47.0029 * T - 0.03302 * T * T + 0.000060 * T * T * T; // angle en secondes d'arc
            eta = eta / 3600.0;                                         // angle en degrés

            // Calcul de l'angle pi
            pi = 174.876384 - 869.8089 * T + 0.03536 * T * T; // angle en secondes d'arc
            pi = pi / 3600.0;                                 // angle en degrés

            // Calcul de l'angle p
            p = 5029.0966 * T + 1.11113 * T * T - 0.000006 * T * T * T; // angle en secondes d'arc
            p = p / 3600.0;                                             // angle en degrés

            // Calcul de l'angle A
            A = Math.Cos(Maths.DegToRad(eta)) * Math.Cos(Maths.DegToRad(betaGeometrique)) * Math.Sin(Maths.DegToRad(pi - lambdaGeometrique)) - Math.Sin(Maths.DegToRad(eta)) * Math.Sin(Maths.DegToRad(betaGeometrique));

            // Calcul de l'angle B
            B = Math.Cos(Maths.DegToRad(betaGeometrique)) * Math.Cos(Maths.DegToRad(pi - lambdaGeometrique));

            // Calcul de l'angle C
            C = Math.Cos(Maths.DegToRad(eta)) * Math.Sin(Maths.DegToRad(betaGeometrique)) + Math.Sin(Maths.DegToRad(eta)) * Math.Cos(Maths.DegToRad(BetaGeometrique)) * Math.Sin(Maths.DegToRad(pi - lambdaGeometrique));

            // Calcul de la correction à apporter sur la longitude écliptique géocentrique géométrique rapportée à l'équinoxe J2000
            deltaLambda2 = Maths.Modulo(p + pi - Maths.RadToDeg(Math.Atan2(A, B)), TypeAngle.ANGLE_DEGRES_360) - lambdaGeometrique;

            // Calcul de la correction à apporter sur la latitude écliptique géocentrique géométrique rapportée à l'équinoxe J2000
            deltaBeta2 = Maths.RadToDeg(Math.Asin(C)) - betaGeometrique;
        }
        // ***** ALGORITHME 38 *****
        /// <summary>
        /// Calcule l’anomalie vraie et le rayon vecteur d’une comète non périodique rapportés à l’équinoxe J2000 à partir du Jour Julien des Ephémérides
        /// correspondant à la date et l’heure considérées, de la distance de la comète à la Terre, du Jour Julien des Ephémérides du passage de la
        /// comète au périhélie et du périhélie de la comète.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerAnomalieVraieEtRayonVecteurParabolique(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double D, W, s;   // variables de calcul
            double precision; // variable de calcul

            // Calcul du nombre de jours écoulés depuis le passage de la comète au périhélie
            D = (a_lieuEtDateCalcul.JourJulienEphemerides - 0.0057755183 * r) - jourJulienEphemeridePP;

            // Calcul du paramètre W
            W = (0.03649116245 * D) / (parametresOrbitaux.Perihelie * Math.Sqrt(parametresOrbitaux.Perihelie)); // W est en radians

            // Calcul du paramètre s (s*s*s +3s -W = 0)
            s = W / 3.0;
            do
            {
                s         = (2 * s * s * s + W) / (3 * (s * s + 1));
                precision = s * s * s + 3 * s - W;
            }while (precision > 0.0000000001 || precision < -0.0000000001);

            // Calcul de l'anomalie vraie de la comète rapportée à l'équinoxe J2000
            anomalieVraie = new Angle(Maths.RadToDeg(2 * Math.Atan(s)), TypeAngle.ANGLE_DEGRES_360);

            // Calcul du rayon vecteur de la comète
            rSoleil = parametresOrbitaux.Perihelie * (1 + s * s);
        }
        // Algorithme 7
        /// <summary>
        /// Calcule les heures sidérales vraies de lever et de coucher à Greenwich à partir des heures sidérales vraies locales de lever et de coucher et de la longitude du lieu d’observation.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(PositionTemps a_lieuEtDateCalcul)
        {
            // Calcul des heures sidérales vraies à Greenwich de lever et de coucher
            heureSideraleVraieAGreenwichLever   = heureSideraleVraieLocaleLever - (a_lieuEtDateCalcul.LieuObservation.Longitude.Decimale / 15.0);
            heureSideraleVraieAGreenwichLever   = Maths.Modulo(heureSideraleVraieAGreenwichLever, TypeAngle.ANGLE_HEURES_24);
            heureSideraleVraieAGreenwichCoucher = heureSideraleVraieLocaleCoucher - (a_lieuEtDateCalcul.LieuObservation.Longitude.Decimale / 15.0);
            heureSideraleVraieAGreenwichCoucher = Maths.Modulo(heureSideraleVraieAGreenwichCoucher, TypeAngle.ANGLE_HEURES_24);

            // Cas où le corps céleste est TOUJOURS VISIBLE ou TOUJOURS INVISIBLE, forçage de l'heure GST à TOUJOURS_VISIBLE ou TOUJOURS_INVISIBLE
            if (heureSideraleVraieLocaleLever == TOUJOURS_VISIBLE)
            {
                heureSideraleVraieAGreenwichLever = TOUJOURS_VISIBLE;
            }
            if (heureSideraleVraieLocaleLever == TOUJOURS_INVISIBLE)
            {
                heureSideraleVraieAGreenwichLever = TOUJOURS_INVISIBLE;
            }
            if (heureSideraleVraieLocaleCoucher == TOUJOURS_VISIBLE)
            {
                heureSideraleVraieAGreenwichCoucher = TOUJOURS_VISIBLE;
            }
            if (heureSideraleVraieLocaleCoucher == TOUJOURS_INVISIBLE)
            {
                heureSideraleVraieAGreenwichCoucher = TOUJOURS_INVISIBLE;
            }
        }
        // METHODES PRIVEES
        /// <summary>
        /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
        /// <param name="a_essai">Incrémentation de l'heure TU de 23h56min04s lorsque cet argument prend une valeur de 1 pour forcer la 2ème solution possible si l'heure TU est proche de 0h.</param>
        private void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil, int a_essai)
        {
            // Déclaration des variables locales de la méthode
            double distanceCalculPrecedent; // variable de calcul
            double precision;               // variable de calcul

            do
            {
                distanceCalculPrecedent = r;
                CalculerCoordonneesEcliptiquesEtRayonVecteur(a_lieuEtDateCalcul, type); // Algorithme 33
                CalculerDistanceALaTerre(a_terreSoleil);                                // Algorithme 34
                precision = r - distanceCalculPrecedent;
            } while (precision > 0.0000000001 || precision < -0.0000000001);


            CalculerCoordonneesEcliptiquesGeocentriquesGeometriques(a_terreSoleil);                    // Algorithme 15
            CalculerCorrectionsCoordonneesEcliptiquesAberration(a_lieuEtDateCalcul, a_terreSoleil);    // Algorithme 20
            CalculerCoordonneesEcliptiquesGeocentriques(a_lieuEtDateCalcul, deltaLambda4, deltaBeta4); // Algorithme 22
            ConvertirCoordonneesEcliptiquesVersEquatoriales(a_lieuEtDateCalcul);                       // Algorithme 12
            ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, true);                // Algorithme 13
            CalculerRefractionAtmospherique(a_lieuEtDateCalcul);                                       // Algorithme 24
            ConvertirCoordonneesHorizontalesVersEquatoriales(a_lieuEtDateCalcul);                      // Algorithme 14
            CalculerCorrectionCoordonneesEquatorialesRefraction();                                     // Algorithme 25
            CalculerCorrectionCoordonneesEquatorialesParallaxe(a_lieuEtDateCalcul);                    // Algorithme 26
            CalculerCoordonneesEquatorialesTopocentriques();                                           // Algorithme 27
            ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, false);               // Algorithme 13
            CalculerTaillePhaseMagnitude(a_lieuEtDateCalcul, a_terreSoleil);                           // Algorithme 35
            CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul, r, taille.Decimale);      // Algorithme 28
            CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(a_lieuEtDateCalcul);                   // Algorithme 7
            CalculerHeuresTULeverCoucher(a_lieuEtDateCalcul, a_essai);                                 // Algorithme 5
            CalculerHeuresLocalesLeverCoucher(a_lieuEtDateCalcul);                                     // Algorithme 2
        }
        // Algorithme 28
        /// <summary>
        /// Calcule les heures sidérales vraies et les azimuts topocentriques de lever et de coucher d’un corps céleste à partir des coordonnées équatoriales géocentriques, de la latitude du lieu d’observation
        /// et dans le cas des corps du système solaire (en particulier le Soleil et la Lune) de la distance à la Terre et de la taille apparente.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_r">Distance à la Terre du corps céleste (cas des corps célestes dans le système solaire), mettre n'importe quelle valeur autrement ou utiliser la méthode surchargée).</param>
        /// <param name="a_taille">Taille apparente du corps céleste (cas des corps célestes dans le système solaire), mettre n'importe quelle valeur autrement ou utiliser la méthode surchargée).</param>
        protected void CalculerHeuresSideralesEtAzimutsLeverCoucher(PositionTemps a_lieuEtDateCalcul, double a_r, double a_taille)
        {
            // Déclaration des variables de la méthode
            double parallaxe, nu, cosH, H; // variables de calcul

            // Calcul de la parallaxe
            switch (type)
            {
            case TypeCorpsCeleste.J2000:
                parallaxe = 0.0;
                break;

            case TypeCorpsCeleste.LUNE:
                parallaxe = Maths.RadToDeg(Math.Asin((6378.14 / a_r)));
                break;

            default:
                parallaxe = Maths.RadToDeg(Math.Asin((Math.Sin(Maths.DegToRad(8.794 / 3600.0)) / a_r)));
                break;
            }

            // Calcul du paramètre nu
            nu = parallaxe - (34.0 / 60.0) - (a_taille / 2.0);

            // Calcul de l'angle horaire
            cosH = (Math.Sin(Maths.DegToRad(nu)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)))
                   / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(declinaisonGeocentrique.Decimale)));
            if (cosH < -1) // Cas où le corps céleste est toujours visible
            {
                heureSideraleVraieLocaleLever   = TOUJOURS_VISIBLE;
                heureSideraleVraieLocaleCoucher = TOUJOURS_VISIBLE;
            }
            if (cosH > 1) // Cas où le corps céleste est toujours invisible
            {
                heureSideraleVraieLocaleLever   = TOUJOURS_INVISIBLE;
                heureSideraleVraieLocaleCoucher = TOUJOURS_INVISIBLE;
            }

            if ((cosH > -1) && (cosH < 1)) // Cas où le corps céleste se lève et se couche
            {
                H = Maths.RadToDeg(Math.Acos(cosH));
                H = H / 15.0; // H en heures

                // Calcul de l'heure sidérale vraie locale et de l'azimut de lever
                heureSideraleVraieLocaleLever = ascensionDroiteGeocentrique.Decimale - H;
                heureSideraleVraieLocaleLever = Maths.Modulo(heureSideraleVraieLocaleLever, TypeAngle.ANGLE_HEURES_24);
                azimutLever = Maths.RadToDeg(Math.Acos((Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - Math.Sin(Maths.DegToRad(nu)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)))
                                                       / (Math.Cos(Maths.DegToRad(nu)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)))));

                // Calcul de l'heure sidérale vraie locale et de l'azimut de coucher
                heureSideraleVraieLocaleCoucher = ascensionDroiteGeocentrique.Decimale + H;
                heureSideraleVraieLocaleCoucher = Maths.Modulo(heureSideraleVraieLocaleCoucher, TypeAngle.ANGLE_HEURES_24);
                azimutCoucher = 360.0 - azimutLever;
            }
        }
        // ***** ALGORITHME 37 *****
        /// <summary>
        /// Calcule l’anomalie moyenne de la comète périodique à partir du Jour Julien des Ephémérides correspondant à la date et l’heure considérées,
        /// de la distance de la comète à la Terre, du Jour Julien des Ephémérides du passage de la comète au périhélie et de la période orbitale de la comète.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerAnomalieMoyenne(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double D; // variable de calcul

            // Calcul du nombre de jours écoulés depuis le passage de la comète au périhélie
            D = (a_lieuEtDateCalcul.JourJulienEphemerides - 0.0057755183 * r) - jourJulienEphemeridePP;

            // Calcul de l'anomalie moyenne de la comète
            anomalieMoyenne = new Angle((360.0 / 365.242191) * (D / periodeOrbitale), TypeAngle.ANGLE_DEGRES_360);
        }
        // METHODES PRIVEES
        /// <summary>
        /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
        /// <param name="a_essai">Incrémentation de l'heure TU de 23h56min04s lorsque cet argument prend une valeur de 1 pour forcer la 2ème solution possible si l'heure TU est proche de 0h.</param>
        private void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil, int a_essai)
        {
            // Déclaration des variables locales de la méthode
            double distanceCalculPrecedent;                 // variable de calcul
            double precision;                               // variable de calcul

            if (type == TypeCorpsCeleste.COMETE_PERIODIQUE) // Cas d'une comète périodique
            {
                do
                {
                    // Affectation de la distance précédemment calculée à la variable distance_calcul_precedent
                    distanceCalculPrecedent = r;
                    CalculerAnomalieMoyenne(a_lieuEtDateCalcul);    // Algorithme 37
                    CalculerAnomalieVraieEtRayonVecteur();          // Algorithme 31
                    CalculerCoordonneesEcliptiqueHeliocentriques(); // Algorithme 32
                    CalculerDistanceALaTerre(a_terreSoleil);        // Algorithme 34
                    // Calcul de la précision sur la distance de la comète
                    precision = r - distanceCalculPrecedent;
                }while (precision > 0.0000000001 || precision < -0.0000000001);
            }
            else // Cas d'une comète périodique
            {
                do
                {
                    // Affectation de la distance précédemment calculée à la variable distance_calcul_precedent
                    distanceCalculPrecedent = r;
                    CalculerAnomalieVraieEtRayonVecteurParabolique(a_lieuEtDateCalcul); // Algorithme 38
                    CalculerCoordonneesEcliptiqueHeliocentriques();                     // Algorithme 32
                    CalculerDistanceALaTerre(a_terreSoleil);                            // Algorithme 34
                    // Calcul de la précision sur la distance de la comète
                    precision = r - distanceCalculPrecedent;
                }while (precision > 0.0000000001 || precision < -0.0000000001);
            }

            CalculerCoordonneesEcliptiquesGeocentriquesGeometriques(a_terreSoleil);                                              // Algorithme 15
            CalculerPrecessionEcliptiques(a_lieuEtDateCalcul);                                                                   // Algorithme 17
            CalculerCorrectionsCoordonneesEcliptiquesAberration(a_lieuEtDateCalcul, a_terreSoleil);                              // Algorithme 20
            CalculerCoordonneesEcliptiquesGeocentriques(a_lieuEtDateCalcul, deltaLambda4, deltaBeta4, deltaLambda2, deltaBeta2); // Algorithme 22
            ConvertirCoordonneesEcliptiquesVersEquatoriales(a_lieuEtDateCalcul);                                                 // Algorithme 12
            ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, true);                                          // Algorithme 13
            CalculerRefractionAtmospherique(a_lieuEtDateCalcul);                                                                 // Algorithme 24
            ConvertirCoordonneesHorizontalesVersEquatoriales(a_lieuEtDateCalcul);                                                // Algorithme 14
            CalculerCorrectionCoordonneesEquatorialesRefraction();                                                               // Algorithme 25
            CalculerCorrectionCoordonneesEquatorialesParallaxe(a_lieuEtDateCalcul);                                              // Algorithme 26
            CalculerCoordonneesEquatorialesTopocentriques();                                                                     // Algorithme 27
            ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, false);                                         // Algorithme 13
            CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul, r, 0);                                              // Algorithme 28
            CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(a_lieuEtDateCalcul);                                             // Algorithme 7
            CalculerHeuresTULeverCoucher(a_lieuEtDateCalcul, a_essai);                                                           // Algorithme 5
            CalculerHeuresLocalesLeverCoucher(a_lieuEtDateCalcul);                                                               // Algorithme 2
        }
        // ***** ALGORITHME 19 *****
        /// <summary>
        /// Calcule les corrections dues à la nutation à apporter sur les coordonnées équatoriales géocentriques géométriques d’un corps céleste à partir de l’obliquité moyenne,
        /// de la nutation en longitude écliptique, de la nutation en obliquité, des coordonnées équatoriales géocentriques géométriques du corps céleste à l’époque J2000,
        /// des corrections dues au mouvement propre et des corrections dues à la précession.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerCorrectionCoordonneesEquatorialesNutation(PositionTemps a_lieuEtDateCalcul)
        {
            // Calcul de la correction à apporter sur l'ascension droite géométrique
            deltaAlpha3 = (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne)) + Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne)) * Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                           * Math.Tan(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2))) * (a_lieuEtDateCalcul.NutationLongitude * 3600.0)
                          - (Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2))) * Math.Tan(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2))) * (a_lieuEtDateCalcul.NutationObliquite * 3600.0); // correction en seconde d'arc de degrés

            deltaAlpha3 = deltaAlpha3 / 54000.0;                                                                                                                                                                                                                                // correction en heure

            // Calcul de la correction à apporter sur la déclinaison géométrique
            deltaDelta3 = (Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne)) * Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))) * (a_lieuEtDateCalcul.NutationLongitude * 3600.0)
                          + Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2))) * (a_lieuEtDateCalcul.NutationObliquite * 3600.0); // correction en secondes d'arc

            deltaDelta3 = deltaDelta3 / 3600.0;                                                                                                                                  // correction en degrés
        }
        // ***** ALGORITHME 16 *****
        /// <summary>
        /// Calcule les corrections dues au mouvement propre d’un corps céleste à apporter sur les coordonnées équatoriales géocentriques géométriques à l’époque J2000 d’un corps céleste
        /// à partir du Jour Julien des Ephémérides correspondant à la date et l’heure considérées, des mouvements propres annuels du corps céleste en ascension droite et déclinaison et
        /// de la déclinaison géocentrique géométrique du corps céleste à l’époque J2000.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        private void CalculerMouvementPropre(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double T; // variable de calcul

            // Calcul du nombre d'années écoulées depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 365.25;

            // Calcul de la correction à apporter sur l'ascension droite géocentrique géométrique à l'époque J2000
            deltaAlpha1 = T * (objetCielProfond.MouvementPropreAlpha / (1000.0 * Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale)))); // correction en s
            deltaAlpha1 = deltaAlpha1 / 3600.0;                                                                                                    // correction en h

            // Calcul de la correction à apporter sur la déclinaison géocentrique géométrique à l'époque J2000
            deltaDelta1 = T * (objetCielProfond.MouvementPropreDelta / 1000.0); // correction en s
            deltaDelta1 = deltaDelta1 / 3600.0;                                 // correction en degrés
        }
Beispiel #16
0
 // METHODES PUBLIQUES
 /// <summary>
 /// Calcule les paramètres de la Terre-Soleil pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
 /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
 /// </summary>
 /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
 public void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul)
 {
     CalculerCoordonneesEcliptiquesEtRayonVecteur(a_lieuEtDateCalcul, TypeCorpsCeleste.TERRE_SOLEIL); // Algorithme 8
     ConvertirCoordonneesEcliptiquesVersEquatoriales(a_lieuEtDateCalcul);                             // Algorithme 12
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, true);                      // Algorithme 13
     CalculerRefractionAtmospherique(a_lieuEtDateCalcul);                                             // Algorithme 24
     ConvertirCoordonneesHorizontalesVersEquatoriales(a_lieuEtDateCalcul);                            // Algorithme 14
     CalculerCorrectionCoordonneesEquatorialesRefraction();                                           // Algorithme 25
     CalculerCorrectionCoordonneesEquatorialesParallaxe(a_lieuEtDateCalcul);                          // Algorithme 26
     CalculerCoordonneesEquatorialesTopocentriques();                                                 // Algorithme 27
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, false);                     // Algorithme 13
     CalculerTailleApparente();                                                                       // Algorithme 29
     CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul, r, taille.Decimale);            // Algorithme 28
     CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(a_lieuEtDateCalcul);                         // Algorithme 7
     CalculerHeuresTULeverCoucher(a_lieuEtDateCalcul, 0);                                             // Algorithme 5
     CalculerHeuresLocalesLeverCoucher(a_lieuEtDateCalcul);                                           // Algorithme 2
 }
 // METHODES PRIVEES
 /// <summary>
 /// Calcule les paramètres d'un objet du cie profond pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
 /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
 /// </summary>
 /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
 /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
 private void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil, int a_essai)
 {
     CalculerMouvementPropre(a_lieuEtDateCalcul);                                            // Algorithme 16
     CalculerCorrectionCoordonneesEquatorialesPrecession(a_lieuEtDateCalcul);                // Algorithme 18P
     CalculerCorrectionCoordonneesEquatorialesNutation(a_lieuEtDateCalcul);                  // Algorithme 19
     CalculerCorrectionCoordonneesEquatorialesAberration(a_lieuEtDateCalcul, a_terreSoleil); // Algorithme 21
     CalculerCoordonneesEquatorialesGeocentriques();                                         // Algorithme 23
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, true);             // Algorithme 13
     CalculerRefractionAtmospherique(a_lieuEtDateCalcul);                                    // Algorithme 24
     ConvertirCoordonneesHorizontalesVersEquatoriales(a_lieuEtDateCalcul);                   // Algorithme 14
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, false);            // Algorithme 13
     CalculerMagnitudeApparente();                                                           // Algorithme 39
     CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul);                       // Algorithme 28
     CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(a_lieuEtDateCalcul);                // Algorithme 7
     CalculerHeuresTULeverCoucher(a_lieuEtDateCalcul, a_essai);                              // Algorithme 5
     CalculerHeuresLocalesLeverCoucher(a_lieuEtDateCalcul);                                  // Algorithme 2
 }
 // METHODES PRIVEES
 /// <summary>
 /// Calcule les paramètres de la Lune pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
 /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
 /// </summary>
 /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
 /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
 /// <param name="a_essai">Incrémentation de l'heure TU de 23h56min04s lorsque cet argument prend une valeur de 1 pour forcer la 2ème solution possible si l'heure TU est proche de 0h.</param>
 public void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil, int a_essai)
 {
     CalculerCoordoonneesEcliptiquesEtRayonVecteur(a_lieuEtDateCalcul);                    // Algorithme 40
     ConvertirCoordonneesEcliptiquesVersEquatoriales(a_lieuEtDateCalcul);                  // Algorithme 12
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, true);           // Algorithme 13
     CalculerRefractionAtmospherique(a_lieuEtDateCalcul);                                  // Algorithme 24
     ConvertirCoordonneesHorizontalesVersEquatoriales(a_lieuEtDateCalcul);                 // Algorithme 14
     CalculerCorrectionCoordonneesEquatorialesRefraction();                                // Algorithme 25
     CalculerCorrectionCoordonneesEquatorialesParallaxe(a_lieuEtDateCalcul);               // Algorithme 26
     CalculerCoordonneesEquatorialesTopocentriques();                                      // Algorithme 27
     ConvertirCoordonneesEquatorialesVersHorizontales(a_lieuEtDateCalcul, false);          // Algorithme 13
     CalculerPhaseEtTailleApparenteLune(a_terreSoleil);                                    // Algorithme 41
     CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul, r, taille.Decimale); // Algorithme 28
     CalculerHeuresSideralesVraiesAGreenwichLeverCoucher(a_lieuEtDateCalcul);              // Algorithme 7
     CalculerHeuresTULeverCoucher(a_lieuEtDateCalcul, 0);                                  // Algorithme 5
     CalculerHeuresLocalesLeverCoucher(a_lieuEtDateCalcul);                                // Algorithme 2
 }
Beispiel #19
0
        // Algorithme 20
        /// <summary>
        /// Calcule les corrections dues à l’aberration de la lumière à apporter sur les coordonnées écliptiques géocentriques géométriques d’une planète
        /// ou d’une comète à partir du Jour Julien des Ephémérides, de la longitude écliptique géocentrique géométrique du Soleil et des coordonnées écliptiques
        /// géocentriques géométriques de la planète ou de la comète.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet représentant la Terre/le Soleil.</param>
        private void CalculerCorrectionsCoordonneesEcliptiquesAberration(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil)
        {
            // Déclaration des variables de la méthode
            double T, et, pit; // variables de calcul

            // Calcul du nombre de siècles depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 36525.0;

            // Calcul de l'excentricité de l'orbite de la Terre
            et = 0.016708617 - 0.000042037 * T - 0.0000001236 * T * T + 0.00000000004 * T * T * T;

            // Calcul de la longitude du perihélie de la Terre
            pit = 102.937348 + 1.7195269 * T + 0.00045962 * T * T + 0.000000499 * T * T * T;

            // Calcul de la correction à apporter sur la longitude écliptique géocentrique géométrique de la planète ou de la comète
            deltaLambda4 = (-20.49552 * Math.Cos(Maths.DegToRad(a_terreSoleil.LambdaGeometrique - lambdaGeometrique)) + 20.49552 * et * Math.Cos(Maths.DegToRad(pit - lambdaGeometrique))) / Math.Cos(Maths.DegToRad(betaGeometrique));

            // Calcul de la correction à apporter sur la latitude écliptique géocentrique géométrique de la planète ou de la comète
            deltaBeta4  = -20.49552 * Math.Sin(Maths.DegToRad(betaGeometrique)) * (Math.Sin(Maths.DegToRad(a_terreSoleil.LambdaGeometrique - lambdaGeometrique)) - et * Math.Sin(Maths.DegToRad(pit - lambdaGeometrique)));
            deltaBeta4 /= 3600.0;
        }
Beispiel #20
0
        // Algorithme 12
        /// <summary>
        /// Calcule les coordonnées écliptiques géocentriques d’un corps céleste en coordonnées équatoriales géocentriques à partir de l’obliquité moyenne et de la nutation en obliquité.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void ConvertirCoordonneesEcliptiquesVersEquatoriales(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double x, y;    // variables de calcul

            // Calcul de la déclinaison géocentrique
            double declGeo = Math.Asin((Math.Sin(Maths.DegToRad(beta.Decimale)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)))
                                       + (Math.Cos(Maths.DegToRad(beta.Decimale)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)) * Math.Sin(Maths.DegToRad(lambda.Decimale))));

            declGeo = Maths.RadToDeg(declGeo);
            declinaisonGeocentrique = new Angle(declGeo, TypeAngle.ANGLE_DEGRES_90);

            // Calcul de l'ascension droite géocentrique
            y = (Math.Sin(Maths.DegToRad(lambda.Decimale)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite))) - (Math.Tan(Maths.DegToRad(beta.Decimale)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)));
            x = Math.Cos(Maths.DegToRad(lambda.Decimale));
            double alphaGeo = Math.Atan2(y, x);

            alphaGeo = Maths.RadToDeg(alphaGeo);
            alphaGeo = Maths.Modulo(alphaGeo, TypeAngle.ANGLE_DEGRES_360) / 15.0;
            ascensionDroiteGeocentrique = new Angle(alphaGeo, TypeAngle.ANGLE_HEURES_24);
        }
        // Algorithme 24
        /// <summary>
        /// Calcule la correction due à la réfraction atmosphérique à apporter sur l’altitude géocentrique d’un corps céleste à partir de l’altitude géocentrique, de la pression
        /// et de la température ambiante du lieu d’observation. En cas de non disponibilité de ces données, des valeurs par défaut (1013mbar pour la pression et 10°C pour la température)
        /// sont utilisées.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void CalculerRefractionAtmospherique(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double z, R = 0.0; // variables de calcul

            // Calcul de l'angle au zénith
            z = 90.0 - altitudeGeocentrique.Decimale;

            // Calcul de la réfraction atmosphérique
            if (altitudeGeocentrique.Decimale >= 15.0)
            {
                R = (0.00452 * (double)a_lieuEtDateCalcul.LieuObservation.Pression * Math.Tan(Maths.DegToRad(z))) / (273.0 + (double)a_lieuEtDateCalcul.LieuObservation.Temperature);
            }
            else
            {
                R = (a_lieuEtDateCalcul.LieuObservation.Pression * (0.1594 + 0.0196 * altitudeGeocentrique.Decimale + 0.00002 * altitudeGeocentrique.Decimale * altitudeGeocentrique.Decimale))
                    / ((273.0 + (double)a_lieuEtDateCalcul.LieuObservation.Temperature) * (1 + 0.505 * altitudeGeocentrique.Decimale + 0.0845 * altitudeGeocentrique.Decimale * altitudeGeocentrique.Decimale));
            }

            // Calcul de l'altitude topocentrique corrigée de la réfraction atmosphérique
            altitudeTopocentrique = new Angle(altitudeGeocentrique.Decimale + R, TypeAngle.ANGLE_DEGRES_90);
            azimutTopocentrique   = new Angle(azimutGeocentrique.Decimale, TypeAngle.ANGLE_DEGRES_360);
        }
        // ***** ALGORITHME 21 *****
        /// <summary>
        /// Calcule les corrections dues à l’aberration de la lumière à apporter sur les coordonnées équatoriales géocentriques géométriques d’un corps céleste à partir du Jour Julien des Ephémérides correspondant
        /// à la date et l’heure considérées, de la longitude écliptique géocentrique géométrique du Soleil, de l’obliquité moyenne, de la nutation en obliquité, des coordonnées équatoriales géocentriques
        /// géométriques du corps céleste à l’époque J2000, des corrections dues au mouvement propre et des corrections dues à la précession.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
        private void CalculerCorrectionCoordonneesEquatorialesAberration(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil)
        {
            // Déclaration des variables de la méthode
            double T, et, pit; // variables de calcul

            // Calcul du nombre de siècles depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 36525.0;

            // Calcul de l'excentricité de l'orbite de la Terre
            et = 0.016708617 - 0.000042037 * T - 0.0000001236 * T * T + 0.00000000004 * T * T * T;

            // Calcul de la longitude du perihélie de la Terre
            pit = 102.937348 + 1.7195269 * T + 0.00045962 * T * T + 0.000000499 * T * T * T;

            // Calcul de la correction à apporter sur la longitude écliptique géocentrique géométrique
            deltaAlpha4 = -20.49552 * ((Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2))) * Math.Cos(Maths.DegToRad(a_terreSoleil.LambdaGeometrique))
                                        * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)) + Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                                        * Math.Sin(Maths.DegToRad(a_terreSoleil.LambdaGeometrique))) / Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)))
                          + 20.49552 * et * ((Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2))) * Math.Cos(Maths.DegToRad(pit))
                                              * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)) + Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2))) * Math.Sin(Maths.DegToRad(pit)))
                                             / Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)));

            deltaAlpha4 = deltaAlpha4 / 54000.0; // corrections en heure

            // Calcul de la correction à apporter sur la déclinaison géocentrique géométrique
            deltaDelta4 = -20.49552 * (Math.Cos(Maths.DegToRad(a_terreSoleil.LambdaGeometrique)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)) * (Math.Tan(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite))
                                                                                                                                                                                                           * Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)) - Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                                                                                                                                                                                                           * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2))) + Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                                       * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)) * Math.Sin(Maths.DegToRad(a_terreSoleil.LambdaGeometrique)))
                          + 20.49552 * et * (Math.Cos(Maths.DegToRad(pit)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite)) * (Math.Tan(Maths.DegToRad(a_lieuEtDateCalcul.ObliquiteMoyenne + a_lieuEtDateCalcul.NutationObliquite))
                                                                                                                                                                                     * Math.Cos(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)) - Math.Sin(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                                                                                                                                                                                     * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2))) + Math.Cos(Maths.DegToRad(15 * (objetCielProfond.AlphaJ2000.Decimale + deltaAlpha1 + deltaAlpha2)))
                                             * Math.Sin(Maths.DegToRad(objetCielProfond.DeltaJ2000.Decimale + deltaDelta1 + deltaDelta2)) * Math.Sin(Maths.DegToRad(pit))); // correction en secondes d'arc

            deltaDelta4 = deltaDelta4 / 3600.0;                                                                                                                             // corrections en degrés
        }
        // METHODES PUBLIQUES
        //Aucune

        // METHODES PROTEGEES
        // Algorithme 2
        /// <summary>
        /// Calcule l’heure locale du point d’observation à partir de la date et de l’heure à Greenwich, c’est-à-dire la date
        /// et l’heure TU, et du décalage horaire dû au fuseau horaire (en France +1h) et aux économies d’énergie liées
        /// à l’heure d’été et à l’heure d’hiver (en France +1h en été et 0h en hiver).
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        protected void CalculerHeuresLocalesLeverCoucher(PositionTemps a_lieuEtDateCalcul)
        {
            // Calcul de l'heure locale de lever
            double heureCalculee = heureTULever + (double)a_lieuEtDateCalcul.ZoneHoraire + (double)a_lieuEtDateCalcul.ChangementHeure;

            heureCalculee = Maths.Modulo(heureCalculee, TypeAngle.ANGLE_HEURES_24);
            int nombreHeure  = (int)heureCalculee;
            int nombreMinute = (int)Math.Round((60.0 * (heureCalculee - (double)nombreHeure)), 0);

            if (nombreMinute == 60)
            {
                nombreMinute = 0;
                nombreHeure += 1;
                if (nombreHeure == 24)
                {
                    nombreHeure = 0;
                }
            }
            heureLocaleLever = new DateTime(a_lieuEtDateCalcul.HeureLocale.Year, a_lieuEtDateCalcul.HeureLocale.Month, a_lieuEtDateCalcul.HeureLocale.Day, nombreHeure, nombreMinute, 0);

            // Calcul de l'heure locale de coucher
            heureCalculee = heureTUCoucher + (double)a_lieuEtDateCalcul.ZoneHoraire + (double)a_lieuEtDateCalcul.ChangementHeure;
            heureCalculee = Maths.Modulo(heureCalculee, TypeAngle.ANGLE_HEURES_24);
            nombreHeure   = (int)heureCalculee;
            nombreMinute  = (int)Math.Round((60.0 * (heureCalculee - (double)nombreHeure)), 0);
            if (nombreMinute == 60)
            {
                nombreMinute = 0;
                nombreHeure += 1;
                if (nombreHeure == 24)
                {
                    nombreHeure = 0;
                }
            }
            heureLocaleCoucher = new DateTime(a_lieuEtDateCalcul.HeureLocale.Year, a_lieuEtDateCalcul.HeureLocale.Month, a_lieuEtDateCalcul.HeureLocale.Day, nombreHeure, nombreMinute, 0);
        }
 // Méthode surchargée
 /// <summary>
 /// Calcule les heures sidérales vraies et les azimuts topocentriques de lever et de coucher d’un corps céleste à partir des coordonnées équatoriales géocentriques, de la latitude du lieu d’observation.
 /// Le calcul par cette version surchargée ne tient pas compte de la distance à la Terre et de la taille apparente (cas des corps du système solaire).
 /// Pour prendre en compte la distance à la Terre et la taille apparente, utiliser la version surchargée avec ces paramètres en argument.
 /// </summary>
 /// <param name="a_lieuEtDateCalcul"></param>
 protected void CalculerHeuresSideralesEtAzimutsLeverCoucher(PositionTemps a_lieuEtDateCalcul)
 {
     CalculerHeuresSideralesEtAzimutsLeverCoucher(a_lieuEtDateCalcul, double.MaxValue, 0.0);
 }
        // ***** ALGORITHME 40P *****
        private void CalculerCoordoonneesEcliptiquesEtRayonVecteur(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double T, ll, Dl, Ms, Ml, Fl, A1, A2, A3, e;                  // variable de calcul
            int    i;                                                     // variable de comptage pour les boucles de calcul
            double argument, somme_l = 0.0, somme_b = 0.0, somme_r = 0.0; // variable de calcul

            // Calcul du nombre de siècles écoulés depuis le 1,5 janvier 2000
            T = (a_lieuEtDateCalcul.JourJulienEphemerides - 2451545.0) / 36525.0;

            // Calcul de la longitude moyenne de la Lune ll
            ll = 218.316654361 + 481267.88134240 * T - 0.00132675 * T * T + (1 / 538841) * T * T * T - (1 / 65193770) * T * T * T * T;
            ll = Maths.Modulo(ll, TypeAngle.ANGLE_DEGRES_360);

            // Calcul de l'élongation moyenne de la Lune Dl
            Dl = 297.85020420 + 445267.11151675 * T - 0.001630028 * T * T + (1 / 545868) * T * T * T - (1 / 113065327) * T * T * T * T;
            Dl = Maths.Modulo(Dl, TypeAngle.ANGLE_DEGRES_360);

            // Calcul de l'anomalie moyenne du Soleil Ms
            Ms = 357.52910918 + 35999.05029094 * T - 0.000153583 * T * T + (1 / 24489796) * T * T * T;
            Ms = Maths.Modulo(Ms, TypeAngle.ANGLE_DEGRES_360);

            // Calcul de l'anomalie moyenne de la Lune Ml
            Ml = 134.96341138 + 477198.86763133 * T + 0.008997028 * T * T + (1 / 69699) * T * T * T - (1 / 14711892) * T * T * T * T;
            Ml = Maths.Modulo(Ml, TypeAngle.ANGLE_DEGRES_360);

            // Calcul de l'argument de la latitude moyenne de la Lune Fl
            Fl = 93.27209932 + 483202.01752731 * T - 0.003402917 * T * T - (1 / 3525955) * T * T * T + (1 / 863309353) * T * T * T * T;
            Fl = Maths.Modulo(Fl, TypeAngle.ANGLE_DEGRES_360);

            // Calcul du paramètre correcteur A1 dû à Vénus
            A1 = 119.75 + 131.849 * T;
            A1 = Maths.Modulo(A1, TypeAngle.ANGLE_DEGRES_360);

            // Calcul du paramètre correcteur A2 dû à Jupiter
            A2 = 53.09 + 479264.290 * T;
            A2 = Maths.Modulo(A2, TypeAngle.ANGLE_DEGRES_360);

            // Calcul du paramètre correcteur additionnel A3
            A3 = 313.45 + 481266.484 * T;
            A3 = Maths.Modulo(A3, TypeAngle.ANGLE_DEGRES_360);

            // Calcul du paramètre correcteur e dû à l'excentricité de la Terre
            e = 1 - 0.002516 * T - 0.0000074 * T * T;

            // Calcul de la longitude écliptique géométrique et géocentrique de la Lune
            for (i = 0; i < ELP2000_82B_BP.INDEX_MAX_COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP; i++)
            {
                argument = Maths.DegToRad(ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 0] * Dl + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] * Ms + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 2] * Ml + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 3] * Fl);
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 0)
                {
                    somme_l += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 4] * Math.Sin(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == -1 || ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 1)
                {
                    somme_l += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 4] * e *Math.Sin(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == -2 || ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 2)
                {
                    somme_l += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 4] * e *e *Math.Sin(argument);
                }
            }
            somme_l          += 3958 * Math.Sin(Maths.DegToRad(A1)) + 1962 * Math.Sin(Maths.DegToRad(ll - Fl)) + 318 * Math.Sin(Maths.DegToRad(A2));
            lambdaGeometrique = ll + (somme_l / 1000000.0);
            lambdaGeometrique = Maths.Modulo(lambdaGeometrique, TypeAngle.ANGLE_DEGRES_360);
            lambda            = new Angle((lambdaGeometrique + a_lieuEtDateCalcul.NutationLongitude), TypeAngle.ANGLE_DEGRES_360);

            // Calcul de la latitude écliptique géométrique et géocentrique de la Lune
            for (i = 0; i < ELP2000_82B_BP.INDEX_MAX_COEFFICIENT_LATITUDE_LUNE_BP; i++)
            {
                argument = Maths.DegToRad(ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 0] * Dl + ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] * Ms + ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 2] * Ml + ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 3] * Fl);
                if (ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] == 0)
                {
                    somme_b += ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 4] * Math.Sin(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] == -1 || ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] == 1)
                {
                    somme_b += ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 4] * e *Math.Sin(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] == -2 || ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 1] == 2)
                {
                    somme_b += ELP2000_82B_BP.COEFFICIENT_LATITUDE_LUNE_BP[i, 4] * e *e *Math.Sin(argument);
                }
            }
            somme_b        += -2235 * Math.Sin(Maths.DegToRad(ll)) + 382 * Math.Sin(Maths.DegToRad(A3)) + 175 * Math.Sin(Maths.DegToRad(A1 - Fl)) + 127 * Math.Sin(Maths.DegToRad(ll - Ml)) - 115 * Math.Sin(Maths.DegToRad(ll + Ml));
            betaGeometrique = (somme_b / 1000000.0);
            beta            = new Angle(betaGeometrique, TypeAngle.ANGLE_DEGRES_90);

            // Calcul du rayon vecteur de la Lune
            for (i = 0; i < ELP2000_82B_BP.INDEX_MAX_COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP; i++)
            {
                argument = Maths.DegToRad(ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 0] * Dl + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] * Ms + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 2] * Ml + ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 3] * Fl);
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 0)
                {
                    somme_r += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 5] * Math.Cos(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == -1 || ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 1)
                {
                    somme_r += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 5] * e *Math.Cos(argument);
                }
                if (ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == -2 || ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 1] == 2)
                {
                    somme_r += ELP2000_82B_BP.COEFFICIENT_LONGITUDE_RAYON_VECTEUR_LUNE_BP[i, 5] * e *e *Math.Cos(argument);
                }
            }
            r = 385000.56 + (somme_r / 1000.0);
        }
        // Algorithme 13
        /// <summary>
        /// Calcule les coordonnées équatoriales (géocentriques ou topocentriques) d’un corps céleste en coordonnées horizontales (géocentriques ou topocentriques)
        /// à partir de la latitude et de l’heure sidérale locale.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_geocentriqueOuTopocentrique">Type de coordonnées à convertir : géocentriques (true) ou topocentriques (false).</param>
        protected void ConvertirCoordonneesEquatorialesVersHorizontales(PositionTemps a_lieuEtDateCalcul, bool a_geocentriqueOuTopocentrique)
        {
            // Déclaration des variables de la méthode
            double H;   // variable de calcul

            // Cas des coordonnées équatoriales géocentriques
            if (a_geocentriqueOuTopocentrique)
            {
                // Calcul de l'angle horaire H
                H = Maths.CalculerHeureDecimale(a_lieuEtDateCalcul.HeureSideraleLocale) - ascensionDroiteGeocentrique.Decimale;
                H = Maths.Modulo(H, TypeAngle.ANGLE_HEURES_24); // H ramené dans l'intervalle [0h ; 24h]
                H = 15.0 * H;                                   // Conversion de H en degrés

                // Calcul de l'altitude géocentrique
                double altGeo = Math.Asin(Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale))
                                          + Math.Cos(Maths.DegToRad(declinaisonGeocentrique.Decimale)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(H)));
                altGeo = Maths.RadToDeg(altGeo); // Conversion de radians en degrées
                altitudeGeocentrique = new Angle(altGeo, TypeAngle.ANGLE_DEGRES_90);

                // Calcul de l'azimut géocentrique
                if (Math.Sin(Maths.DegToRad(H)) <= 0.0)
                {
                    double azgeo = Math.Acos((Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale))
                                              * Math.Sin(Maths.DegToRad(altitudeGeocentrique.Decimale))) / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(altitudeGeocentrique.Decimale))));
                    azgeo = Maths.RadToDeg(azgeo);
                    azimutGeocentrique = new Angle(azgeo, TypeAngle.ANGLE_DEGRES_360);
                }
                if (Math.Sin(Maths.DegToRad(H)) > 0.0)
                {
                    double azGeo = Math.Acos((Math.Sin(Maths.DegToRad(declinaisonGeocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Sin(Maths.DegToRad(altitudeGeocentrique.Decimale)))
                                             / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(altitudeGeocentrique.Decimale))));
                    azGeo = 360 - Maths.RadToDeg(azGeo);
                    azimutGeocentrique = new Angle(azGeo, TypeAngle.ANGLE_DEGRES_360);
                }
            }
            // Cas des coordonnées équatoriales topocentriques
            else
            {
                // Calcul de l'angle horaire H
                H = Maths.CalculerHeureDecimale(a_lieuEtDateCalcul.HeureSideraleLocale) - AscensionDroiteTopocentrique.Decimale;
                H = Maths.Modulo(H, TypeAngle.ANGLE_HEURES_24); // H ramené dans l'intervalle [0h ; 24h]
                H = 15.0 * H;                                   // Conversion de H en degrés

                // Calcul de l'altitude topocentrique
                double altTop = Math.Asin((Math.Sin(Maths.DegToRad(declinaisonTopocentrique.Decimale)) * Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)))
                                          + (Math.Cos(Maths.DegToRad(declinaisonTopocentrique.Decimale)) * Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(H))));
                altTop = Maths.RadToDeg(altTop); // Conversion de radians en degrées
                altitudeTopocentrique = new Angle(altTop, TypeAngle.ANGLE_DEGRES_90);

                // Calcul de l'azimut topocentrique
                if (Math.Sin(Maths.DegToRad(H)) <= 0.0)
                {
                    double azTop = Math.Acos((Math.Sin(Maths.DegToRad(declinaisonTopocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale))
                                              * Math.Sin(Maths.DegToRad(altitudeTopocentrique.Decimale))) / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(altitudeTopocentrique.Decimale))));
                    azTop = Maths.RadToDeg(azTop);
                    azimutTopocentrique = new Angle(azTop, TypeAngle.ANGLE_DEGRES_360);
                }
                if (Math.Sin(Maths.DegToRad(H)) > 0.0)
                {
                    double azTop = Math.Acos((Math.Sin(Maths.DegToRad(declinaisonTopocentrique.Decimale)) - Math.Sin(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Sin(Maths.DegToRad(altitudeTopocentrique.Decimale)))
                                             / (Math.Cos(Maths.DegToRad(a_lieuEtDateCalcul.LieuObservation.Latitude.Decimale)) * Math.Cos(Maths.DegToRad(altitudeTopocentrique.Decimale))));
                    azTop = 360.0 - Maths.RadToDeg(azTop);
                    azimutTopocentrique = new Angle(azTop, TypeAngle.ANGLE_DEGRES_360);
                }
            }
        }
        // Algorithme 35
        /// <summary>
        /// Calcule la taille apparente, la phase et la magnitude apparente des planètes à partir de la distance des planètes à la Terre,
        /// du rayon vecteur des planètes, de la taille apparente des planètes à 1 UA, de l’altitude topocentrique des planètes et du
        /// rayon vecteur de la Terre.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet représentant la Terre/le Soleil.</param>
        private void CalculerTaillePhaseMagnitude(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil)
        {
            // Déclaration des variables de la méthode
            double i, z;                                                                 // variable de calcul

            double[] taille_1UA = { 6.72, 16.82, 9.36, 196.88, 165.40, 70.04, 67.00 };   // taille apparente des planètes à 1 UA

            // Calcul de l'angle de phase (en radians)
            i = Math.Acos((rSoleil * rSoleil + r * r - a_terreSoleil.R * a_terreSoleil.R) / (2 * rSoleil * r));

            // Calcul de la phase
            phase = (1 + Math.Cos(i)) / 2;

            // Conversion de l'angle de phase en degrés
            i = Maths.RadToDeg(i);

            // Cas de Mercure
            if (type == TypeCorpsCeleste.MERCURE)
            {
                taille = new Angle((float)(taille_1UA[0] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[0] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -0.42 + 5 * Math.Log10(rSoleil * r) + 0.0380 * i - 0.000273 * i * i + 0.000002 * i * i * i;
            }

            // Cas de Vénus
            if (type == TypeCorpsCeleste.VENUS)
            {
                taille = new Angle((float)(taille_1UA[1] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[1] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -4.40 + 5 * Math.Log10(rSoleil * r) + 0.0009 * i + 0.000239 * i * i - 0.00000065 * i * i * i;
            }

            // Cas de Mars
            if (type == TypeCorpsCeleste.MARS)
            {
                taille = new Angle((float)(taille_1UA[2] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[2] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -1.52 + 5 * Math.Log10(rSoleil * r) + 0.016 * i;
            }

            // Cas de Jupiter
            if (type == TypeCorpsCeleste.JUPITER)
            {
                taille = new Angle((float)(taille_1UA[3] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[3] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -9.40 + 5 * Math.Log10(rSoleil * r) + 0.005 * i;
            }

            // Cas de Saturne
            if (type == TypeCorpsCeleste.SATURNE)
            {
                taille = new Angle((float)(taille_1UA[4] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[4] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -8.88 + 5 * Math.Log10(rSoleil * r) + 0.044 * i;
            }

            // Cas de Uranus
            if (type == TypeCorpsCeleste.URANUS)
            {
                taille = new Angle((float)(taille_1UA[5] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[5] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -7.19 + 5 * Math.Log10(rSoleil * r);
            }

            // Cas de Neptune
            if (type == TypeCorpsCeleste.NEPTUNE)
            {
                taille = new Angle((float)(taille_1UA[6] / r) / 3600, TypeAngle.ANGLE_DEGRES_360);
                //taille = new Angle(0, 0, (float)(taille_1UA[6] / r), TypeAngle.ANGLE_DEGRES_360);
                magnitude = -6.87 + 5 * Math.Log10(rSoleil * r);
            }

            // Calcul de la baisse de magnitude due à l'extinction atmosphérique
            z = 90.0 - altitudeTopocentrique.Decimale;
            deltaMagnitude = 0.2 / Math.Cos(Maths.DegToRad(z));
        }
 /// <summary>
 /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
 /// une seule fois sans calcul itératif de convergence pour les heures de lever et de coucher.
 /// </summary>
 /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
 /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du calcul.</param>
 public void CalculerNonIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil)
 {
     CalculerNonIteratif(a_lieuEtDateCalcul, a_terreSoleil, 0);
 }
Beispiel #29
0
        /// <summary>
        /// Calcule les paramètres de la Terre-Soleil pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// de façon itérative jusqu'à convergence des heures de lever et de coucher.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        public void CalculerIteratif(PositionTemps a_lieuEtDateCalcul)
        {
            // Déclaration des variables de la méthode
            double        heureSideraleVraieLocaleLever;         // Heure sidérale vraie locale de lever
            double        azimutLever;                           // Azimut de lever
            double        heureSideraleVraieLocaleCoucher;       // Heure sidérale vraie locale de coucher
            double        azimutCoucher;                         // Azimut de coucher
            double        heureSideraleVraieAGreenwichLever;     // Heure sidérale vraie à Greenwich de lever
            double        heureSideraleVraieAGreenwichCoucher;   // Heure sidérale vraie à Greenwich de coucher
            double        heureTULever;                          // Heure TU de lever
            double        heureTUCoucher;                        // Heure TU de coucher
            DateTime      heureLocaleLever     = new DateTime(); // Heure locale de lever
            DateTime      heureLocaleCoucher   = new DateTime(); // Heure locale de coucher
            TimeSpan      precision            = new TimeSpan(); // variable de contrôle de la convergence
            PositionTemps dateTemporaireCalcul = null;           // Objet PositionTemps pour le calcul en temps différé

            // Calcul initial des paramètres du Soleil
            CalculerNonIteratif(a_lieuEtDateCalcul);

            // Sauvegarde des heures de lever et de coucher
            heureSideraleVraieLocaleLever = this.heureSideraleVraieLocaleLever;
            azimutLever = this.azimutLever;
            heureSideraleVraieLocaleCoucher = this.heureSideraleVraieLocaleCoucher;
            azimutCoucher = this.azimutCoucher;
            heureSideraleVraieAGreenwichLever   = this.heureSideraleVraieAGreenwichLever;
            heureSideraleVraieAGreenwichCoucher = this.heureSideraleVraieAGreenwichCoucher;
            heureTULever       = this.heureTULever;
            heureTUCoucher     = this.heureTUCoucher;
            heureLocaleLever   = this.heureLocaleLever;
            heureLocaleCoucher = this.heureLocaleCoucher;

            // Création et initialisation d'un nouvel objet PositionTemps pour calculer les heures de lever et de coucher en temps différé
            dateTemporaireCalcul = new PositionTemps(a_lieuEtDateCalcul.LieuObservation, a_lieuEtDateCalcul.HeureLocale.Year, a_lieuEtDateCalcul.HeureLocale.Month, a_lieuEtDateCalcul.HeureLocale.Day, heureLocaleLever.Hour, heureLocaleLever.Minute, 0, a_lieuEtDateCalcul.ZoneHoraire, a_lieuEtDateCalcul.ChangementHeure, a_lieuEtDateCalcul.DeltaT);

            // Calcul itératif pour l'heure de lever du Soleil
            do
            {
                // Paramétrage de l'objet dateTemporaireCalcul avec l'heure de lever précédemment calculée
                dateTemporaireCalcul.HeureLocale = heureLocaleLever;
                // Calcul de dateTemporaireCalcul avec les nouveaux réglages
                dateTemporaireCalcul.CalculerParametres();

                // Calcul des paramètres du Soleil à l'instant différé
                CalculerNonIteratif(dateTemporaireCalcul);

                // Calcul de la précision atteinte
                precision = this.heureLocaleLever - heureLocaleLever;

                // Sauvegarde de la nouvelle heure de lever
                heureSideraleVraieLocaleLever = this.heureSideraleVraieLocaleLever;
                azimutLever = this.azimutLever;
                heureSideraleVraieAGreenwichLever = this.heureSideraleVraieAGreenwichLever;
                heureTULever     = this.heureTULever;
                heureLocaleLever = this.heureLocaleLever;
            } while (precision > TimeSpan.FromSeconds(59.0)); // Précision de 1 minute

            // Calcul itératif pour l'heure de coucher du Soleil
            do
            {
                // Paramétrage de l'objet dateTemporaireCalcul avec l'heure de coucher précédemment calculée
                dateTemporaireCalcul.HeureLocale = heureLocaleCoucher;
                // Calcul de dateTemporaireCalcul avec les nouveaux réglages
                dateTemporaireCalcul.CalculerParametres();

                // Calcul des paramètres du Soleil à l'instant différé
                CalculerNonIteratif(dateTemporaireCalcul);

                // Calcul de la précision atteinte
                precision = this.heureLocaleCoucher - heureLocaleCoucher;

                // Sauvegarde de la nouvelle heure de coucher
                heureSideraleVraieLocaleCoucher = this.heureSideraleVraieLocaleCoucher;
                azimutCoucher = this.azimutCoucher;
                heureSideraleVraieAGreenwichCoucher = this.heureSideraleVraieAGreenwichCoucher;
                heureTUCoucher     = this.heureTUCoucher;
                heureLocaleCoucher = this.heureLocaleCoucher;
            } while (precision > TimeSpan.FromSeconds(59.0)); // Précision de 1 minute

            // Calcul des paramètres du Soleil pour la date et l'heure considérée
            CalculerNonIteratif(a_lieuEtDateCalcul);
            // Affectation des heures de lever et de coucher calculées
            this.heureSideraleVraieLocaleLever = heureSideraleVraieLocaleLever;
            this.azimutLever = azimutLever;
            this.heureSideraleVraieLocaleCoucher = heureSideraleVraieLocaleCoucher;
            this.azimutCoucher = azimutCoucher;
            this.heureSideraleVraieAGreenwichLever   = heureSideraleVraieAGreenwichLever;
            this.heureSideraleVraieAGreenwichCoucher = heureSideraleVraieAGreenwichCoucher;
            this.heureTULever       = heureTULever;
            this.heureTUCoucher     = heureTUCoucher;
            this.heureLocaleLever   = heureLocaleLever;
            this.heureLocaleCoucher = heureLocaleCoucher;
        }
        /// <summary>
        /// Calcule les paramètres d'une planète pour le lieu d'observation et la date de calcul spécifié. La méthode effectue tous les calculs du synoptique
        /// de façon itérative jusqu'à convergence des heures de lever et de coucher.
        /// </summary>
        /// <param name="a_lieuEtDateCalcul">Lieu d'observation et date pour le calcul.</param>
        /// <param name="a_terreSoleil">Objet Soleil calculé pour le lieu d'observation et la date du caluul.</param>
        /// <returns>Résultat du succès (true) ou de l'échec (false) du calcul de convergence des heures de lever et de coucher.</returns>
        public bool CalculerIteratif(PositionTemps a_lieuEtDateCalcul, CorpsSystemeSolaire a_terreSoleil)
        {
            // Déclaration des variables de la méthode
            double        heureSideraleVraieLocaleLever;         // Heure sidérale vraie locale de lever
            double        azimutLever;                           // Azimut de lever
            double        heureSideraleVraieLocaleCoucher;       // Heure sidérale vraie locale de coucher
            double        azimutCoucher;                         // Azimut de coucher
            double        heureSideraleVraieAGreenwichLever;     // Heure sidérale vraie à Greenwich de lever
            double        heureSideraleVraieAGreenwichCoucher;   // Heure sidérale vraie à Greenwich de coucher
            double        heureTULever;                          // Heure TU de lever
            double        heureTUCoucher;                        // Heure TU de coucher
            DateTime      heureLocaleLever     = new DateTime(); // Heure locale de lever
            DateTime      heureLocaleCoucher   = new DateTime(); // Heure locale de coucher
            TimeSpan      precision            = new TimeSpan(); // variable de contrôle de la convergence
            PositionTemps dateTemporaireCalcul = null;           // Objet PositionTemps pour le calcul en temps différé
            Soleil        terreSoleil          = null;           // Objet Soleil pour le calcul en temps différé des paramètres du Soleil
            int           compteur;                              // Variable de contrôle de la convergence du calcul
            bool          succes = true;

            // Calcul initial des paramètres de la planète
            CalculerNonIteratif(a_lieuEtDateCalcul, a_terreSoleil);

            // Sauvegarde des heures de lever et de coucher
            heureSideraleVraieLocaleLever = this.heureSideraleVraieLocaleLever;
            azimutLever = this.azimutLever;
            heureSideraleVraieLocaleCoucher = this.heureSideraleVraieLocaleCoucher;
            azimutCoucher = this.azimutCoucher;
            heureSideraleVraieAGreenwichLever   = this.heureSideraleVraieAGreenwichLever;
            heureSideraleVraieAGreenwichCoucher = this.heureSideraleVraieAGreenwichCoucher;
            heureTULever       = this.heureTULever;
            heureTUCoucher     = this.heureTUCoucher;
            heureLocaleLever   = this.heureLocaleLever;
            heureLocaleCoucher = this.heureLocaleCoucher;

            // Création et initialisation d'un nouvel objet PositionTemps pour calculer les heures de lever et de coucher en temps différé
            dateTemporaireCalcul = new PositionTemps(a_lieuEtDateCalcul.LieuObservation, a_lieuEtDateCalcul.HeureLocale.Year, a_lieuEtDateCalcul.HeureLocale.Month, a_lieuEtDateCalcul.HeureLocale.Day, heureLocaleLever.Hour, heureLocaleLever.Minute, 0, a_lieuEtDateCalcul.ZoneHoraire, a_lieuEtDateCalcul.ChangementHeure, a_lieuEtDateCalcul.DeltaT);

            // Calcul itératif pour l'heure de lever de la planète
            compteur = 0;
            do
            {
                // Paramétrage de l'objet dateTemporaireCalcul avec l'heure de lever précédemment calculée
                dateTemporaireCalcul.HeureLocale = heureLocaleLever;
                // Calcul de dateTemporaireCalcul avec les nouveaux réglages
                dateTemporaireCalcul.CalculerParametres();

                // Création et initialisation d'un nouvel objet Soleil pour calculer les heures de lever et de coucher en temps différé
                terreSoleil = new Soleil();
                terreSoleil.CalculerNonIteratif(dateTemporaireCalcul);

                // Calcul des paramètres de la planète à l'instant différé
                CalculerNonIteratif(dateTemporaireCalcul, terreSoleil);

                // Au-delà de 6 itérations si le calcul n'a pas convergé, la méthode force la 2ème solution TU en ajoutant +23h56min04s si l'heure TU est compris entre 0h TU et 03h3min56s
                if (compteur >= 6)
                {
                    CalculerNonIteratif(dateTemporaireCalcul, terreSoleil, 1);
                }

                // Calcul de la précision atteinte
                precision = this.heureLocaleLever - heureLocaleLever;

                // Détection d'une absence de solution (cas d'un lever du corps céleste proche de minuit et oscillant autour de minuit)
                if (precision > TimeSpan.FromHours(20))
                {
                    this.azimutLever = TOUJOURS_INVISIBLE;
                    this.heureSideraleVraieLocaleLever     = TOUJOURS_INVISIBLE;
                    this.heureSideraleVraieAGreenwichLever = TOUJOURS_INVISIBLE;
                    this.heureTULever     = TOUJOURS_INVISIBLE;
                    this.heureLocaleLever = new DateTime();
                    precision             = TimeSpan.FromSeconds(1);
                }

                // Sauvegarde de la nouvelle heure de lever
                heureSideraleVraieLocaleLever = this.heureSideraleVraieLocaleLever;
                azimutLever = this.azimutLever;
                heureSideraleVraieAGreenwichLever = this.heureSideraleVraieAGreenwichLever;
                heureTULever     = this.heureTULever;
                heureLocaleLever = this.heureLocaleLever;

                // Incrémentation du compteur
                compteur++;

                // Au-delà de 10 itérations si le calcul n'a pas convergé, la méthode la boucle est stoppée
                if (compteur == 10)
                {
                    succes    = false;
                    precision = TimeSpan.FromSeconds(1);
                }
            } while (precision > TimeSpan.FromSeconds(59.0)); // Précision de 1 minute

            // Calcul itératif pour l'heure de coucher de la planète
            compteur = 0;
            do
            {
                // Paramétrage de l'objet dateTemporaireCalcul avec l'heure de coucher précédemment calculée
                dateTemporaireCalcul.HeureLocale = heureLocaleCoucher;
                // Calcul de dateTemporaireCalcul avec les nouveaux réglages
                dateTemporaireCalcul.CalculerParametres();

                // Création et initialisation d'un nouvel objet Soleil pour calculer les heures de lever et de coucher en temps différé
                terreSoleil = new Soleil();
                terreSoleil.CalculerNonIteratif(dateTemporaireCalcul);

                // Calcul des paramètres de la planète à l'instant différé
                CalculerNonIteratif(dateTemporaireCalcul, terreSoleil);

                // Au-delà de 6 itérations si le calcul n'a pas convergé, la méthode force la 2ème solution TU en ajoutant +23h56min04s si l'heure TU est compris entre 0h TU et 03h3min56s
                if (compteur >= 6)
                {
                    CalculerNonIteratif(dateTemporaireCalcul, terreSoleil, 1);
                }

                // Calcul de la précision atteinte
                precision = this.heureLocaleCoucher - heureLocaleCoucher;

                // Détection d'une absence de solution (cas d'un coucher du corps céleste proche de minuit et oscillant autour de minuit)
                if (precision > TimeSpan.FromHours(20))
                {
                    this.azimutCoucher = TOUJOURS_INVISIBLE;
                    this.heureSideraleVraieLocaleCoucher     = TOUJOURS_INVISIBLE;
                    this.heureSideraleVraieAGreenwichCoucher = TOUJOURS_INVISIBLE;
                    this.heureTUCoucher     = TOUJOURS_INVISIBLE;
                    this.heureLocaleCoucher = new DateTime();
                    precision = TimeSpan.FromSeconds(1);
                }

                // Sauvegarde de la nouvelle heure de coucher
                heureSideraleVraieLocaleCoucher = this.heureSideraleVraieLocaleCoucher;
                azimutCoucher = this.azimutCoucher;
                heureSideraleVraieAGreenwichCoucher = this.heureSideraleVraieAGreenwichCoucher;
                heureTUCoucher     = this.heureTUCoucher;
                heureLocaleCoucher = this.heureLocaleCoucher;

                // Incrémentation du compteur
                compteur++;

                // Au-delà de 10 itérations si le calcul n'a pas convergé, la méthode la boucle est stoppée
                if (compteur == 10)
                {
                    succes    = false;
                    precision = TimeSpan.FromSeconds(1);
                }
            } while (precision > TimeSpan.FromSeconds(59.0)); // Précision de 1 minute

            // Calcul des paramètres du Soleil pour la date et l'heure considérée
            CalculerNonIteratif(a_lieuEtDateCalcul, a_terreSoleil);

            // Affectation des heures de lever et de coucher calculées
            this.heureSideraleVraieLocaleLever = heureSideraleVraieLocaleLever;
            this.azimutLever = azimutLever;
            this.heureSideraleVraieLocaleCoucher = heureSideraleVraieLocaleCoucher;
            this.azimutCoucher = azimutCoucher;
            this.heureSideraleVraieAGreenwichLever   = heureSideraleVraieAGreenwichLever;
            this.heureSideraleVraieAGreenwichCoucher = heureSideraleVraieAGreenwichCoucher;
            this.heureTULever       = heureTULever;
            this.heureTUCoucher     = heureTUCoucher;
            this.heureLocaleLever   = heureLocaleLever;
            this.heureLocaleCoucher = heureLocaleCoucher;

            return(succes);
        }