File indexing completed on 2024-04-28 11:25:27
0001 /* 0002 SPDX-FileCopyrightText: 2008 Akarsh Simha <akarsh.simha@kdemail.net> 0003 SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "approachsolver.h" 0009 #include <kstars_debug.h> 0010 0011 ApproachSolver::ApproachSolver(QObject *parent) : QObject(parent) 0012 { 0013 m_geoPlace = KStarsData::Instance()->geo(); 0014 m_Earth = KSPlanet(i18n("Earth"), QString(), QColor("white"), 12756.28 /*diameter in km*/); 0015 } 0016 0017 void ApproachSolver::setGeoLocation(GeoLocation *geo) 0018 { 0019 if (geo != nullptr) 0020 m_geoPlace = geo; 0021 else 0022 m_geoPlace = KStarsData::Instance()->geo(); 0023 } 0024 0025 // FIXME: We need a better algo for finding approaches! 0026 QMap<long double, dms> ApproachSolver::findClosestApproach(long double startJD, 0027 long double stopJD, std::function<void (long double, dms)> const &callback) 0028 { 0029 QMap<long double, dms> Separations; 0030 QPair<long double, dms> extremum; 0031 dms Dist; 0032 dms prevDist; 0033 0034 double step, step0; 0035 int Sign, prevSign; 0036 0037 // qCDebug(KSTARS) << "Entered KSConjunct::findClosestApproach() with startJD = " << (double)startJD; 0038 // qCDebug(KSTARS) << "Initial Positional Information: \n"; 0039 // qCDebug(KSTARS) << m_object1->name() << ": RA = " << m_object1->ra() -> toHMSString() << "; Dec = " << m_object1->dec() -> toDMSString() << "\n"; 0040 // qCDebug(KSTARS) << m_object2->name() << ": RA = " << m_object2->ra() -> toHMSString() << "; Dec = " << m_object2->dec() -> toDMSString() << "\n"; 0041 prevSign = 0; 0042 0043 step0 = findInitialStep(startJD, stopJD); 0044 step = step0; 0045 // qCDebug(KSTARS) << "Initial Separation between " << m_object1->name() << " and " << m_object2->name() << " = " << (prevDist.toDMSString()); 0046 0047 long double jd = startJD; 0048 prevDist = updateAndFindDistance(jd); 0049 jd += step; 0050 while (jd <= stopJD) 0051 { 0052 int progress = int(100.0 * (jd - startJD) / (stopJD - startJD)); 0053 emit solverMadeProgress(progress); 0054 0055 Dist = updateAndFindDistance(jd); 0056 Sign = sgn(Dist - prevDist); 0057 // qCDebug(KSTARS) << "Dist = " << Dist.toDMSString() << "; prevDist = " << prevDist.toDMSString() << "; Difference = " << (Dist.Degrees() - prevDist.Degrees()) << "; Step = " << step; 0058 0059 //How close are we to a conjunction, and how fast are we approaching one? 0060 double factor = fabs((Dist.Degrees() - prevDist.Degrees()) / Dist.Degrees()); 0061 if (factor > 10.0) //let's go faster! 0062 { 0063 step = step0 * factor / 10.0; 0064 } 0065 else //slow down, we're getting close! 0066 { 0067 step = step0; 0068 } 0069 0070 if (Sign != prevSign && prevSign == -1) //all right, we may have just passed a conjunction 0071 { 0072 if (step > step0) //mini-loop to back up and make sure we're close enough 0073 { 0074 // qCDebug(KSTARS) << "Entering slow loop: "; 0075 jd -= step; 0076 step = step0; 0077 Sign = prevSign; 0078 while (jd <= stopJD) 0079 { 0080 Dist = updateAndFindDistance(jd); 0081 Sign = sgn(Dist - prevDist); 0082 // qCDebug(KSTARS) << "Dist=" << Dist.toDMSString() << "; prevDist=" << prevDist.toDMSString() << "; Diff=" << (Dist.Degrees() - prevDist.Degrees()) << "djd=" << (int)(jd - startJD); 0083 if (Sign != prevSign) 0084 break; 0085 0086 prevDist = Dist; 0087 prevSign = Sign; 0088 jd += step; 0089 } 0090 } 0091 0092 // qCDebug(KSTARS) << "Sign = " << Sign << " and " << "prevSign = " << prevSign << ": Entering findPrecise()\n"; 0093 if (findPrecise(&extremum, jd, step, Sign)) 0094 { 0095 if (extremum.second.radians() < getMaxSeparation()) 0096 { 0097 Separations.insert(extremum.first, extremum.second); 0098 0099 if(callback) 0100 callback(extremum.first, extremum.second); 0101 } 0102 } 0103 } 0104 0105 prevDist = Dist; 0106 prevSign = Sign; 0107 jd += step; 0108 } 0109 0110 return Separations; 0111 } 0112 0113 bool ApproachSolver::findPrecise(QPair<long double, dms> *out, long double jd, 0114 double step, int prevSign) 0115 { 0116 dms prevDist; 0117 int Sign; 0118 dms Dist; 0119 0120 if (out == nullptr) 0121 { 0122 qCDebug(KSTARS) << "ERROR: Argument out to KSConjunct::findPrecise(...) was nullptr!"; 0123 return false; 0124 } 0125 0126 prevDist = updateAndFindDistance(jd); 0127 0128 step = -step / 2.0; 0129 prevSign = -prevSign; 0130 0131 while (true) 0132 { 0133 jd += step; 0134 Dist = updateAndFindDistance(jd); 0135 // qCDebug(KSTARS) << "Dist=" << Dist.toDMSString() << "; prevDist=" << prevDist.toDMSString() << "; Diff=" << (Dist.Degrees() - prevDist.Degrees()) << "step=" << step; 0136 0137 if (fabs(step) < 1.0 / (24.0 * 60.0)) 0138 { 0139 out->first = jd - step / 2.0; 0140 out->second = updateAndFindDistance(jd - step / 2.0); 0141 if (out->second.radians() < updateAndFindDistance(jd - 5.0).radians()) 0142 return true; 0143 else 0144 return false; 0145 } 0146 Sign = sgn(Dist - prevDist); 0147 if (Sign != prevSign) 0148 { 0149 step = -step / 2.0; 0150 Sign = -Sign; 0151 } 0152 prevSign = Sign; 0153 prevDist = Dist; 0154 } 0155 } 0156 0157 dms ApproachSolver::findSkyPointDistance(SkyPoint * obj1, SkyPoint * obj2) 0158 { 0159 dms dist; 0160 dist.setRadians(obj1->angularDistanceTo(obj2).radians()); 0161 return dist; 0162 } 0163 0164 int ApproachSolver::sgn(dms a) 0165 { 0166 // Auxiliary function used by the KSConjunct::findClosestApproach(...) 0167 // method and the KSConjunct::findPrecise(...) method 0168 0169 return ((a.radians() > 0) ? 1 : ((a.radians() < 0) ? -1 : 0)); 0170 } 0171