File indexing completed on 2024-04-14 14:11:27

0001 /*
0002     SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf (do not hesitate to contact)>
0003     matrix               : @hiro98@tchncs.de
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include "ksplanetbase.h"
0011 
0012 class KSSun;
0013 class KSMoon;
0014 class KSPlanet;
0015 
0016 /**
0017  * @class KSEarthShadow
0018  * @short A class that manages the calculation of the
0019  * earths shadow (in moon distance) as a 'virtual' skyobject.
0020  * KSMoon is responsible for coordinating this object. While a
0021  * rather unusual measure, this method ensures that unnecessary
0022  * calculations are avoided.
0023  *
0024  * @author Valentin Boettcher
0025  * @version 1.0
0026  */
0027 class KSEarthShadow : public KSPlanetBase
0028 {
0029     public:
0030         /**
0031          * @param moon - an instance of KSMoon
0032          * @param sun - an instance of KSSun
0033          * @param earth - an instance of KSPlanet
0034          * @note The three parameters must be supplied to avoid initialization order
0035          * problems. This class may be generalized to any three bodies if it becomes
0036          * necessary in the future.
0037          * This class is relatively cheap, so it's save to create new instances instead
0038          * of reusing an existing one.
0039          */
0040         KSEarthShadow(const KSMoon *moon, const KSSun *sun, const KSPlanet * earth);
0041 
0042         /**
0043          * @brief The ECLIPSE_TYPE enum describes the quality of an eclipse.
0044          */
0045         enum ECLIPSE_TYPE
0046         {
0047             PARTIAL, FULL_PENUMBRA, FULL_UMBRA, NONE
0048         };
0049 
0050         /**
0051          * @short The earths shadow on the moon appears only at new moon
0052          * so calculating it on other occasions is rather pointless.
0053          * @return whether to update the shadow or not
0054          */
0055         bool shouldUpdate();
0056 
0057 
0058         /**
0059          * @brief isInEclipse - a slim version of getEclipseType()
0060          * @return Whether the earth shadow eclipses the moon.
0061          */
0062         bool isInEclipse();
0063 
0064         /**
0065          * @brief eclipse
0066          * @return The eclipse type. @see KSEarthShadow::ECLIPSE_TYPE
0067          */
0068         ECLIPSE_TYPE getEclipseType();
0069 
0070         bool findGeocentricPosition(const KSNumbers *, const KSPlanetBase * Earth = nullptr) override;
0071 
0072         /**
0073          * @short Update the Coordinates of the shadow.
0074          * In truth it finds the sun and calls KSEarthShadow::updateCoords(const KSSun *)
0075          */
0076         void updateCoords(const KSNumbers *num, bool includePlanets = true, const CachingDms *lat = nullptr,
0077                           const CachingDms *LST = nullptr, bool forceRecompute = false) override;
0078 
0079         /**
0080          * @short Update the RA/DEC of the shadow.
0081          */
0082         void updateCoords();
0083 
0084         /**
0085          * @short Updates umbra and penumbra radius from the positions of the three bodies.
0086          */
0087         void calculateShadowRadius();
0088 
0089         /**
0090          * @return The angular radius of the umbra.
0091          */
0092         double getUmbraAngSize() const
0093         {
0094             return m_umbra_ang;
0095         }
0096 
0097         /**
0098          * @return The angular radius of the penumbra.
0099          */
0100         double getPenumbraAngSize() const
0101         {
0102             return m_penumbra_ang;
0103         }
0104 
0105         /**
0106          * @brief angSize
0107          * @return the angular size (penumbra) in arc minutes
0108          */
0109         double findAngularSize() final override
0110         {
0111             calculateShadowRadius();
0112             return m_penumbra_ang;
0113         }
0114 
0115         // Some Compatibility Nonsense
0116         void findMagnitude(const KSNumbers *) override {} // Empty
0117         bool loadData() override
0118         {
0119             return true;
0120         }
0121         void findPhase() override {}
0122 
0123     private:
0124         double m_umbra_ang { 0 }; // Radius!
0125         double m_penumbra_ang { 0 }; // Radius!
0126 
0127         const KSSun* m_sun { nullptr };
0128         const KSMoon* m_moon { nullptr };
0129         const KSPlanet* m_earth { nullptr };
0130 
0131         void findSun();
0132         void findMoon();
0133         void findEarth();
0134 };