Exemplo n.º 1
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);
        }