1 /* 2 * Navigational Stars plug-in 3 * Copyright (C) 2020 Andy Kirkham 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. 18 */ 19 20 #ifndef NAVSTARSCALCULATOR_HPP 21 #define NAVSTARSCALCULATOR_HPP 22 23 /*! @defgroup navigationalStars Navigational Stars Plug-in 24 @{ 25 The Navigational Stars plugin marks a set of navigational stars. 26 27 The NavStars class is the main class of the plug-in. It manages the list of 28 navigational stars and manipulate show/hide markers of them. Markers 29 are not objects! 30 31 The plugin is also an example of a custom plugin that just marks existing stars. 32 33 <b>Configuration</b> 34 35 The plug-ins' configuration data is stored in Stellarium's main configuration 36 file (section [NavigationalStars]). 37 38 @} 39 */ 40 41 #include <cmath> 42 43 #include <QMap> 44 #include <QString> 45 46 #ifndef DEG2RAD 47 #define DEG2RAD(x) ((x * M_PI) / 180.) 48 #endif 49 50 #ifndef RAD2DEG 51 #define RAD2DEG(x) ((x * 180.) / M_PI) 52 #endif 53 54 //! Forward declaration for UT inputter. 55 struct NavStarCalculatorDegreeInputs; 56 57 //! @class NavStarsCalculator 58 //! @author Andy Kirkham 59 //! @ingroup navigationalStars 60 class NavStarsCalculator 61 { 62 public: 63 NavStarsCalculator(); 64 NavStarsCalculator(const NavStarCalculatorDegreeInputs* ip); 65 ~NavStarsCalculator(); 66 67 //! Calculate intermediates. 68 void execute(); 69 70 //! Get a string that represents degrees and decimal minutes of an angle. 71 //! Format is as per the standard Nautical Almanac, +/-DDDMM.m 72 //! @param double rad The angle in radians. 73 //! @param QString pos Use + or N or E. 74 //! @param QString neg Use - or S or W. 75 //! @return QString the representation of angle rad. 76 static QString radToDm(double rad, const QString &pos = "+", const QString &neg = "-"); 77 78 79 //! Ensure the supplied angle, in radians, is with 0 to 2PI. 80 //! @param double d The angle in radians. 81 //! @return The wrapped value. 82 static double wrap2pi(double d); 83 84 //! Ensure the supplied angle, in degrees, is with 0 to 360. 85 //! @param double d The angle in degrees. 86 //! @return The wrapped value. 87 static double wrap360(double d); 88 89 static bool useExtraDecimals; 90 static bool useDecimalDegrees; 91 92 private: 93 QString utc; 94 public: 95 NavStarsCalculator& setUTC(const QString& s); getUTC()96 QString getUTC() { return utc; } 97 98 QMap<QString, QString> printable(); 99 100 private: 101 double lmst; 102 double lmst_rad; 103 public: lmstDegreesPrintable()104 QString lmstDegreesPrintable() 105 { 106 QString sign = lmst < 0. ? "-" : "+"; 107 return QString("%1%2%3").arg(sign).arg(QString::number(lmst, 'f', 3)).arg("°"); 108 } lmstPrintable()109 QString lmstPrintable() { return radToDm(lmst_rad); } 110 111 private: 112 double sha_rad; 113 public: shaPrintable()114 QString shaPrintable() { return radToDm(sha_rad); } 115 116 private: 117 double lha; 118 public: lhaPrintable()119 QString lhaPrintable() { return radToDm(lha); } 120 121 private: 122 double hc_rad; 123 public: hcPrintable()124 QString hcPrintable() { return radToDm(hc_rad); } 125 126 private: 127 double zn_rad; 128 public: znPrintable()129 QString znPrintable() { return radToDm(zn_rad); } 130 131 private: 132 double gha_rad; 133 public: ghaPrintable()134 QString ghaPrintable() { return (radToDm(gha_rad)); } 135 136 private: 137 double gmst; 138 double gmst_rad; 139 public: getGmst()140 double getGmst() { return gmst; } setGmst(double d)141 NavStarsCalculator& setGmst(double d) 142 { 143 gmst = wrap360(d); 144 return *this; 145 } gmstDegreesPrintable()146 QString gmstDegreesPrintable() { 147 QString sign = gmst < 0. ? "-" : "+"; 148 return QString("%1%2%3").arg(sign).arg(QString::number(gmst, 'f', 3)).arg("°"); 149 } gmstPrintable()150 QString gmstPrintable() { return radToDm(gmst_rad); } 151 152 private: 153 double lat_deg; 154 double lat_rad; 155 public: setLatDeg(double d)156 NavStarsCalculator& setLatDeg(double d) 157 { 158 lat_deg = d; 159 lat_rad = DEG2RAD(d); 160 return *this; 161 } latPrintable()162 QString latPrintable() { return radToDm(lat_rad, "N", "S"); } 163 164 private: 165 double lon_deg; 166 double lon_rad; 167 public: setLonDeg(double d)168 NavStarsCalculator& setLonDeg(double d) 169 { 170 lon_deg = d; 171 lon_rad = DEG2RAD(d); 172 return *this; 173 } lonPrintable()174 QString lonPrintable() { return radToDm(lon_rad, "E", "W"); } 175 176 private: 177 double gp_lat_deg; 178 double gp_lat_rad; 179 public: setGpLatRad(double d)180 NavStarsCalculator& setGpLatRad(double d) 181 { 182 gp_lat_rad = d; 183 gp_lat_deg = DEG2RAD(d); 184 return *this; 185 } gplatPrintable()186 QString gplatPrintable() { return radToDm(gp_lat_rad, "N", "S"); } 187 188 private: 189 double gp_lon_deg; 190 double gp_lon_rad; 191 public: setGpLonRad(double d)192 NavStarsCalculator& setGpLonRad(double d) 193 { 194 gp_lon_rad = d; 195 gp_lon_deg = DEG2RAD(d); 196 return *this; 197 } gplonPrintable()198 QString gplonPrintable() { return radToDm(gp_lon_rad, "E", "W"); } 199 200 private: 201 double az_rad; 202 public: setAzRad(double d)203 NavStarsCalculator& setAzRad(double d) 204 { 205 az_rad = d; 206 return *this; 207 } 208 209 private: 210 double alt_rad; 211 public: setAltRad(double d)212 NavStarsCalculator& setAltRad(double d) 213 { 214 alt_rad = d; 215 return *this; 216 } 217 218 private: 219 double az_app_rad; 220 public: setAzAppRad(double d)221 NavStarsCalculator& setAzAppRad(double d) 222 { 223 az_app_rad = d; 224 return *this; 225 } azAppPrintable()226 QString azAppPrintable() { return radToDm(az_app_rad); } 227 228 private: 229 double alt_app_rad; 230 public: setAltAppRad(double d)231 NavStarsCalculator& setAltAppRad(double d) 232 { 233 alt_app_rad = d; 234 return *this; 235 } altAppPrintable()236 QString altAppPrintable() { return radToDm(alt_app_rad); } addAltAppRad(double d)237 NavStarsCalculator& addAltAppRad(double d) 238 { 239 alt_app_rad += d; 240 return *this; 241 } 242 243 private: 244 double jd; 245 public: getJd()246 double getJd() { return jd; } setJd(double d)247 NavStarsCalculator& setJd(double d) 248 { 249 jd = d; 250 return *this; 251 } 252 253 private: 254 double jde; 255 public: getJde()256 double getJde() { return jde; } setJde(double d)257 NavStarsCalculator& setJde(double d) 258 { 259 jde = d; 260 return *this; 261 } 262 263 private: 264 double dec_rad; 265 public: setDecRad(double d)266 NavStarsCalculator& setDecRad(double d) 267 { 268 dec_rad = d; 269 return *this; 270 } decPrintable()271 QString decPrintable() { return radToDm(dec_rad); } 272 273 private: 274 double ra_rad; 275 public: setRaRad(double d)276 NavStarsCalculator& setRaRad(double d) 277 { 278 ra_rad = d; 279 sha_rad = (2. * M_PI) - ra_rad; 280 return *this; 281 } 282 }; 283 284 // When exactly does code to support Unit Testing become intrusive? 285 // I've done worse than this before so it's not all that bad. 286 // See specialized constructor above. 287 struct NavStarCalculatorDegreeInputs 288 { 289 QString utc; 290 double ra; 291 double dec; 292 double lat; 293 double lon; 294 double jd; 295 double jde; 296 double gmst; 297 double az; 298 double alt; 299 double az_app; 300 double alt_app; 301 }; 302 303 #endif /* NAVSTARSCALCULATOR_HPP */ 304