File indexing completed on 2022-12-06 18:58:43

0001 /*
0002     SPDX-FileCopyrightText: 2009 Prakash Mohan <prakash.mohan@kdemail.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "skyobjects/kssun.h"
0010 #include "skyobjects/ksmoon.h"
0011 #include "kstarsdatetime.h"
0012 
0013 /**
0014  *@class KSAlmanac
0015  *
0016  *A class that implements methods to find sun rise, sun set, twilight
0017  *begin / end times, moon rise and moon set times.
0018  *
0019  *@short Implement methods to find important times in a day
0020  *@author Prakash Mohan
0021  *@version 1.0
0022  */
0023 
0024 class GeoLocation;
0025 
0026 class KSAlmanac
0027 {
0028   public:
0029     /**
0030          *@brief KSAlmanac constructor initializing an almanac for the current KStarsData::Instance geolocation and time.
0031          */
0032     KSAlmanac();
0033 
0034     /**
0035          *@brief KSAlmanac constructor initializing an almanac for an arbitrary geolocation and time.
0036          *@param midnight is the midnight date and time to consider as beginning of the day at the "geo" location.
0037          *@param geo is the GeoLocation to use for this almanac, defaulting to the KStarsData::Instance geolocation.
0038          *@note if the timespec of midnight is local time, its UTC value at the geolocation "geo" will be used instead.
0039          */
0040     KSAlmanac(const KStarsDateTime &midnight, const GeoLocation *geo = nullptr);
0041 
0042     /**
0043          *@short Get/set the date for computations to the given date.
0044          *@param utc_midnight and local_midnight are the midnight date and time to consider as beginning of the day at the geo_ location, either UTC or local.
0045          *@note The time must be the local time midnight of the day the almanac is required for, so that
0046          *      resulting ephemerides are calculated around that time.
0047          *@note These functions are not merged into a single timespec-aware one for backwards compatilibity.
0048          */
0049     /** @{ */
0050     void setDate(const KStarsDateTime &utc_midnight);
0051     void setDateFromLT(const KStarsDateTime &local_midnight) { setDate(geo->LTtoUT(local_midnight)); }
0052     KStarsDateTime getDate() const { return dt; }
0053     /** @} */
0054 
0055     /**
0056          *@short Set the location for computations to the given location
0057          *@param geo_ The location to set for computations
0058          */
0059     void setLocation(const GeoLocation *geo_);
0060 
0061     /**
0062          *All the functions returns the fraction of the day given by getDate()
0063          *as their return value
0064          */
0065     inline double getSunRise() const { return SunRise; }
0066     inline double getSunSet() const { return SunSet; }
0067     inline double getMoonRise() const { return MoonRise; }
0068     inline double getMoonSet() const { return MoonSet; }
0069     inline double getDuskAstronomicalTwilight() const { return DuskAstronomicalTwilight; }
0070     inline double getDawnAstronomicalTwilight() const { return DawnAstronomicalTwilight; }
0071 
0072     /**
0073          *These functions return the max and min altitude of the sun during the course of the day in degrees
0074          */
0075     inline double getSunMaxAlt() const { return SunMaxAlt; }
0076     inline double getSunMinAlt() const { return SunMinAlt; }
0077 
0078     /**
0079          *@return the moon phase in degrees at the given date/time. Ranges is [0, 180]
0080          */
0081     inline double getMoonPhase() const { return MoonPhase; }
0082 
0083     /**
0084          *@return get the moon illuminated fraction at the given date/time. Range is [0.,1.]
0085          */
0086     inline double getMoonIllum() const { return m_Moon.illum(); }
0087 
0088     inline QTime sunRise() const { return SunRiseT; }
0089     inline QTime sunSet() const { return SunSetT; }
0090     inline QTime moonRise() const { return MoonRiseT; }
0091     inline QTime moonSet() const { return MoonSetT; }
0092 
0093     /**
0094          *@short Convert the zenithal distance of the sun to fraction of the day
0095          *@param z Zenithal angular distance
0096          *@return Time as a fraction of the day, at which the zenithal distance is attained by the sun
0097          *@note This is accurate only for zenithal angles close to sunset. TODO: Make this more accurate
0098          */
0099     double sunZenithAngleToTime(double z) const;
0100 
0101   private:
0102     void update();
0103 
0104     /**
0105           * This function computes the rise and set time for the given SkyObject. This is done in order to
0106           * have a common function for the computation of the Sun and Moon rise and set times.
0107           */
0108     void RiseSetTime(SkyObject *o, double *riseTime, double *setTime, QTime *RiseTime, QTime *SetTime);
0109 
0110     /**
0111          * Compute the dawn and dusk times in a [-12,+12] hours around the day midnight of this KSAlmanac, if any, as well as min and max altitude.
0112          * - If the day midnight of this KSAlmanac is during astronomical night time, dusk will be before dawn.
0113          * - If the day midnight of this KSAlmanac is during twilight or day time, dawn will be before dusk.
0114          * - If there is no astronomical night time, dawn and dusk will be set to the time of minimal altitude of the Sun.
0115          * - If there is no twilight or day time, dawn and dusk will be set to the time of minimal altitude of the Sun.
0116          */
0117     void findDawnDusk(double altitude = -18.0);
0118 
0119     /**
0120          * Computes the moon phase at the given date/time
0121          */
0122     void findMoonPhase();
0123 
0124     /**
0125          * FIXME: More code duplication!
0126          * findAltitude should really be part of KSEngine. Copying from ObservingList.
0127          * returns in degrees
0128          */
0129     double findAltitude(const SkyPoint *p, double hour);
0130 
0131     KSSun m_Sun;
0132     KSMoon m_Moon;
0133     KStarsDateTime dt;
0134 
0135     const GeoLocation *geo { nullptr };
0136     double SunRise { 0 };
0137     double SunSet { 0 };
0138     double MoonRise { 0 };
0139     double MoonSet { 0 };
0140     double DuskAstronomicalTwilight { 0 };
0141     double DawnAstronomicalTwilight { 0 };
0142     double SunMinAlt { 0 };
0143     double SunMaxAlt { 0 };
0144     double MoonPhase { 0 };
0145     QTime SunRiseT, SunSetT, MoonRiseT, MoonSetT, DuskAstronomicalTwilightT, DawnAstronomicalTwilightT;
0146 };