Kstars

approachsolver.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Akarsh Simha <akarsh.simha@kdemail.net>
3 SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "approachsolver.h"
9#include <kstars_debug.h>
10
11ApproachSolver::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
113bool ApproachSolver::findPrecise(QPair<long double, dms> *out, long double jd,
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
164int 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
void solverMadeProgress(int progress)
solverMadeProgress
dms findSkyPointDistance(SkyPoint *obj1, SkyPoint *obj2)
findSkyPointDistance
virtual double findInitialStep(long double startJD, long double stopJD)=0
findStep
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.
void setGeoLocation(GeoLocation *geo)
Sets the geographic location to compute conjunctions at.
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.
virtual double getMaxSeparation()
getMaxSeparation
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
A subclass of KSPlanetBase for seven of the major planets in the solar system (Earth and Pluto have t...
Definition ksplanet.h:33
GeoLocation * geo()
Definition kstarsdata.h:230
The sky coordinates of a point in the sky.
Definition skypoint.h:45
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition skypoint.cpp:899
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
double radians() const
Express the angle in radians.
Definition dms.h:325
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition dms.h:333
const double & Degrees() const
Definition dms.h:141
QString i18n(const char *text, const TYPE &arg...)
iterator insert(const Key &key, const T &value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:38:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.