Kstars

lunareclipsehandler.cpp
1/*
2 SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "lunareclipsehandler.h"
8#include "skymapcomposite.h"
9#include "solarsystemcomposite.h"
10#include "dms.h"
11
12LunarEclipseHandler::LunarEclipseHandler(QObject * parent) : EclipseHandler(parent),
13 m_sun(), m_moon(), m_shadow(&m_moon, &m_sun, &m_Earth)
14{
15}
16
18{
19 m_mode = CLOSEST_APPROACH;
20
21 const long double SEARCH_INTERVAL = 5.l; // Days
22
25
26 int total = fullMoons.length();
27 if (total == 0)
28 return eclipses;
29
30 float step = 1 / total;
31 float progress = 0;
32
33 connect(this, &ApproachSolver::solverMadeProgress, this, [ &, this] (int dProgress)
34 {
35 float tmpProgress = roundf(progress + step * dProgress);
36 if (tmpProgress > progress)
37 {
38 progress = tmpProgress;
39 emit signalProgress(static_cast<int>(progress));
40 }
41 });
42
43 for(auto date : fullMoons)
44 {
45 findClosestApproach(date, date + SEARCH_INTERVAL, [&eclipses, this] (long double JD, dms)
46 {
49
51 switch (extended_type)
52 {
53 case KSEarthShadow::FULL_PENUMBRA:
54 case KSEarthShadow::FULL_UMBRA:
55 type = EclipseEvent::FULL;
56 break;
57 case KSEarthShadow::NONE:
58 return;
59 default:
60 type = EclipseEvent::PARTIAL;
61 break;
62 }
63
64 EclipseEvent_s event = std::make_shared<LunarEclipseEvent>(JD, *getGeoLocation(), type, extended_type);
66 eclipses.append(event);
67 });
68
69 progress++;
70 emit signalProgress(static_cast<int>(roundf(100 * (progress / total))));
71 }
72
75 return eclipses;
76}
77
78// FIXME: (Valentin) This doesn't work for now. We need another method.
79LunarEclipseDetails LunarEclipseHandler::findEclipseDetails(LunarEclipseEvent *event)
80{
82 // const long double INTERVAL = 1.l;
83
84 // const long double JD = event->getJD();
85 // const long double start = JD - INTERVAL;
86 // const long double stop = JD + INTERVAL;
87
88 LunarEclipseDetails details;
89 // details.available = true;
90 // details.eclipseTimes.insert(JD, LunarEclipseDetails::CLOSEST_APPROACH);
91
92 // auto type = event->getDetailedType();
93 // auto findBoth = [&](LunarEclipseDetails::EVENT ev1 /* first (temporal) */, LunarEclipseDetails::EVENT ev2) {
94 // QMap<long double, dms> tmpApproaches;
95
96 // QPair<long double, dms> out;
97 // findPrecise(&out, JD, 0.001, -1);
98 // details.eclipseTimes.insert(out.first, ev1);
99
100 // findPrecise(&out, JD, 0.001, 1);
101 // details.eclipseTimes.insert(out.first, ev2);
102 // };
103
104 // // waterfall method...
105
106 // if(type == KSEarthShadow::NONE) {
107 // details.available = false;
108 // return details;
109 // }
110
111 // if(type == KSEarthShadow::FULL_UMBRA) {
112 // m_mode = UMBRA_IMMERSION;
113 // findBoth(LunarEclipseDetails::BEGIN_FULL_PENUMRA, LunarEclipseDetails::END_FULL_PENUMRA);
114
115 // m_mode = UMBRA_CONTACT;
116 // findBoth(LunarEclipseDetails::BEGIN_UMBRA_CONTACT, LunarEclipseDetails::END_UMBRA_CONTACT);
117 // }
118
119 //// if(type == KSEarthShadow::FULL_PENUMBRA || type == KSEarthShadow::FULL_UMBRA) {
120
121 //// m_mode = UMR
122 //// };
123 return details;
124
125}
126
127LunarEclipseHandler::~LunarEclipseHandler()
128{
129
130}
131
133{
135 KSNumbers num(jd);
136 CachingDms LST(getGeoLocation()->GSTtoLST(t.gst()));
137 const CachingDms * LAT = getGeoLocation()->lat();
138
139 m_Earth.findPosition(&num);
140 m_sun.findPosition(&num, LAT, &LST, &m_Earth);
141 m_moon.findPosition(&num, LAT, &LST, &m_Earth);
142 m_shadow.findPosition(&num, LAT, &LST, &m_Earth);
143}
144
146{
147 dms moon_rad = dms(m_moon.angSize() / 120);
148 dms pen_rad = dms(m_shadow.getPenumbraAngSize() / 60);
149 dms um_rad = dms(m_shadow.getUmbraAngSize() / 60);
150
151 dms dist = findSkyPointDistance(&m_shadow, &m_moon);
152 switch (m_mode)
153 {
154 case CLOSEST_APPROACH:
155 return dist;
156 case PENUMBRA_CONTACT:
157 return dist - (moon_rad + pen_rad);
158 case PUNUMBRA_IMMERSION:
159 return dist + moon_rad - pen_rad;
160 case UMBRA_CONTACT:
161 return dist - (moon_rad + um_rad);
162 case UMBRA_IMMERSION:
163 return dist + moon_rad - um_rad;
164 }
165
166 return dms();
167}
168
170{
171 const double SEP_QUALITY = 0.1;
172
173 // we use the penumbra as measure :)
174 if(m_mode == CLOSEST_APPROACH)
175 return (m_shadow.getPenumbraAngSize() + m_moon.angSize()) / 60;
176 else
177 return SEP_QUALITY;
178}
179
180QVector<long double> LunarEclipseHandler::getFullMoons(long double startJD, long double endJD)
181{
182 const long double NEXT_STEP = 0.5l;
183 const long double INTERVAL = 26.5l;
184 long double &currentJD = startJD;
185
187 while(currentJD <= endJD)
188 {
190 KSNumbers num(currentJD);
191 CachingDms LST = getGeoLocation()->GSTtoLST(t.gst());
192
193 m_sun.updateCoords(&num, true, getGeoLocation()->lat(), &LST, true);
194 m_moon.updateCoords(&num, true, getGeoLocation()->lat(), &LST, true);
195 m_moon.findPhase(&m_sun);
196
197 if(m_moon.illum() > 0.9)
198 {
199 fullMoons.append(currentJD);
201 continue;
202 }
203
205 }
206
207 return fullMoons;
208}
209
210LunarEclipseEvent::LunarEclipseEvent(long double jd, GeoLocation geoPlace, EclipseEvent::ECLIPSE_TYPE type, KSEarthShadow::ECLIPSE_TYPE detailed_type)
211 : EclipseEvent (jd, geoPlace, type), m_detailedType { detailed_type }
212{
213 m_details.available = false;
214}
215
217{
218 switch(m_detailedType)
219 {
220 case KSEarthShadow::FULL_UMBRA:
221 return "Full Umbral";
222 case KSEarthShadow::FULL_PENUMBRA:
223 return "Full Penumbral";
224 case KSEarthShadow::PARTIAL:
225 case KSEarthShadow::NONE:
226 return "";
227 }
228 return "";
229}
230
232{
233 return KStarsData::Instance()->skyComposite()->solarSystemComposite()->moon();
234}
235
236void LunarEclipseEvent::slotShowDetails()
237{
238 if(!m_details.available)
239 {
240 LunarEclipseHandler handler;
242 handler.setGeoLocation(&loc);
243 handler.findEclipseDetails(this);
244 }
245}
void solverMadeProgress(int progress)
solverMadeProgress
dms findSkyPointDistance(SkyPoint *obj1, SkyPoint *obj2)
findSkyPointDistance
QMap< long double, dms > findClosestApproach(long double startJD, long double stopJD, const std::function< void(long double, dms)> &callback={})
Compute the closest approach of two planets in the given range.
GeoLocation * getGeoLocation()
getGeoLocation
void setGeoLocation(GeoLocation *geo)
Sets the geographic location to compute conjunctions at.
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
The EclipseEvent class.
ECLIPSE_TYPE
The ECLIPSE_TYPE_T enum.
GeoLocation getGeolocation()
getGeolocation
The EclipseHandler class.
void signalProgress(int)
signalProgress
void signalEventFound(EclipseEvent_s event)
signalEventFound
void signalComputationFinished()
signalComputationFinished
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
const CachingDms * lat() const
Definition geolocation.h:70
double getPenumbraAngSize() const
ECLIPSE_TYPE getEclipseType()
eclipse
ECLIPSE_TYPE
The ECLIPSE_TYPE enum describes the quality of an eclipse.
double getUmbraAngSize() const
double illum() const
Definition ksmoon.h:49
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 findPosition(const KSNumbers *num, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, const KSPlanetBase *Earth=nullptr)
Find position, including correction for Figure-of-the-Earth.
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)
double angSize() const
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
The LunarEclipseEvent class.
QString getExtraInfo() override
getExtraInfo
SkyObject * getEclipsingObjectFromSkyComposite() override
getEclipsingObjectFromSkyComposite
The LunarEclipseHandler class.
EclipseVector computeEclipses(long double startJD, long double endJD) override
compute
dms findDistance() override
Finds the angular distance between two solar system objects.
double getMaxSeparation() override
getMaxSeparation
void updatePositions(long double jd) override
updatePositions
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
Type type(const QSqlDatabase &db)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
The LunarEclipseDetails struct.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.