Kstars

approachsolver.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Akarsh Simha <[email protected]>
3  SPDX-FileCopyrightText: 2018 Valentin Boettcher <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "approachsolver.h"
9 #include <kstars_debug.h>
10 
11 ApproachSolver::ApproachSolver(QObject *parent) : QObject(parent)
12 {
13  m_geoPlace = KStarsData::Instance()->geo();
14  m_Earth = KSPlanet(i18n("Earth"), QString(), QColor("white"), 12756.28 /*diameter in km*/);
15 }
16 
18 {
19  if (geo != nullptr)
20  m_geoPlace = geo;
21  else
22  m_geoPlace = KStarsData::Instance()->geo();
23 }
24 
25 // FIXME: We need a better algo for finding approaches!
27  long double stopJD, std::function<void (long double, dms)> const &callback)
28 {
29  QMap<long double, dms> Separations;
30  QPair<long double, dms> extremum;
31  dms Dist;
32  dms prevDist;
33 
34  double step, step0;
35  int Sign, prevSign;
36 
37  // qCDebug(KSTARS) << "Entered KSConjunct::findClosestApproach() with startJD = " << (double)startJD;
38  // qCDebug(KSTARS) << "Initial Positional Information: \n";
39  // qCDebug(KSTARS) << m_object1->name() << ": RA = " << m_object1->ra() -> toHMSString() << "; Dec = " << m_object1->dec() -> toDMSString() << "\n";
40  // qCDebug(KSTARS) << m_object2->name() << ": RA = " << m_object2->ra() -> toHMSString() << "; Dec = " << m_object2->dec() -> toDMSString() << "\n";
41  prevSign = 0;
42 
43  step0 = findInitialStep(startJD, stopJD);
44  step = step0;
45  // qCDebug(KSTARS) << "Initial Separation between " << m_object1->name() << " and " << m_object2->name() << " = " << (prevDist.toDMSString());
46 
47  long double jd = startJD;
48  prevDist = updateAndFindDistance(jd);
49  jd += step;
50  while (jd <= stopJD)
51  {
52  int progress = int(100.0 * (jd - startJD) / (stopJD - startJD));
53  emit solverMadeProgress(progress);
54 
55  Dist = updateAndFindDistance(jd);
56  Sign = sgn(Dist - prevDist);
57  // qCDebug(KSTARS) << "Dist = " << Dist.toDMSString() << "; prevDist = " << prevDist.toDMSString() << "; Difference = " << (Dist.Degrees() - prevDist.Degrees()) << "; Step = " << step;
58 
59  //How close are we to a conjunction, and how fast are we approaching one?
60  double factor = fabs((Dist.Degrees() - prevDist.Degrees()) / Dist.Degrees());
61  if (factor > 10.0) //let's go faster!
62  {
63  step = step0 * factor / 10.0;
64  }
65  else //slow down, we're getting close!
66  {
67  step = step0;
68  }
69 
70  if (Sign != prevSign && prevSign == -1) //all right, we may have just passed a conjunction
71  {
72  if (step > step0) //mini-loop to back up and make sure we're close enough
73  {
74  // qCDebug(KSTARS) << "Entering slow loop: ";
75  jd -= step;
76  step = step0;
77  Sign = prevSign;
78  while (jd <= stopJD)
79  {
80  Dist = updateAndFindDistance(jd);
81  Sign = sgn(Dist - prevDist);
82  // qCDebug(KSTARS) << "Dist=" << Dist.toDMSString() << "; prevDist=" << prevDist.toDMSString() << "; Diff=" << (Dist.Degrees() - prevDist.Degrees()) << "djd=" << (int)(jd - startJD);
83  if (Sign != prevSign)
84  break;
85 
86  prevDist = Dist;
87  prevSign = Sign;
88  jd += step;
89  }
90  }
91 
92  // qCDebug(KSTARS) << "Sign = " << Sign << " and " << "prevSign = " << prevSign << ": Entering findPrecise()\n";
93  if (findPrecise(&extremum, jd, step, Sign))
94  {
95  if (extremum.second.radians() < getMaxSeparation())
96  {
97  Separations.insert(extremum.first, extremum.second);
98 
99  if(callback)
100  callback(extremum.first, extremum.second);
101  }
102  }
103  }
104 
105  prevDist = Dist;
106  prevSign = Sign;
107  jd += step;
108  }
109 
110  return Separations;
111 }
112 
114  double step, int prevSign)
115 {
116  dms prevDist;
117  int Sign;
118  dms Dist;
119 
120  if (out == nullptr)
121  {
122  qCDebug(KSTARS) << "ERROR: Argument out to KSConjunct::findPrecise(...) was nullptr!";
123  return false;
124  }
125 
126  prevDist = updateAndFindDistance(jd);
127 
128  step = -step / 2.0;
129  prevSign = -prevSign;
130 
131  while (true)
132  {
133  jd += step;
134  Dist = updateAndFindDistance(jd);
135  // qCDebug(KSTARS) << "Dist=" << Dist.toDMSString() << "; prevDist=" << prevDist.toDMSString() << "; Diff=" << (Dist.Degrees() - prevDist.Degrees()) << "step=" << step;
136 
137  if (fabs(step) < 1.0 / (24.0 * 60.0))
138  {
139  out->first = jd - step / 2.0;
140  out->second = updateAndFindDistance(jd - step / 2.0);
141  if (out->second.radians() < updateAndFindDistance(jd - 5.0).radians())
142  return true;
143  else
144  return false;
145  }
146  Sign = sgn(Dist - prevDist);
147  if (Sign != prevSign)
148  {
149  step = -step / 2.0;
150  Sign = -Sign;
151  }
152  prevSign = Sign;
153  prevDist = Dist;
154  }
155 }
156 
158 {
159  dms dist;
160  dist.setRadians(obj1->angularDistanceTo(obj2).radians());
161  return dist;
162 }
163 
164 int ApproachSolver::sgn(dms a)
165 {
166  // Auxiliary function used by the KSConjunct::findClosestApproach(...)
167  // method and the KSConjunct::findPrecise(...) method
168 
169  return ((a.radians() > 0) ? 1 : ((a.radians() < 0) ? -1 : 0));
170 }
171 
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
QMap::iterator insert(const Key &key, const T &value)
QString i18n(const char *text, const TYPE &arg...)
GeoLocation * geo()
Definition: kstarsdata.h:229
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.
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition: skypoint.cpp:899
Provides necessary information about objects in the solar system.
Definition: ksplanet.h:32
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition: dms.h:328
double radians() const
Express the angle in radians.
Definition: dms.h:320
const double & Degrees() const
Definition: dms.h:141
bool findPrecise(QPair< long double, dms > *out, long double jd, double step, int prevSign)
Compute the precise value of the extremum once the extremum has been detected.
void setGeoLocation(GeoLocation *geo)
Sets the geographic location to compute conjunctions at.
dms findSkyPointDistance(SkyPoint *obj1, SkyPoint *obj2)
findSkyPointDistance
Relevant data about an observing location on Earth.
Definition: geolocation.h:27
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.