1 /*
2     SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf (do not hesitate to contact)>
3     matrix               : @hiro98@tchncs.de
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #pragma once
9 
10 #include "ksplanetbase.h"
11 
12 class KSSun;
13 class KSMoon;
14 class KSPlanet;
15 
16 /**
17  * @class KSEarthShadow
18  * @short A class that manages the calculation of the
19  * earths shadow (in moon distance) as a 'virtual' skyobject.
20  * KSMoon is responsible for coordinating this object. While a
21  * rather unusual measure, this method ensures that unnecessary
22  * calculations are avoided.
23  *
24  * @author Valentin Boettcher
25  * @version 1.0
26  */
27 class KSEarthShadow : public KSPlanetBase
28 {
29     public:
30         /**
31          * @param moon - an instance of KSMoon
32          * @param sun - an instance of KSSun
33          * @param earth - an instance of KSPlanet
34          * @note The three parameters must be supplied to avoid initialization order
35          * problems. This class may be generalized to any three bodies if it becomes
36          * necessary in the future.
37          * This class is relatively cheap, so it's save to create new instances instead
38          * of reusing an existing one.
39          */
40         KSEarthShadow(const KSMoon *moon, const KSSun *sun, const KSPlanet * earth);
41 
42         /**
43          * @brief The ECLIPSE_TYPE enum describes the quality of an eclipse.
44          */
45         enum ECLIPSE_TYPE
46         {
47             PARTIAL, FULL_PENUMBRA, FULL_UMBRA, NONE
48         };
49 
50         /**
51          * @short The earths shadow on the moon appears only at new moon
52          * so calculating it on other occasions is rather pointless.
53          * @return whether to update the shadow or not
54          */
55         bool shouldUpdate();
56 
57 
58         /**
59          * @brief isInEclipse - a slim version of getEclipseType()
60          * @return Whether the earth shadow eclipses the moon.
61          */
62         bool isInEclipse();
63 
64         /**
65          * @brief eclipse
66          * @return The eclipse type. @see KSEarthShadow::ECLIPSE_TYPE
67          */
68         ECLIPSE_TYPE getEclipseType();
69 
70         bool findGeocentricPosition(const KSNumbers *, const KSPlanetBase * Earth = nullptr) override;
71 
72         /**
73          * @short Update the Coordinates of the shadow.
74          * In truth it finds the sun and calls KSEarthShadow::updateCoords(const KSSun *)
75          */
76         void updateCoords(const KSNumbers *num, bool includePlanets = true, const CachingDms *lat = nullptr,
77                           const CachingDms *LST = nullptr, bool forceRecompute = false) override;
78 
79         /**
80          * @short Update the RA/DEC of the shadow.
81          */
82         void updateCoords();
83 
84         /**
85          * @short Updates umbra and penumbra radius from the positions of the three bodies.
86          */
87         void calculateShadowRadius();
88 
89         /**
90          * @return The angular radius of the umbra.
91          */
getUmbraAngSize()92         double getUmbraAngSize() const
93         {
94             return m_umbra_ang;
95         }
96 
97         /**
98          * @return The angular radius of the penumbra.
99          */
getPenumbraAngSize()100         double getPenumbraAngSize() const
101         {
102             return m_penumbra_ang;
103         }
104 
105         /**
106          * @brief angSize
107          * @return the angular size (penumbra) in arc minutes
108          */
findAngularSize()109         double findAngularSize() final override
110         {
111             calculateShadowRadius();
112             return m_penumbra_ang;
113         }
114 
115         // Some Compatibility Nonsense
findMagnitude(const KSNumbers *)116         void findMagnitude(const KSNumbers *) override {} // Empty
loadData()117         bool loadData() override
118         {
119             return true;
120         }
findPhase()121         void findPhase() override {}
122 
123     private:
124         double m_umbra_ang { 0 }; // Radius!
125         double m_penumbra_ang { 0 }; // Radius!
126 
127         const KSSun* m_sun { nullptr };
128         const KSMoon* m_moon { nullptr };
129         const KSPlanet* m_earth { nullptr };
130 
131         void findSun();
132         void findMoon();
133         void findEarth();
134 };
135