File indexing completed on 2024-04-21 14:46:50
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 #pragma once 0009 #include "dms.h" 0010 #include "skyobjects/ksplanet.h" 0011 #include "skycomponents/typedef.h" 0012 0013 #include <QObject> 0014 #include <QMap> 0015 #include <memory> 0016 0017 /** 0018 * @class ApproachSolver 0019 * @short Implements algorithms to find close approaches of two objects on the sky. 0020 * A class that implements a method to compute close approaches between any two solar system 0021 * objects excluding planetary moons. Given two such objects, this class has implementations of 0022 * algorithms required to find the time of closest approach in a given range of time. It is meant 0023 * to be subclassed and provides the boilerplate (+ common interface) for classes like KSKonjunct 0024 * and EclipseHandler. 0025 * 0026 * @author Akarsh Simha 0027 * @version 2.0 0028 */ 0029 class ApproachSolver : public QObject 0030 { 0031 Q_OBJECT 0032 public: 0033 explicit ApproachSolver(QObject *parent = nullptr); 0034 0035 /** 0036 * @short Sets the geographic location to compute conjunctions at 0037 * 0038 * @param geo Pointer to the GeoLocation object 0039 */ 0040 void setGeoLocation(GeoLocation *geo); 0041 0042 /** 0043 * @short Compute the closest approach of two planets in the given range 0044 * 0045 * @param startJD Julian Day corresponding to start of the calculation period 0046 * @param stopJD Julian Day corresponding to end of the calculation period 0047 * @param callback A callback function 0048 * @return Hash containing julian days of close conjunctions against separation 0049 */ 0050 QMap<long double, dms> findClosestApproach(long double startJD, 0051 long double stopJD, 0052 const std::function<void (long double, dms)> &callback = {}); // FIXME: QMap is awkward! 0053 0054 /** 0055 * @brief getGeoLocation 0056 * @return the currently set GeoLocation 0057 */ 0058 GeoLocation * getGeoLocation() { return m_geoPlace; } 0059 0060 0061 /** 0062 * @brief setMaxSeparation 0063 * @param sep - maximum allowed anglar separation 0064 */ 0065 void setMaxSeparation(double sep) { m_maxSeparation = sep; } 0066 void setMaxSeparation(dms sep) { m_maxSeparation = sep.radians(); } 0067 0068 signals: 0069 /** 0070 * @brief solverMadeProgress 0071 * @param progress - progress in percent 0072 */ 0073 void solverMadeProgress(int progress); 0074 0075 protected: 0076 // TODO: This one may be moved to KSConjunct 0077 0078 /** 0079 * @brief getMaxSeparation 0080 * @return the maximum separation allowed, based on the (guaranteed to be up-to-date) 0081 * parameters of the objects if overwritten. Here it's just a constant. 0082 */ 0083 virtual double getMaxSeparation() { return m_maxSeparation; } 0084 0085 /** 0086 * @brief findSkyPointDistance 0087 * @param obj1 0088 * @param obj2 0089 * @return the angular distance between two SkyPoints in arcminutes 0090 */ 0091 dms findSkyPointDistance(SkyPoint * obj1, SkyPoint * obj2); 0092 0093 /** 0094 * @short Finds the angular distance between two solar system objects. 0095 * @return The angular distance between the two bodies. 0096 */ 0097 virtual dms findDistance() = 0; 0098 0099 /** 0100 * @brief updatePositions 0101 * @short Update the positions of the objects involved. 0102 * @param jd Julian Day corresponding to the time of computation 0103 */ 0104 virtual void updatePositions(long double jd) = 0; 0105 0106 /** 0107 * @brief findStep 0108 * @return the step size used by findClosestApproach (in Julian Days) 0109 * 0110 * @short Make this as big as possible. The bigger it is, the more likely is a skip over... 0111 */ 0112 virtual double findInitialStep(long double startJD, long double stopJD) = 0; 0113 0114 /** 0115 * @short Compute the precise value of the extremum once the extremum has been detected. 0116 * 0117 * @param out A pointer to a QPair that stores the Julian Day and Separation corresponding to the extremum 0118 * @param jd Julian day corresponding to the endpoint of the interval where extremum was detected. 0119 * @param step The step in jd taken during computation earlier. (Defines the interval size) 0120 * @param prevSign The previous sign of increment in moving from jd - step to jd 0121 * 0122 * @return true if the extremum is a minimum 0123 */ 0124 bool findPrecise(QPair<long double, dms> *out, long double jd, 0125 double step, int prevSign); 0126 0127 KSPlanet m_Earth; 0128 0129 private: 0130 /** 0131 * @brief updateAndFindDistance 0132 * @param jd Julian Date for which to calculate 0133 * @return output of ApproachSolver::findDistance 0134 */ 0135 dms updateAndFindDistance(long double jd) { 0136 updatePositions(jd); 0137 return findDistance(); 0138 } 0139 0140 /** 0141 * @short Return the sign of an angle 0142 * 0143 * @param a The angle whose sign has to be returned 0144 * 0145 * @return (-1, 0, 1) if a.radians() is (-ve, zero, +ve) 0146 */ 0147 int sgn(dms a); 0148 0149 GeoLocation * m_geoPlace { nullptr }; 0150 double m_maxSeparation; 0151 };