Kstars

lunareclipsehandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2018 Valentin Boettcher <[email protected]>
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 
12 LunarEclipseHandler::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 
23  QVector<EclipseEvent_s> eclipses;
24  QVector<long double> fullMoons = getFullMoons(startJD, endJD);
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  {
48  updatePositions(JD);
49 
50  KSEarthShadow::ECLIPSE_TYPE extended_type = m_shadow.getEclipseType();
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);
65  emit signalEventFound(event);
66  eclipses.append(event);
67  });
68 
69  progress++;
70  emit signalProgress(static_cast<int>(roundf(100 * (progress / total))));
71  }
72 
73  emit signalProgress(100);
75  return eclipses;
76 }
77 
78 // FIXME: (Valentin) This doesn't work for now. We need another method.
79 LunarEclipseDetails LunarEclipseHandler::findEclipseDetails(LunarEclipseEvent *event)
80 {
81  Q_UNUSED(event);
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 
127 LunarEclipseHandler::~LunarEclipseHandler()
128 {
129 
130 }
131 
133 {
134  KStarsDateTime t(jd);
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 
180 QVector<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 
186  QVector<long double> fullMoons;
187  while(currentJD <= endJD)
188  {
189  KStarsDateTime t(currentJD);
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);
200  currentJD += INTERVAL;
201  continue;
202  }
203 
204  currentJD += NEXT_STEP;
205  }
206 
207  return fullMoons;
208 }
209 
210 LunarEclipseEvent::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 
236 void LunarEclipseEvent::slotShowDetails()
237 {
238  if(!m_details.available)
239  {
240  LunarEclipseHandler handler;
241  GeoLocation loc = getGeolocation();
242  handler.setGeoLocation(&loc);
243  handler.findEclipseDetails(this);
244  }
245 }
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
The EclipseEvent class.
void signalComputationFinished()
signalComputationFinished
ECLIPSE_TYPE
The ECLIPSE_TYPE enum describes the quality of an eclipse.
Definition: ksearthshadow.h:45
GeoLocation * getGeoLocation()
getGeoLocation
Type type(const QSqlDatabase &db)
void solverMadeProgress(int progress)
solverMadeProgress
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:18
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 append(const T &value)
QString getExtraInfo() override
getExtraInfo
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
EclipseVector computeEclipses(long double startJD, long double endJD) override
compute
The EclipseHandler class.
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)
void signalProgress(int)
signalProgress
The LunarEclipseHandler class.
virtual bool event(QEvent *e)
GeoLocation getGeolocation()
getGeolocation
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const CachingDms * lat() const
Definition: geolocation.h:70
double getUmbraAngSize() const
Definition: ksearthshadow.h:92
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
The LunarEclipseEvent class.
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.
SkyObject * getEclipsingObjectFromSkyComposite() override
getEclipsingObjectFromSkyComposite
void updatePositions(long double jd) override
updatePositions
double getPenumbraAngSize() const
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:165
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
double angSize() const
Definition: ksplanetbase.h:184
dms findDistance() override
Finds the angular distance between two solar system objects.
double getMaxSeparation() override
getMaxSeparation
void signalEventFound(EclipseEvent_s event)
signalEventFound
int length() const const
The LunarEclipseDetails struct.
ECLIPSE_TYPE
The ECLIPSE_TYPE_T enum.
void setGeoLocation(GeoLocation *geo)
Sets the geographic location to compute conjunctions at.
dms findSkyPointDistance(SkyPoint *obj1, SkyPoint *obj2)
findSkyPointDistance
Information about an object in the sky.
Definition: skyobject.h:41
Relevant data about an observing location on Earth.
Definition: geolocation.h:27
ECLIPSE_TYPE getEclipseType()
eclipse
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.