Kstars

ksalmanac.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Prakash Mohan <prakash.mohan@kdemail.net>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "ksalmanac.h"
8
9#include "geolocation.h"
10#include "ksnumbers.h"
11#include "kstarsdata.h"
12
14{
15 KStarsData *data = KStarsData::Instance();
16
17 /*dt = KStarsDateTime::currentDateTime();
18 geo = data->geo();
19 dt.setTime(QTime());
20 dt = geo->LTtoUT(dt);*/
21
22 // Jasem 2015-08-24 Do NOT use KStarsDataTime for local time, it is only for UTC
23 QDateTime midnight = QDateTime(data->lt().date(), QTime());
24 geo = data->geo();
25 dt = geo->LTtoUT(KStarsDateTime(midnight));
26 update();
27}
28
30{
31 geo = g ? g : KStarsData::Instance()->geo();
32
33 dt = midnight.isValid() ?
34 midnight.timeSpec() == Qt::LocalTime ?
35 geo->LTtoUT(midnight) :
36 midnight :
37 KStarsData::Instance()->ut();
38
39 update();
40}
41
42void KSAlmanac::update()
43{
44 RiseSetTime(&m_Sun, &SunRise, &SunSet, &SunRiseT, &SunSetT);
45 RiseSetTime(&m_Moon, &MoonRise, &MoonSet, &MoonRiseT, &MoonSetT);
46 // qDebug() << Q_FUNC_INFO << "Sun rise: " << SunRiseT.toString() << " Sun set: " << SunSetT.toString() << " Moon rise: " << MoonRiseT.toString() << " Moon set: " << MoonSetT.toString();
47 findDawnDusk();
48 findMoonPhase();
49}
50
51void KSAlmanac::RiseSetTime(SkyObject *o, double *riseTime, double *setTime, QTime *RiseTime, QTime *SetTime)
52{
53 // Compute object rise and set times
54 const KStarsDateTime today = dt;
55 const GeoLocation *_geo = geo;
57 today, _geo,
58 true); // FIXME: Should we add a day here so that we report future rise time? Not doing so produces the right results for the moon. Not sure about the sun.
59 *SetTime = o->riseSetTime(today, _geo, false);
60 *riseTime = -1.0 * RiseTime->secsTo(QTime(0, 0, 0, 0)) / 86400.0;
61 *setTime = -1.0 * SetTime->secsTo(QTime(0, 0, 0, 0)) / 86400.0;
62
63 // Check to see if the object is circumpolar
64 // NOTE: Since we are working on a local copy of the Sun / Moon,
65 // we freely change the geolocation / time without setting
66 // them back.
67
68 KSNumbers num(dt.djd());
69 CachingDms LST = geo->GSTtoLST(dt.gst());
70 o->updateCoords(&num, true, geo->lat(), &LST, true);
71 if (o->checkCircumpolar(geo->lat()))
72 {
73 if (o->alt().Degrees() > 0.0)
74 {
75 //Circumpolar, signal it this way:
76 *riseTime = 0.0;
77 *setTime = 1.0;
78 }
79 else
80 {
81 //never rises, signal it this way:
82 *riseTime = 0.0;
83 *setTime = -1.0;
84 }
85 }
86}
87
88void KSAlmanac::findDawnDusk(double altitude)
89{
91 KSNumbers num(today.djd());
92 CachingDms LST = geo->GSTtoLST(today.gst());
93
94 // Relocate our local Sun to this almanac time - local midnight
95 m_Sun.updateCoords(&num, true, geo->lat(), &LST, true);
96
97 // Granularity
98 int const h_inc = 5;
99
100 // Compute the altitude of the Sun twelve hours before this almanac time
101 int const start_h = -1200, end_h = +1200;
102 double last_alt = findAltitude(&m_Sun, start_h/100.0);
103
104 int dawn = -1300, dusk = -1300, min_alt_time = -1300;
105 double max_alt = -100.0, min_alt = +100.0;
106
107 // Compute the dawn and dusk times in a [-12,+12] hours around the day midnight of this almanac as well as min and max altitude
108 // See the header comment about dawn and dusk positions
109 for (int h = start_h + h_inc; h <= end_h; h += h_inc)
110 {
111 // Compute the Sun's altitude in an increasing hour interval
112 double const alt = findAltitude(&m_Sun, h/100.0);
113
114 // Deduce whether the Sun is rising or setting
115 bool const rising = alt - last_alt > 0;
116
117 // Extend min/max altitude interval, push minimum time down
118 if (max_alt < alt)
119 {
120 max_alt = alt;
121 }
122 else if (alt < min_alt)
123 {
124 min_alt = alt;
125 min_alt_time = h;
126 }
127
128 // Dawn is when the Sun is rising and crosses an altitude of -18 degrees
129 if (dawn < 0)
130 if (rising)
131 if (last_alt <= altitude && altitude <= alt)
132 dawn = h - h_inc * (alt == last_alt ? 0 : (alt - altitude)/(alt - last_alt));
133
134 // Dusk is when the Sun is setting and crosses an altitude of -18 degrees
135 if (dusk < 0)
136 if (!rising)
137 if (last_alt >= altitude && altitude >= alt)
138 dusk = h - h_inc * (alt == last_alt ? 0 : (alt - altitude)/(alt - last_alt));
139
140 last_alt = alt;
141 }
142
143 // If the Sun did not cross the astronomical twilight altitude, use the minimal altitude
144 if (dawn < start_h || dusk < start_h)
145 {
146 DawnAstronomicalTwilight = static_cast <double> (min_alt_time) / 2400.0;
147 DuskAstronomicalTwilight = static_cast <double> (min_alt_time) / 2400.0;
148 }
149 // If the Sun did cross the astronomical twilight, use the computed time offsets
150 else
151 {
152 DawnAstronomicalTwilight = static_cast <double> (dawn) / 2400.0;
153 DuskAstronomicalTwilight = static_cast <double> (dusk) / 2400.0;
154 }
155
156 SunMaxAlt = max_alt;
157 SunMinAlt = min_alt;
158}
159
160void KSAlmanac::findMoonPhase()
161{
162 const KStarsDateTime today = dt;
163 KSNumbers num(today.djd());
164 CachingDms LST = geo->GSTtoLST(today.gst());
165
166 m_Sun.updateCoords(&num, true, geo->lat(), &LST, true); // We can abuse our own copy of the sun and/or moon
167 m_Moon.updateCoords(&num, true, geo->lat(), &LST, true);
168 m_Moon.findPhase(&m_Sun);
169 MoonPhase = m_Moon.phase().Degrees();
170}
171
173{
174 dt = utc_midnight;
175 update();
176}
177
179{
180 geo = geo_;
181 update();
182}
183
185{
186 // TODO: Correct for movement of the sun
187 double HA = acos((cos(z * dms::DegToRad) - m_Sun.dec().sin() * geo->lat()->sin()) /
188 (m_Sun.dec().cos() * geo->lat()->cos()));
189 double HASunset = acos((-m_Sun.dec().sin() * geo->lat()->sin()) / (m_Sun.dec().cos() * geo->lat()->cos()));
190 return SunSet + (HA - HASunset) / 24.0;
191}
192
193double KSAlmanac::findAltitude(const SkyPoint *p, double hour)
194{
195 return SkyPoint::findAltitude(p, dt, geo, hour).Degrees();
196}
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
double sunZenithAngleToTime(double z) const
Convert the zenithal distance of the sun to fraction of the day.
void setDate(const KStarsDateTime &utc_midnight)
Get/set the date for computations to the given date.
void setLocation(const GeoLocation *geo_)
Set the location for computations to the given location.
KSAlmanac()
KSAlmanac constructor initializing an almanac for the current KStarsData::Instance geolocation and ti...
Definition ksalmanac.cpp:13
void findPhase(const KSSun *Sun=nullptr)
Determine the phase angle of the moon, and assign the appropriate moon image.
Definition ksmoon.cpp:268
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false) override
Update position of the planet (reimplemented from SkyPoint)
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
const KStarsDateTime & lt() const
Definition kstarsdata.h:151
GeoLocation * geo()
Definition kstarsdata.h:230
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
long double djd() const
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
QTime riseSetTime(const KStarsDateTime &dt, const GeoLocation *geo, bool rst, bool exact=true) const
Determine the time at which the point will rise or set.
Definition skyobject.cpp:93
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
bool checkCircumpolar(const dms *gLat) const
Check if this point is circumpolar at the given geographic latitude.
static dms findAltitude(const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour=0)
Compute the altitude of a given skypoint hour hours from the given date/time.
virtual void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false)
Determine the current coordinates (RA, Dec) from the catalog coordinates (RA0, Dec0),...
Definition skypoint.cpp:582
const dms & alt() const
Definition skypoint.h:281
const double & Degrees() const
Definition dms.h:141
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition dms.h:390
LocalTime
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.