File indexing completed on 2024-04-28 03:44:54

0001 /*
0002     SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 #include "eclipsehandler.h"
0009 #include "ksearthshadow.h"
0010 #include "ksmoon.h"
0011 #include "kssun.h" // NOTE: Maybe use pointers... compile time savings
0012 
0013 // FIXME: (Valentin) WIP, To be completed (extra features)!
0014 
0015 /**
0016  * @brief The LunarEclipseDetails struct
0017  * @short A struct to hold detail information about an eclipse
0018  */
0019 struct LunarEclipseDetails {
0020     enum EVENT {
0021         BEGIN_PENUMBRA_CONTACT,
0022         BEGIN_UMBRA_CONTACT,
0023         END_PENUMBRA_CONTACT,
0024         END_UMBRA_CONTACT,
0025         BEGIN_FULL_UMBRA,
0026         END_FULL_UMBRA,
0027         BEGIN_FULL_PENUMRA,
0028         END_FULL_PENUMRA,
0029         CLOSEST_APPROACH
0030     };
0031 
0032     bool available = false;
0033     QMap<long double, EVENT> eclipseTimes;
0034     // More Later
0035 };
0036 
0037 /**
0038  * @brief The LunarEclipseEvent class
0039  * @short implementation of the EclipseEvent for the LunarEclipseHandler
0040  */
0041 class LunarEclipseEvent : public EclipseEvent
0042 {
0043     Q_OBJECT
0044 public:
0045     LunarEclipseEvent(long double jd, GeoLocation geoPlace, ECLIPSE_TYPE type, KSEarthShadow::ECLIPSE_TYPE detailed_type);
0046 
0047     ~LunarEclipseEvent() override {} // empty for now
0048 
0049     QString getExtraInfo() override;
0050 
0051     /**
0052      * @brief getDetailedType
0053      * @return Type of the eclipse as in KSEarthShadow::ECLIPSE_TYPE
0054      */
0055     KSEarthShadow::ECLIPSE_TYPE getDetailedType() { return m_detailedType; }
0056 
0057     QString getEclipsingObjectName() override { return i18n("Earth Shadow"); }
0058     QString getEclipsedObjectName() override  { return i18n("Moon"); }
0059 
0060     SkyObject * getEclipsingObjectFromSkyComposite() override;
0061 
0062     bool hasDetails() override { return false; } // false for now!
0063 
0064 public slots:
0065     void slotShowDetails() override;
0066 
0067 private:
0068     KSEarthShadow::ECLIPSE_TYPE m_detailedType;
0069     LunarEclipseDetails m_details;
0070     // More Later_details;
0071 };
0072 
0073 
0074 /**
0075  * @brief The LunarEclipseHandler class
0076  * @short Calculate lunar eclipses.
0077  *
0078  * Calculates lunar eclipses by looking for them close to full moon.
0079  */
0080 class LunarEclipseHandler : public EclipseHandler
0081 {
0082     Q_OBJECT
0083 public:
0084     explicit LunarEclipseHandler(QObject * parent = nullptr);
0085     virtual ~LunarEclipseHandler() override;
0086 
0087     EclipseVector computeEclipses(long double startJD, long double endJD) override;
0088 
0089     // FIXME: (Valentin) Not yet finished. Returns empty Details!
0090     LunarEclipseDetails findEclipseDetails(LunarEclipseEvent *event);
0091 
0092 protected:
0093     double findInitialStep(long double, long double) override
0094         { return (m_mode == CLOSEST_APPROACH) ? INITIAL_STEP : DETAIL_STEP; }
0095 
0096     void updatePositions(long double jd) override;
0097 
0098     // NOTE: This method depends on m_mode!
0099     dms findDistance() override;
0100 
0101     // NOTE: This method depends on m_mode!
0102     double getMaxSeparation() override;
0103 
0104 private:
0105     /**
0106      * @brief getFullMoons
0107      * @param startJD start Date
0108      * @param endJD end Date
0109      * @return a vector of JDs for full moons (actually a little earlier as it doesn't matter much)
0110      */
0111     QVector<long double> getFullMoons(long double startJD, long double endJD);
0112 
0113     // Objects for the Calculations
0114     KSSun m_sun;
0115     KSMoon m_moon;
0116     KSEarthShadow m_shadow;
0117 
0118     // Controls the step size, is chosen small to minimize overshooting
0119     const double INITIAL_STEP { 0.1 };
0120     const double DETAIL_STEP { 0.001 };
0121 
0122     /**
0123      * @brief The MODE enum
0124      * @short Set the mode for the distance minimizer, i.e. which point to find.
0125      */
0126     enum {
0127         CLOSEST_APPROACH,
0128         PENUMBRA_CONTACT,
0129         PUNUMBRA_IMMERSION,
0130         UMBRA_CONTACT,
0131         UMBRA_IMMERSION
0132     } m_mode { CLOSEST_APPROACH };
0133 };