• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 15291774563

28 May 2025 04:48AM UTC coverage: 11.932% (-0.02%) from 11.952%
15291774563

push

github

alex-w
Fix comet discovery data

14635 of 122658 relevant lines covered (11.93%)

18292.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.93
/src/core/StelUtils.hpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2002 Fabien Chereau
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 STELUTILS_HPP
21
#define STELUTILS_HPP
22

23
#include <cmath>
24
#include "VecMath.hpp"
25

26
#include <QVariantMap>
27
#include <QDateTime>
28
#include <QString>
29

30
// astronomical unit (km)
31
#define AU 149597870.691
32
#define AUf 149597870.691f
33
#define AU_KM (1.0/149597870.691)
34
#define AU_KMf (1.0f/149597870.691f)
35
// Parsec (km)
36
#define PARSEC 30.857e12
37
// Parsec (LY)
38
#define PARSEC_LY 3.261563777
39
// speed of light (km/sec)
40
#define SPEED_OF_LIGHT 299792.458
41
// Ecliptic obliquity of J2000.0, degrees
42
#define EPS_0 23.4392803055555555555556
43
// Equatorial radius of the Earth in km (WGS-84)
44
#define EARTH_RADIUS 6378.1366
45
// Equatorial radius of the Sun in km
46
#define SUN_RADIUS 696000.
47
// Equatorial radius of the Moon in km
48
#define MOON_RADIUS 1738.
49
// 1 mas to 1 radian, is M_PI / (3600000. * 180.)
50
#define MAS2RAD 4.8481368110953594e-9
51
// julian year in seconds that is 365.25 * 86400.
52
#define JYEAR_SECONDS 31557600.0
53

54
// Add a few frequently used extra math-type literals
55
#ifndef M_PI_180
56
        #define M_PI_180    (M_PI/180.)
57
#endif
58
#ifndef M_180_PI
59
        #define M_180_PI    (180./M_PI)
60
#endif
61
// Add some math literals in float version to avoid many static_casts
62
#ifndef M_PIf
63
        #define M_PIf       3.14159265358979323846f   // pi
64
#endif
65
#ifndef M_PI_2f
66
        #define M_PI_2f     1.57079632679489661923f   // pi/2
67
#endif
68
#ifndef M_PI_4f
69
        #define M_PI_4f     0.785398163397448309616f  // pi/4
70
#endif
71
#ifndef M_1_PIf
72
        #define M_1_PIf     0.318309886183790671538f  // 1/pi
73
#endif
74
#ifndef M_2_PIf
75
        #define M_2_PIf     0.636619772367581343076f  // 2/pi
76
#endif
77
#ifndef M_PI_180f
78
        #define M_PI_180f   (M_PIf/180.f)
79
#endif
80
#ifndef M_180_PIf
81
        #define M_180_PIf   (180.f/M_PIf)
82
#endif
83

84
#define stelpow10f(x) std::exp((x) * 2.3025850930f)
85

86
#define L1S(x) QLatin1String(x)
87

88
// Allow parallel evaluation of std::transform_reduce(std::execution::par, ...) or
89
// std::sort(std::execution::par, ...) where known. Not all compilers know it.
90
// Use std::transform_reduce(STD_EXECUTION_PAR_COMMA ...) for the general case.
91
#if STD_EXECUTION_KNOWN
92
# define STD_EXECUTION_PAR_COMMA std::execution::par,
93
#else
94
# define STD_EXECUTION_PAR_COMMA
95
#endif
96

97
constexpr double DEFAULT_FONT_SIZE = 13;
98

99
//! @namespace StelUtils contains general purpose utility functions.
100
namespace StelUtils
101
{
102
        static inline constexpr double J2000 = 2451545.0;
103

104
        //! Return the full name of stellarium, i.e. "Stellarium 23.1"
105
        QString getApplicationName();
106

107
        //! Return the version of stellarium, i.e. "23.1.0"
108
        QString getApplicationVersion();
109

110
        //! Return the public version of stellarium, i.e. "23.1"
111
        QString getApplicationPublicVersion();
112

113
        //! Return the series of stellarium, i.e. "23.0"
114
        QString getApplicationSeries();
115

116
        //! Return the name and the version of operating system, i.e. "macOS 12.5"
117
        QString getOperatingSystemInfo();
118

119
        //! Return the user agent name, i.e. "Stellarium/0.15.0 (Linux)"
120
        QString getUserAgentString();
121

122
        /*! \brief Get a long integer from a JSON value
123
         *
124
         *  QJsonValue stores JSON numbers as double-precision floating-point values. This means
125
         *  that numbers greater than 2^53-1 will be rounded, which is unacceptable for e.g. ids
126
         *  like those of the Gaia catalog.
127
         *  This function supports, in addition to normal JSON numbers, also representations of
128
         *  numbers by JSON strings. If the value passed is a JSON string, it will be parsed to a
129
         *  number. If it's a JSON number less than 2^53, it will be returned as is. Otherwise it
130
         *  will return 0, as QJsonValue's getters would in case of a type mismatch.
131
         */
132
        qint64 getLongLong(const class QJsonValue& v);
133

134
        inline const QString getEndLineChar() {
1✔
135
                #ifdef Q_OS_WIN
136
                const QString stelEndl="\r\n";
137
                #else
138
                const QString stelEndl="\n";
1✔
139
                #endif
140
                return stelEndl;
1✔
141
        }
142

143
        //! Convert hours, minutes, seconds to decimal hours
144
        inline double hmsToHours(const unsigned int h, const unsigned int m, const double s){
43✔
145
                return static_cast<double>(h)+static_cast<double>(m)/60.+s/3600.;
43✔
146
        }
147

148
        //! Convert an angle in hms format to radian.
149
        //! @param h hour component
150
        //! @param m minute component
151
        //! @param s second component
152
        //! @return angle in radian
153
        inline double hmsToRad(const unsigned int h, const unsigned int m, const double s){
15✔
154
                return hmsToHours(h, m, s)*M_PI/12.;
15✔
155
        }
156

157
        //! Convert an angle in +-dms format to radian.
158
        //! @param d degree component
159
        //! @param m arcmin component
160
        //! @param s arcsec component
161
        //! @return angle in radian
162
        inline double dmsToRad(const int d, const unsigned int m, const double s){
41✔
163
                double rad = M_PI_180*qAbs(d)+M_PI/10800.*m+s*M_PI/648000.;
41✔
164
                return (d<0 ? -rad : rad);
41✔
165
        }
166

167
        //! Convert an angle in radian to hms format.
168
        //! @param rad input angle in radian
169
        //! @param h hour component
170
        //! @param m minute component
171
        //! @param s second component
172
        void radToHms(double rad, unsigned int& h, unsigned int& m, double& s);
173

174
        //! Convert an angle in radian to +-dms format.
175
        //! @param rad input angle in radian
176
        //! @param sign true if positive, false otherwise
177
        //! @param d degree component
178
        //! @param m minute component
179
        //! @param s second component
180
        void radToDms(double rad, bool& sign, unsigned int& d, unsigned int& m, double& s);
181

182
        //! Convert an angle in radian to decimal degree.
183
        //! @param rad input angle in radian
184
        //! @param sign true if positive, false otherwise
185
        //! @param deg decimal degree
186
        Q_DECL_DEPRECATED_X("just use rad*M_180_PI instead")
187
        void radToDecDeg(double rad, bool& sign, double& deg);
188

189
        //! Convert an angle in radian to a decimal degree string.
190
        //! @param angle input angle in radian
191
        //! @param precision
192
        //! @param useD Define if letter "d" must be used instead of deg sign
193
        //! @param positive Define if function should use 0-360 degrees
194
        QString radToDecDegStr(const double angle, const int precision = 4, const bool useD=false, const bool positive=false);
195

196
        //! Convert an angle in radian to a hms formatted string.
197
        //! If the second, minute part is == 0, it is not output
198
        //! @param angle input angle in radian
199
        QString radToHmsStrAdapt(const double angle);
200

201
        //! Convert an angle in radian to a hms formatted string.
202
        //! @param angle input angle in radian
203
        //! @param decimal output decimal second value
204
        QString radToHmsStr(const double angle, const bool decimal=false);
205

206
        //! Convert an angle in radian to a dms formatted string.
207
        //! If the second, minute part is == 0, it is not output
208
        //! @param angle input angle in radian
209
        //! @param useD Define if letter "d" must be used instead of deg sign
210
        QString radToDmsStrAdapt(const double angle, const bool useD=false);
211

212
        //! Convert an angle in radian to a dms formatted string.
213
        //! @param angle input angle in radian        
214
        //! @param decimal output second value with decimal fraction
215
        //! @param useD Define if letter "d" must be used instead of deg sign
216
        QString radToDmsStr(const double angle, const bool decimal=false, const bool useD=false);
217

218
        //! Convert an angle in radian to a dms formatted string.
219
        //! @param angle input angle in radian
220
        //! @param precision
221
        //! @param useD Define if letter "d" must be used instead of deg sign
222
        QString radToDmsPStr(const double angle, const int precision = 0, const bool useD=false);
223

224
        //! Convert an angle in decimal degree to +-dms format.
225
        //! @param angle input angle in decimal degree
226
        //! @param sign true if positive, false otherwise
227
        //! @param d degree component
228
        //! @param m minute component
229
        //! @param s second component
230
        void decDegToDms(double angle, bool& sign, unsigned int& d, unsigned int& m, double& s);
231

232
        //! Convert an angle in decimal degrees to a dms formatted string.
233
        //! @param angle input angle in decimal degrees
234
        QString decDegToDmsStr(const double angle);
235

236
        //! Convert latitude in decimal degrees to a dms formatted string or use decimal values.
237
        //! @param latitude in decimal degrees
238
        //! @param dms set true to use DMS formatted string
239
        QString decDegToLatitudeStr(const double latitude, bool dms = true);
240

241
        //! Convert longitude in decimal degrees to a dms formatted string.
242
        //! @param longitude in decimal degrees
243
        //! @param eastPositive set true to counting East direction positive
244
        //! @param semiSphere set true to use -180..180 degrees range (0..360 degrees otherwise)
245
        //! @param dms set true to use DMS formatted string
246
        QString decDegToLongitudeStr(const double longitude, bool eastPositive = true, bool semiSphere = true, bool dms = true);
247

248
        //! Convert a dms formatted string to an angle in radian
249
        //! @param s The input string
250
        double dmsStrToRad(const QString& s);
251

252
        //! Convert from spherical coordinates to Rectangular direction.
253
        //! @param lng longitude in radian
254
        //! @param lat latitude in radian
255
        //! @param v the resulting 3D unit vector
256
        inline void spheToRect(const double lng, const double lat, Vec3d& v){
625✔
257
                const double cosLat = cos(lat);
625✔
258
                v.set(cos(lng) * cosLat, sin(lng) * cosLat, sin(lat));
625✔
259
        }
625✔
260

261
        //! Convert from spherical coordinates to Rectangular direction.
262
        //! @param lng longitude in radian
263
        //! @param lat latitude in radian
264
        //! @param v the resulting 3D unit vector
265
        inline void spheToRect(const float lng, const float lat, Vec3f& v){
83✔
266
                const double dlng = static_cast<double>(lng), dlat = static_cast<double>(lat), cosLat = cos(dlat);
83✔
267
                v.set(static_cast<float>(cos(dlng) * cosLat), static_cast<float>(sin(dlng) * cosLat), sinf(lat));
83✔
268
        }
83✔
269

270
        //! Convert from spherical coordinates to Rectangular direction.
271
        //! @param lng longitude in radian
272
        //! @param lat latitude in radian
273
        //! @param v the resulting 3D unit vector
274
        inline void spheToRect(const double lng, const double lat, Vec3f& v){
275
                const float cosLat = cos(static_cast<float>(lat));
276
                v.set(cos(static_cast<float>(lng)) * cosLat, sin(static_cast<float>(lng)) * cosLat, sin(static_cast<float>(lat)));
277
        }
278

279
        //! Convert from spherical coordinates to Rectangular direction.
280
        //! @param lng longitude in radian
281
        //! @param lat latitude in radian
282
        //! @param v the resulting 3D unit vector
283
        inline void spheToRect(const float lng, const float lat, Vec3d& v){
7✔
284
                const double dlng = static_cast<double>(lng), dlat = static_cast<double>(lat), cosLat = cos(dlat);
7✔
285
                v.set(cos(dlng) * cosLat, sin(dlng) * cosLat, sin(dlat));
7✔
286
        }
7✔
287

288
        //! Convert from Rectangular direction to spherical coordinate components.
289
        //! @param lng double* to store longitude in radian [-pi, pi]
290
        //! @param lat double* to store latitude in radian
291
        //! @param v the input 3D vector
292
        inline void rectToSphe(double *lng, double *lat, const Vec3d& v){
93✔
293
                *lat = atan2(v[2], sqrt(v[0]*v[0] + v[1]*v[1]));
93✔
294
                *lng = atan2(v[1],v[0]);
93✔
295
        }
93✔
296

297
        //! Convert from Rectangular direction to spherical coordinate components.
298
        //! @param lng float* to store longitude in radian [-pi, pi]
299
        //! @param lat float* to store latitude in radian
300
        //! @param v the input 3D vector
301
        inline void rectToSphe(float *lng, float *lat, const Vec3d& v){
5✔
302
                *lng = static_cast<float>(atan2(v[1],v[0]));
5✔
303
                *lat = atan2(v[2], sqrt(v[0]*v[0] + v[1]*v[1]));
5✔
304
        }
5✔
305

306

307
        //! Convert from Rectangular direction to spherical coordinate components.
308
        //! @param lng float* to store longitude in radian [-pi, pi]
309
        //! @param lat float* to store latitude in radian
310
        //! @param v the input 3D vector
311
        inline void rectToSphe(float *lng, float *lat, const Vec3f& v){
81✔
312
                *lat = atan2(v[2], sqrt(v[0]*v[0] + v[1]*v[1]));
81✔
313
                *lng = atan2f(v[1],v[0]);
81✔
314
        }
81✔
315

316
        //! Convert from Rectangular direction to spherical coordinate components.
317
        //! @param lng double* to store longitude in radian [-pi, pi]
318
        //! @param lat double* to store latitude in radian
319
        //! @param v the input 3D vector
320
        inline void rectToSphe(double *lng, double *lat, const Vec3f &v){
5✔
321
                *lat = atan2(static_cast<double>(v[2]), sqrt(static_cast<double>(v[0]*v[0] + v[1]*v[1])));
5✔
322
                *lng = atan2(static_cast<double>(v[1]),static_cast<double>(v[0]));
5✔
323
        }
5✔
324

325
        //! Convert from spherical coordinates (including distance) to Rectangular direction.
326
        //! @param lng longitude in radian
327
        //! @param lat latitude in radian
328
        //! @param r length of radius vector (distance)
329
        //! @param v the resulting 3D unit vector
330
        inline void spheToRect(const double lng, const double lat, const double r, Vec3d& v){
7✔
331
                const double cosLat = cos(lat);
7✔
332
                v.set(cos(lng) * cosLat * r, sin(lng) * cosLat * r, sin(lat) * r);
7✔
333
        }
7✔
334

335
        //! Convert from Rectangular direction to spherical coordinate components (including distance).
336
        //! @param lng double* to store longitude in radian [-pi, pi]
337
        //! @param lat double* to store latitude in radian
338
        //! @param r double*   length of radius vector (distance)
339
        //! @param v the input 3D vector
340
        inline void rectToSphe(double *lng, double *lat, double *r, const Vec3d& v){
5✔
341
                *r = v.norm();
5✔
342
                *lat = atan2(v[2], sqrt(v[0]*v[0] + v[1]*v[1]));
5✔
343
                *lng = atan2(v[1],v[0]);
5✔
344
        }
5✔
345

346
        //! Coordinate Transformation from equatorial to ecliptical
347
        inline void equToEcl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad){
5✔
348
                *lambdaRad=std::atan2(std::sin(raRad)*std::cos(eclRad)+std::tan(decRad)*std::sin(eclRad), std::cos(raRad));
5✔
349
                *betaRad=std::asin(std::sin(decRad)*std::cos(eclRad)-std::cos(decRad)*std::sin(eclRad)*std::sin(raRad));
5✔
350
        }
5✔
351

352
        //! Coordinate Transformation from ecliptical to equatorial
353
        inline void eclToEqu(const double lambdaRad, const double betaRad, const double eclRad, double *raRad, double *decRad){
5✔
354
                *raRad = std::atan2(std::sin(lambdaRad)*std::cos(eclRad)-std::tan(betaRad)*std::sin(eclRad), std::cos(lambdaRad));
5✔
355
                *decRad = std::asin(std::sin(betaRad)*std::cos(eclRad)+std::cos(betaRad)*std::sin(eclRad)*std::sin(lambdaRad));
5✔
356
        }
5✔
357

358
        //! Convert a string longitude, latitude, RA or declination angle
359
        //! to radians.
360
        //! @param str the angle in a format according to:
361
        //!   angle ::= [sign¹] ( real [degs | mins | secs]
362
        //!                     | [integer degs] ( [integer mins] real secs
363
        //!                                       | real mins )
364
        //!                     ) [cardinal¹]            
365
        //!   sign ::= + | -
366
        //!   digit := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
367
        //!   integer ::= digit [digits]
368
        //!   real ::= integer [. integer]
369
        //!   degs ::= d | h² | U+00B0 | U+00BA³
370
        //!   mins ::= m | '
371
        //!   secs ::= s | "
372
        //!   cardinal ::= N² | S² | E | W
373
        //!   ¹) A cardinal point overrides any sign. N and E result in a positive,
374
        //!      W and S in a negative angle.
375
        //!   ²) The use of the cardinal points N and S together with the hour sign
376
        //!      'H' or 'h' is forbidden.
377
        //!   ³) The MASCULINE ORDINAL INDICATOR U+00BA is accepted, considering
378
        //!      Spanish QWERTY keyboards.
379
        //! The string is parsed without regarding to case, except that, after a
380
        //! single real, a solitary 's' indicates seconds whereas an 'S' indicates South.
381
        //! It is highly recommended to use lower case for hdms and upper case for NSEW.
382
        //! Latitude: North is positive, South is negative.
383
        //! Longitude: East is positive, West is negative.
384
        //! @return the angle in radians.
385
        double getDecAngle(const QString& str);
386

387
        //! Check if a number is a power of 2.
388
        inline bool isPowerOfTwo(const int value){
10✔
389
                return (value & -value) == value;
10✔
390
        }
391

392
        //! Return the smallest power of two greater than or equal to the given value.
393
        int getBiggerPowerOfTwo(int value);
394

395
        //! Return the largest power of two smaller than or equal to the given value
396
        int getSmallerPowerOfTwo(const int value);
397

398
        //! Return the inverse sinus hyperbolic of z.
399
        inline double asinh(const double z){
400
                return (z>0 ? std::log(z + std::sqrt(z*z+1)) :
401
                             -std::log(-z + std::sqrt(z*z+1)));
402
        }
403

404
        //! Integer modulo where the result is always nonnegative. [0..b-1]
405
        inline int imod(const int a, const int b){
13,839✔
406
                int ret = a % b;
13,839✔
407
                if(ret < 0)
13,839✔
408
                        ret+=b;
269✔
409
                return ret;
13,839✔
410
        }
411
        //! Integer modulo where the result is always positive. [1..b]
412
        inline int amod(const int a, const int b){
580✔
413
                int ret = a % b;
580✔
414
                if(ret <= 0)
580✔
415
                        ret+=b;
126✔
416
                return ret;
580✔
417
        }
418
        //! Integer interval modulo. [a..b)
419
        inline int amod(const int x, const int a, const int b){
×
420
                if (a==b)
×
421
                        return x;
×
422
                int ret = imod(x-a, b-a);
×
423
                return ret+a;
×
424
        }
425
        //! Double modulo where the result is always nonnegative. [0..(b
426
        inline double fmodpos(const double a, const double b){
21,823✔
427
                double ret = fmod(a, b);
21,823✔
428
                if(ret < 0)
21,823✔
429
                        ret+=b;
1,321✔
430
                return ret;
21,823✔
431
        }
432
        //! Float modulo where the result is always nonnegative. [0..(b
433
        inline float fmodpos(const float a, const float b){
6✔
434
                float ret = fmodf(a, b);
6✔
435
                if(ret < 0)
6✔
436
                        ret+=b;
1✔
437
                return ret;
6✔
438
        }
439

440
        //! Floor integer division provides truncating to the next lower integer, also for negative numerators.
441
        //! https://stackoverflow.com/questions/2622441/c-integer-floor-function
442
        //! @returns floor(num/den)
443
        inline int intFloorDiv (int num, int den)
22,311✔
444
        {
445
          if (0 < (num^den)) // lgtm [cpp/bitwise-sign-check]
22,311✔
446
            return num/den;
21,594✔
447
          else
448
            {
449
              ldiv_t res = ldiv(num,den);
717✔
450
              return (res.rem)? res.quot-1
1,382✔
451
                              : res.quot;
717✔
452
            }
453
        }
454

455
        //! version of intFloorDiv() for large integers.
456
        inline int intFloorDivLL(qint64 num, qint64 den)
137✔
457
        {
458
          if (0 < (num^den)) // lgtm [cpp/bitwise-sign-check]
137✔
459
            return int(num/den);
107✔
460
          else
461
            {
462
              lldiv_t res = lldiv(num,den);
30✔
463
              qint64 ret= (res.rem)? res.quot-1
30✔
464
                              : res.quot;
465
              return int(ret);
30✔
466
            }
467
        }
468

469
        ///////////////////////////////////////////////////
470
        // New Qt based General Calendar Functions.
471
        //! Extract from julianDay a year, month, day for the Julian Date julianDay represents.
472
        //! @attention Under rare circumstances with a rounded result where julianDay=*.49999999xyz this will still round off whereas the time is less than a fraction from midnight of the next day.
473
        //! Depending on circumstances this may matter or not. If you need a full decoding of a Julian day number, prefer to use getDateTimeFromJulianDay()
474
        void getDateFromJulianDay(const double julianDay, int *year, int *month, int *day);
475

476
        //! Extract from julianDay an hour, minute, second.
477
        //! @attention Under rare circumstances with a rounded result where julianDay=*.49999999xyz this will lead to a factual result for *.5000000abc, i.e. not 24 but 0 hours, and wrapDay will be true.
478
        //! Depending on circumstances this may matter or not. If you need a full decoding of a Julian day number, prefer to use getDateTimeFromJulianDay()
479
        void getTimeFromJulianDay(const double julianDay, int *hour, int *minute, int *second, int *millis=Q_NULLPTR, bool *wrapDay=Q_NULLPTR);
480

481
        //! Extract from julianDay a year, month, day, hour, minute, second and (optional) millisecond for the Julian Day julianDay represents.
482
        //! This is the preferred method of complete decoding of a Julian day number.
483
        void getDateTimeFromJulianDay(const double julianDay, int *year, int *month, int *day, int *hour, int *minute, int *second, int *millis=Q_NULLPTR);
484

485
        //! Make hours (decimal format) from julianDay
486
        double getHoursFromJulianDay(const double julianDay);
487

488
        //! Parse an ISO8601 date string.
489
        //! Also handles negative and distant years.
490
        bool getDateTimeFromISO8601String(const QString& iso8601Date, int* y, int* m, int* d, int* h, int* min, float* s);
491
        
492
        //! Format the given Julian Day in (UTC) ISO8601 date string.
493
        //! Also handles negative and distant years.
494
        QString julianDayToISO8601String(const double jd, bool addMS = false);
495

496
        //! Return the Julian Date matching the ISO8601 date string.
497
        //! Also handles negative and distant years.
498
        double getJulianDayFromISO8601String(const QString& iso8601Date, bool* ok);
499
        
500
        //! Format the date and day-of-week per the format in fmt
501
        //! (see QDateTime::toString()). Uses the @b system locale, not
502
        //! the one set in Stellarium.
503
        //! @return QString representing the formatted date
504
        QString localeDateString(const int year, const int month, const int day, const int dayOfWeek, const QString &fmt);
505

506
        //! Format the date and day-of-week per the @b system locale's
507
        //! QLocale::ShortFormat.
508
        //! @return QString representing the formatted date
509
        QString localeDateString(const int year, const int month, const int day, const int dayOfWeek);
510

511
        //! Return a day number of week for date
512
        //! @return number of day: 0 - sunday, 1 - monday,..
513
        int getDayOfWeek(int year, int month, int day);
514
        inline int getDayOfWeek(double JD)
6✔
515
        {
516
                double d= fmodpos(JD+1.5, 7);
6✔
517
                return std::lround(floor(d));
6✔
518
        }
519

520
        //! Format the discovery date
521
        //! @return QString representing the formatted date
522
        QString localeDiscoveryDateString(const QString& discovery);
523

524
        //! Get the current Julian Date from system time.
525
        //! @return the current Julian Date
526
        double getJDFromSystem();
527

528
        //! Get the Julian Day Number (JD) from Besselian epoch.
529
        //! @param epoch Besselian epoch, expressed as year with decimal fraction
530
        //! @return Julian Day number (JD) for B<Year>
531
        double getJDFromBesselianEpoch(const double epoch);
532

533
        //! Get the Julian Day Number (JD) from Julian epoch.
534
        //! @param epoch Julian epoch, expressed as year with decimal fraction
535
        //! @return Julian Day number (JD) for J<Year>
536
        double getJDFromJulianEpoch(const double epoch);
537

538
        //! Convert a time of day to the fraction of a Julian Day.
539
        //! Note that a Julian Day starts at 12:00, not 0:00, and
540
        //! so 12:00 == 0.0 and 0:00 == 0.5
541
        double qTimeToJDFraction(const QTime& time);
542

543
        //! Convert a fraction of a Julian Day to a QTime
544
        QTime jdFractionToQTime(const double jd);
545

546
        //! Convert a QT QDateTime class to julian day.
547
        //! @param dateTime the UTC QDateTime to convert
548
        //! @result the matching decimal Julian Day
549
        inline double qDateTimeToJd(const QDateTime& dateTime){
6✔
550
                Q_ASSERT(dateTime.timeSpec()==Qt::UTC);
6✔
551
                return dateTime.date().toJulianDay()+static_cast<double>(1./(24*60*60*1000))*QTime(0, 0, 0, 0).msecsTo(dateTime.time())-0.5;
6✔
552
        }
553

554
        //! Convert a Julian Day number to a QDateTime.
555
        //! @param jd Julian Day number (with fractions) to convert
556
        //! @param timeSpec a @c Qt::TimeSpec constant. Meaningful in this context seem only Qt::UTC (preferred) and Qt::LocalTime (useful in some GUI contexts).
557
        //! @note From 2008 to 2022-05 this converted to local time zone, not to UTC as specified and intended.
558
        //!        The old behaviour is kept with @p timeSpec set to Qt::LocalTime.
559
        //! If you use Qt::LocalTime, you should add StelCore::getUTCOffset(jd)/24 to the current JD before calling this to have @p jd as a "local time zone corrected JD" before conversion.
560
        //! @result the matching QDateTime
561
        //! @note QDate has no year zero. This and other idiosyncrasies of QDateTime may limit the applicability of program parts which use this method to positive years or may cause other issues.
562
        QDateTime jdToQDateTime(const double& jd, const Qt::TimeSpec timeSpec);
563

564
        //! Compute Julian day number from calendar date.
565
        //! Uses QDate functionality if possible, but also works for negative JD.
566
        //! Dates before 1582-10-15 are in the Julian Calendar.
567
        //! @param newjd pointer to JD
568
        //! @param y Calendar year.
569
        //! @param m month, 1=January ... 12=December
570
        //! @param d day
571
        //! @param h hour
572
        //! @param min minute
573
        //! @param s second
574
        //! @result true in all conceivable cases.
575
        bool getJDFromDate(double* newjd, const int y, const int m, const int d, const int h, const int min, const float s);
576

577
        int numberOfDaysInMonthInYear(const int month, const int year);
578
        //! @result true if year is a leap year. Observes 1582 switch from Julian to Gregorian Calendar.
579
        bool isLeapYear(const int year);
580
        //! Find day number for date in year.
581
        //! Meeus, Astronomical Algorithms 2nd ed., 1998, ch.7, p.65
582
        int dayInYear(const int year, const int month, const int day);
583
        //! Find date from day number within year and the year.
584
        //! Meeus, AA 2nd, 1998, ch.7 p.66
585
        //! @returns Vec3i(year, month, day)
586
        Vec3i dateFromDayYear(const int day, const int year);
587
        //! Return a fractional year like YYYY.ddddd. For negative years, the year number is decreased. E.g. -500.5 occurs in -501.
588
        double yearFraction(const int year, const int month, const double day);
589

590
        bool changeDateTimeForRollover(int oy, int om, int od, int oh, int omin, int os,
591
                                       int* ry, int* rm, int* rd, int* rh, int* rmin, int* rs);
592

593
        //! Output a QVariantMap to qDebug().  Formats like a tree where there are nested objects.
594
        void debugQVariantMap(const QVariant& m, const QString& indent="", const QString& key="");
595

596

597
        /// Compute acos(x)
598
        //! The taylor serie is not accurate around x=1 and x=-1
599
        inline float fastAcos(const float x)
7✔
600
        {
601
                return static_cast<float>(M_PI_2) - (x + x*x*x * (1.f/6.f + x*x * (3.f/40.f + 5.f/112.f * x*x)) );
7✔
602
        }
603

604
        //! Compute exp(x) for small exponents x
605
        inline float fastExp(const float x)
9✔
606
        {
607
                return (x>=0)?
9✔
608
                        (1.f + x*(1.f+ x/2.f*(1.f+ x/3.f*(1.f+x/4.f*(1.f+x/5.f))))):
5✔
609
                                1.f / (1.f -x*(1.f -x/2.f*(1.f- x/3.f*(1.f-x/4.f*(1.f-x/5.f)))));
9✔
610
        }
611

612
        // Calculate and return sidereal period in days from semi-major axis (in AU)
613
        //double calculateSiderealPeriod(const double SemiMajorAxis);  MOVED TO Orbit.h
614

615
        //! Convert decimal hours to hours, minutes, seconds
616
        //! Format for:
617
        //! @p colonFormat        |      false     |   true
618
        //! ----------------------|----------------|----------
619
        //! @p minutesOnly=false  |  "HhMMmSS.Ss"  | "HHhMMm"
620
        //! @p minutesOnly=true   |  "H:MM:SS.S"   | "HH:MM"
621
        QString hoursToHmsStr(const double hours, const bool minutesOnly = false, const bool colonFormat=false);
622
        QString hoursToHmsStr(const float hours, const bool minutesOnly = false, const bool colonFormat=false);
623

624
        //! Convert JD to hours and minutes
625
        QString getHoursMinutesFromJulianDay(const double julianDay);
626

627
        //! Convert a hms formatted string to decimal hours
628
        double hmsStrToHours(const QString& s);
629

630
        //! Convert days (float) to a time string
631
        QString daysFloatToDHMS(float days);
632

633
        //! The method to splitting the text by substrings by some limit of string length
634
        QString wrapText(const QString& s, const int limit = 52);
635

636
        //! Get Delta-T estimation for a given date.
637
        //! This is just an "empty" correction function, returning 0.
638
        double getDeltaTwithoutCorrection(const double jDay);
639

640
        //! Get Delta-T estimation for a given date.
641
        //! Note that this method is recommended for the year range:
642
        //! -1999 to +3000. It gives details for -500...+2150.
643
        //! Implementation of algorithm by Espenak & Meeus (2006) for DeltaT computation
644
        //! @param jDay the date and time expressed as a Julian day
645
        //! @return Delta-T in seconds
646
        double getDeltaTByEspenakMeeus(const double jDay);
647

648
        //! Get Delta-T estimation for a given date.
649
        //! Note that this method is recommended for the year range:
650
        //! -1999 to +3000. It gives details for -500...+2150.
651
        //! Implementation of algorithm by Espenak & Meeus (2006) with modified formulae for DeltaT computation
652
        //! @param jDay the date and time expressed as a Julian day
653
        //! @return Delta-T in seconds
654
        double getDeltaTByEspenakMeeusModified(const double jDay);
655

656
        //! Get Delta-T estimation for a given date.
657
        //! Implementation of algorithm by Schoch (1931) for DeltaT computation,
658
        //! outdated but may be useful for science-historical purposes.
659
        //! Source: Schoch, C. (1931). Die sekulare Accelaration des Mondes und der Sonne.
660
        //! Astronomische Abhandlungen, Ergnzungshefte zu den Astronomischen Nachrichten,
661
        //! Band 8, B2. Kiel.
662
        //! @param jDay the date and time expressed as a Julian day
663
        //! @return Delta-T in seconds
664
        double getDeltaTBySchoch(const double jDay);
665

666
        //! Get Delta-T estimation for a given date.
667
        //! Implementation of algorithm by Clemence (1948) for DeltaT computation,
668
        //! outdated but may be useful for science-historical purposes.
669
        //! Source: On the system of astronomical constants.
670
        //! Clemence, G. M.
671
        //! Astronomical Journal, Vol. 53, p. 169
672
        //! 1948AJ.....53..169C [http://adsabs.harvard.edu/abs/1948AJ.....53..169C]
673
        //! @param jDay the date and time expressed as a Julian day
674
        //! @return Delta-T in seconds
675
        double getDeltaTByClemence(const double jDay);
676

677
        //! Get Delta-T estimation for a given date.
678
        //! Implementation of algorithm by IAU (1952) for DeltaT computation,
679
        //! outdated but may be useful for science-historical purposes.
680
        //! Source: Spencer Jones, H., "The Rotation of the Earth, and the Secular Accelerations of the Sun, Moon and Planets",
681
        //! Monthly Notices of the Royal Astronomical Society, 99 (1939), 541-558
682
        //! http://adsabs.harvard.edu/abs/1939MNRAS..99..541S
683
        //! @param jDay the date and time expressed as a Julian day
684
        //! @return Delta-T in seconds
685
        double getDeltaTByIAU(const double jDay);
686

687
        //! Get Delta-T estimation for a given date.
688
        //! Implementation of algorithm by Astronomical Ephemeris (1960) for DeltaT computation.
689
        //! Sources: Spencer Jones, H., "The Rotation of the Earth, and the Secular Accelerations of the Sun, Moon and Planets",
690
        //! Monthly Notices of the Royal Astronomical Society, 99 (1939), 541-558
691
        //! http://adsabs.harvard.edu/abs/1939MNRAS..99..541S
692
        //! or Explanatory Supplement to the Astr. Ephemeris, 1961, p.87.
693
        //! Also used by Mucke&Meeus, Canon of Solar Eclipses, Vienna 1983.
694
        //! @param jDay the date and time expressed as a Julian day
695
        //! @return Delta-T in seconds
696
        double getDeltaTByAstronomicalEphemeris(const double jDay);
697

698
        //! Get Delta-T estimation for a given date.
699
        //! Implementation of algorithm by Tuckerman (1962, 1964) & Goldstine (1973) for DeltaT computation
700
        //! @param jDay the date and time expressed as a Julian day
701
        //! @return Delta-T in seconds
702
        double getDeltaTByTuckermanGoldstine(const double jDay);
703

704
        //! Get Delta-T estimation for a given date.
705
        //! Implementation of algorithm by Muller & Stephenson (1975) for DeltaT computation.
706
        //! Source: The accelerations of the earth and moon from early astronomical observations
707
        //! Muller, P. M.; Stephenson, F. R.
708
        //! Growth rhythms and the history of the earth's rotation; Proceedings of the Interdisciplinary
709
        //! Winter Conference on Biological Clocks and Changes in the Earth's Rotation: Geophysical and
710
        //! Astronomical Consequences, Newcastle-upon-Tyne, England, January 8-10, 1974. (A76-18126 06-46)
711
        //! London, Wiley-Interscience, 1975, p. 459-533; Discussion, p. 534.
712
        //! 1975grhe.conf..459M [http://adsabs.harvard.edu/abs/1975grhe.conf..459M]
713
        //! @param jDay the date and time expressed as a Julian day
714
        //! @return Delta-T in seconds
715
        double getDeltaTByMullerStephenson(const double jDay);
716

717
        //! Get Delta-T estimation for a given date.
718
        //! Implementation of algorithm by Stephenson (1978) for DeltaT computation.
719
        //! Source: Pre-Telescopic Astronomical Observations
720
        //! Stephenson, F. R.
721
        //! Tidal Friction and the Earth's Rotation, Proceedings of a Workshop, held in Bielefeld,
722
        //! September 26-30, 1977, Edited by P. Brosche, and J. Sundermann. Berlin: Springer-Verlag, 1978, p.5
723
        //! 1978tfer.conf....5S [http://adsabs.harvard.edu/abs/1978tfer.conf....5S]
724
        //! @param jDay the date and time expressed as a Julian day
725
        //! @return Delta-T in seconds
726
        double getDeltaTByStephenson1978(const double jDay);
727

728
        //! Get Delta-T estimation for a given date.
729
        //! Implementation of algorithm by Stephenson (1997) for DeltaT computation.
730
        //! Source: Book "Historical Eclipses and Earth's Rotation" by F. R. Stephenson (1997)
731
        //! http://ebooks.cambridge.org/ebook.jsf?bid=CBO9780511525186
732
        //! @param jDay the date and time expressed as a Julian day
733
        //! @return Delta-T in seconds
734
        double getDeltaTByStephenson1997(const double jDay);
735

736
        //! Get Delta-T estimation for a given date.
737
        //! Implementation of algorithm by Schmadel & Zech (1979) for DeltaT computation.
738
        //! Outdated, but may be useful for science-historical purposes.
739
        //! Source: Polynomial approximations for the correction delta T E.T.-U.T. in the period 1800-1975
740
        //! Schmadel, L. D.; Zech, G.
741
        //! Acta Astronomica, vol. 29, no. 1, 1979, p. 101-104.
742
        //! 1979AcA....29..101S [http://adsabs.harvard.edu/abs/1979AcA....29..101S]
743
        //! @param jDay the date and time expressed as a Julian day
744
        //! @return Delta-T in seconds
745
        //! @note The polynome is strictly applicable 1800...1975 only! Delivers values for the nearer edge (1800/1989) if jDay is outside.
746
        double getDeltaTBySchmadelZech1979(const double jDay);
747

748
        //! Get Delta-T estimation for a given date.
749
        //! Implementation of algorithm by Morrison & Stephenson (1982) for DeltaT computation
750
        //! @param jDay the date and time expressed as a Julian day
751
        //! @return Delta-T in seconds
752
        double getDeltaTByMorrisonStephenson1982(const double jDay);
753

754
        //! Get Delta-T estimation for a given date.
755
        //! Implementation of algorithm by Stephenson & Morrison (1984) for DeltaT computation
756
        //! Source: Long-term changes in the rotation of the earth - 700 B.C. to A.D. 1980.
757
        //! Stephenson, F. R.; Morrison, L. V.
758
        //! Philosophical Transactions, Series A (ISSN 0080-4614), vol. 313, no. 1524, Nov. 27, 1984, p. 47-70.
759
        //! 1984RSPTA.313...47S [http://adsabs.harvard.edu/abs/1984RSPTA.313...47S]
760
        //! @param jDay the date and time expressed as a Julian day
761
        //! @return Delta-T in seconds or Zero if date outside years -391..1600
762
        double getDeltaTByStephensonMorrison1984(const double jDay);
763

764
        //! Get Delta-T estimation for a given date.
765
        //! Implementation of algorithm by Stephenson & Morrison (1995) for DeltaT computation
766
        //! Source: Long-Term Fluctuations in the Earth's Rotation: 700 BC to AD 1990.
767
        //! Stephenson, F. R.; Morrison, L. V.
768
        //! Philosophical Transactions: Physical Sciences and Engineering, Volume 351, Issue 1695, pp. 165-202
769
        //! 1995RSPTA.351..165S [http://adsabs.harvard.edu/abs/1995RSPTA.351..165S]
770
        //! @param jDay the date and time expressed as a Julian day
771
        //! @return Delta-T in seconds
772
        double getDeltaTByStephensonMorrison1995(const double jDay);
773

774
        //! Get Delta-T estimation for a given date.
775
        //! Implementation of algorithm by Stephenson & Houlden (1986) for DeltaT computation
776
        //! Source: STEPHENSON F.R and HOULDEN M.A. - Atlas of Historical Eclipse Maps - Cambridge Univ.Press. (1986)
777
        //! [https://assets.cambridge.org/97805212/67236/frontmatter/9780521267236_frontmatter.pdf]
778
        //! @param jDay the date and time expressed as a Julian day
779
        //! @return Delta-T in seconds or 0 if year > 1600
780
        double getDeltaTByStephensonHoulden(const double jDay);
781

782
        //! Get Delta-T estimation for a given date.
783
        //! Implementation of algorithm by Espenak (1987, 1989) for DeltaT computation.
784
        //! This relation should not be used before around 1950 or after around 2100 (Espenak, pers. comm.).
785
        //! @param jDay the date and time expressed as a Julian day
786
        //! @return Delta-T in seconds
787
        double getDeltaTByEspenak(const double jDay);
788

789
        //! Get Delta-T estimation for a given date.
790
        //! Implementation of algorithm by Borkowski (1988) for DeltaT computation.
791
        //! Source: ELP 2000-85 and the dynamic time-universal time relation
792
        //! Borkowski, K. M.
793
        //! Astronomy and Astrophysics (ISSN 0004-6361), vol. 205, no. 1-2, Oct. 1988, p. L8-L10.
794
        //! 1988A&A...205L...8B [http://adsabs.harvard.edu/abs/1988A&A...205L...8B]
795
        //! @param jDay the date and time expressed as a Julian day
796
        //! @return Delta-T in seconds
797
        double getDeltaTByBorkowski(const double jDay);
798

799
        //! Get Delta-T estimation for a given date.
800
        //! Implementation of algorithm by Schmadel & Zech (1988) for DeltaT computation.
801
        //! Source: Empirical Transformations from U.T. to E.T. for the Period 1800-1988
802
        //! Schmadel, L. D.; Zech, G.
803
        //! Astronomische Nachrichten 309, 219-221
804
        //! 1988AN....309..219S [http://adsabs.harvard.edu/abs/1988AN....309..219S]
805
        //! @param jDay the date and time expressed as a Julian day
806
        //! @return Delta-T in seconds
807
        //! @note The polynome is strictly applicable 1800...1988 only! Delivers values for the nearer edge (1800/1989) if jDay is outside.
808
        double getDeltaTBySchmadelZech1988(const double jDay);
809

810
        //! Get Delta-T estimation for a given date.
811
        //! Implementation of algorithm by Chapront-Touzé & Chapront (1991) for DeltaT computation
812
        //! @param jDay the date and time expressed as a Julian day
813
        //! @return Delta-T in seconds or 0 if year not in -391..1600
814
        double getDeltaTByChaprontTouze(const double jDay);        
815

816
        //! Get Delta-T estimation for a given date.
817
        //! Implementation of the "historical" part of the algorithm by JPL Horizons for DeltaT computation.
818
        //! @param jDay the date and time expressed as a Julian day
819
        //! @return Delta-T in seconds or 0 if year not in -2999..1620 (!)
820
        double getDeltaTByJPLHorizons(const double jDay);
821

822
        //! Get Delta-T estimation for a given date.
823
        //! Implementation of algorithm by Morrison & Stephenson (2004, 2005) for DeltaT computation.
824
        //! Sources: Historical values of the Earth's clock error ΔT and the calculation of eclipses
825
        //! Morrison, L. V.; Stephenson, F. R.
826
        //! Journal for the History of Astronomy (ISSN 0021-8286), Vol. 35, Part 3, No. 120, p. 327 - 336 (2004)
827
        //! 2004JHA....35..327M [http://adsabs.harvard.edu/abs/2004JHA....35..327M]
828
        //! Addendum: Historical values of the Earth's clock error
829
        //! Morrison, L. V.; Stephenson, F. R.
830
        //! Journal for the History of Astronomy (ISSN 0021-8286), Vol. 36, Part 3, No. 124, p. 339 (2005)
831
        //! 2005JHA....36..339M [http://adsabs.harvard.edu/abs/2005JHA....36..339M]
832
        //! @param jDay the date and time expressed as a Julian day
833
        //! @return Delta-T in seconds
834
        double getDeltaTByMorrisonStephenson2004(const double jDay);
835

836
        //! Get Delta-T estimation for a given date.
837
        //! Implementation of algorithm by Reijs (2006) for DeltaT computation
838
        //! Details: http://www.iol.ie/~geniet/eng/DeltaTeval.htm
839
        //! @param jDay the date and time expressed as a Julian day
840
        //! @return Delta-T in seconds
841
        double getDeltaTByReijs(const double jDay);
842

843
        //! Get Delta-T estimation for a given date.
844
        //! Implementation of algorithm by Chapront, Chapront-Touze & Francou (1997) & Meeus (1998) for DeltaT computation
845
        //! @param jDay the date and time expressed as a Julian day
846
        //! @return Delta-T in seconds
847
        double getDeltaTByChaprontMeeus(const double jDay);
848

849
        //! Get Delta-T estimation for a given date.
850
        //! Implementation of algorithm by Meeus & Simons (2000) for DeltaT computation.
851
        //! Source: Polynomial approximations to Delta T, 1620-2000 AD
852
        //! Meeus, J.; Simons, L.
853
        //! Journal of the British Astronomical Association, vol.110, no.6, 323
854
        //! 2000JBAA..110..323M [http://adsabs.harvard.edu/abs/2000JBAA..110..323M]
855
        //! @param jDay the date and time expressed as a Julian day
856
        //! @return Delta-T in seconds or 0 if year not in 1620..2000
857
        double getDeltaTByMeeusSimons(const double jDay);
858

859
        //! Get Delta-T estimation for a given date.
860
        //! Implementation of algorithm by Montenbruck & Pfleger (2000) for DeltaT computation,
861
        //! a data fit through the table of values found in Meeus, Astronomical algorithms (1991).
862
        //! Book "Astronomy on the Personal Computer" by O. Montenbruck & T. Pfleger (4th ed., 2000), p.181-182
863
        //! @param jDay the date and time expressed as a Julian day
864
        //! @return Delta-T in seconds or 0 if not 1825<=year<2005
865
        double getDeltaTByMontenbruckPfleger(const double jDay);
866

867
        //! Get Delta-T estimation for a given date.
868
        //! Implementation of algorithm by Reingold & Dershowitz (1997, 2001, 2002, 2007, 2018) for DeltaT computation.
869
        //! This is again mostly a data fit based on the table in Meeus, Astronomical Algorithms (1991).
870
        //! This is the version given in the 4th edition ("the ultimate edition"; 2018) which added the fit
871
        //! for -500..1699 and 2006..2150 omitted from previous editions.
872
        //! Calendrical Calculations: The Ultimate Edition / Edward M. Reingold, Nachum Dershowitz - 4th Edition,
873
        //! Cambridge University Press, 2018. - 660p. ISBN: 9781107057623, DOI: 10.1017/9781107415058
874
        //! @param jDay the date and time expressed as a Julian day
875
        //! @return Delta-T in seconds
876
        double getDeltaTByReingoldDershowitz(const double jDay);
877

878
        //! Get Delta-T estimation for a given date.
879
        //! Implementation of algorithm by Banjevic (2006) for DeltaT computation.
880
        //! Source: Ancient eclipses and dating the fall of Babylon
881
        //! Banjevic, B.
882
        //! Publications of the Astronomical Observatory of Belgrade, Vol. 80, p. 251-257 (2006)
883
        //! 2006POBeo..80..251B [http://adsabs.harvard.edu/abs/2006POBeo..80..251B]
884
        //! @param jDay the date and time expressed as a Julian day
885
        //! @return Delta-T in seconds
886
        double getDeltaTByBanjevic(const double jDay);
887

888
        //! Get Delta-T estimation for a given date.
889
        //! Implementation of algorithm by Islam, Sadiq & Qureshi (2008 + revisited 2013) for DeltaT computation.
890
        //! Source: Error Minimization of Polynomial Approximation of DeltaT
891
        //! Islam, S. & Sadiq, M. & Qureshi, M. S.
892
        //! Journal of Astrophysics & Astronomy, Vol. 29, p. 363-366 (2008)
893
        //! http://www.ias.ac.in/jaa/dec2008/JAA610.pdf
894
        //! Note: These polynomials are based on the uncorrected deltaT table from the Astronomical Almanac, thus
895
        //! ndot = -26.0 arcsec/cy^2. Meeus & Simons (2000) corrected the deltaT table for years before 1955.5 using
896
        //! ndot = -25.7376 arcsec/cy^2. Therefore the accuracies stated by Meeus & Simons are correct and cannot be
897
        //! compared with accuracies from Islam & Sadiq & Qureshi.
898
        //! @param jDay the date and time expressed as a Julian day
899
        //! @return Delta-T in seconds
900
        double getDeltaTByIslamSadiqQureshi(const double jDay);
901

902
        //! Get Delta-T estimation for a given date.
903
        //! Implementation of polynomial approximation of time period 1620-2013 for DeltaT by M. Khalid, Mariam Sultana and Faheem Zaidi (2014).
904
        //! Source: Delta T: Polynomial Approximation of Time Period 1620-2013
905
        //! Journal of Astrophysics, Vol. 2014, Article ID 480964
906
        //! https://doi.org/10.1155/2014/480964
907
        //! @param jDay the date and time expressed as a Julian day
908
        //! @return Delta-T in seconds
909
        double getDeltaTByKhalidSultanaZaidi(const double jDay);
910

911
        //! Get Delta-T estimation for a given date.
912
        //! Implementation of a spline approximation for time period -720-2019.0 for DeltaT by Stephenson, Morrison and Hohenkerk (2016).
913
        //! Source: Measurement of the Earth's rotation: 720 BC to AD 2015, published in 2016 in the Royal Society's
914
        //! Proceedings A 472, and made freely available via Open Access, by Stephenson, F.R., Morrison, L.V. and
915
        //! Hohenkerk, C.Y..
916
        //! https://doi.org/10.1098/rspa.2016.0404
917
        //! Addendum 2020 to "Measurement of the Earth's Rotation: 720 BC to AD 2015", published in 2021 February
918
        //! in the Royal Society's Proceedings A 478, by Morrison, L. V., Stephenson, F.R., Hohenkerk, C.Y. and
919
        //! M. Zawilski, M..
920
        //! https://doi.org/10.1098/rspa.2020.0776
921
        //! @param jDay the date and time expressed as a Julian day
922
        //! @return Delta-T in seconds. For times outside the limits, return result from the fitting parabola.
923
        double getDeltaTByStephensonMorrisonHohenkerk2016(const double jDay);
924

925
        //! Get Secular Acceleration estimation for a given year.
926
        //! Method described is here: http://eclipse.gsfc.nasa.gov/SEcat5/secular.html
927
        //! For adapting from -26 to -25.858, use -0.91072 * (-25.858 + 26.0) = -0.12932224
928
        //! For adapting from -26 to -23.895, use -0.91072 * (-23.895 + 26.0) = -1.9170656
929
        //! @param jDay the JD
930
        //! @param ndot value of n-dot (secular acceleration of the Moon) which should be used in the lunar ephemeris instead of the default values.
931
        //! @param useDE4xx true if function should adapt calculation of the secular acceleration of the Moon to the DE43x/DE44x ephemerides
932
        //! @return SecularAcceleration in seconds
933
        //! @note n-dot for secular acceleration of the Moon in ELP2000-82B is -23.8946 "/cy/cy and for DE43x/DE44x is -25.8 "/cy/cy
934
        double getMoonSecularAcceleration(const double jDay, const double ndot, const bool useDE4xx);
935

936
        //! Get the standard error (sigma) for the value of DeltaT
937
        //! @param jDay the JD
938
        //! @return sigma in seconds
939
        double getDeltaTStandardError(const double jDay);
940

941
        //! Get value of the Moon fluctuation
942
        //! Source: The Rotation of the Earth, and the Secular Accelerations of the Sun, Moon and Planets
943
        //! Spencer Jones, H.
944
        //! Monthly Notices of the Royal Astronomical Society, 99 (1939), 541-558
945
        //! 1939MNRAS..99..541S [http://adsabs.harvard.edu/abs/1939MNRAS..99..541S]
946
        //! @param jDay the JD
947
        //! @return fluctuation in seconds
948
        double getMoonFluctuation(const double jDay);
949

950
        //! Sign function from http://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c
951
        template <typename T> int sign(T val)
63,010✔
952
        {
953
                return (T(0) < val) - (val < T(0));
63,010✔
954
        }
955
        
956
        //! Compute cosines and sines around a circle which is split in "slices" parts.
957
        //! Values are stored in the global static array cos_sin_theta.
958
        //! Used for the sin/cos values along a latitude circle, equator, etc. for a spherical mesh.
959
        //! @param slices number of partitions (elsewhere called "segments") for the circle
960
        float *ComputeCosSinTheta(const unsigned int slices);
961
        
962
        //! Compute cosines and sines around a half-circle which is split in "segments" parts.
963
        //! Values are stored in the global static array cos_sin_rho.
964
        //! Used for the sin/cos values along a meridian for a spherical mesh.
965
        //! @param segments number of partitions (elsewhere called "stacks") for the half-circle
966
        float *ComputeCosSinRho(const unsigned int segments);
967
        
968
        //! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.
969
        //! Values are stored in the global static array cos_sin_rho.
970
        //! Used for the sin/cos values along a meridian.
971
        //! This allows leaving away pole caps. The array now contains values for the region minAngle+segments*phi
972
        //! @param dRho a difference angle between the stops
973
        //! @param segments number of segments
974
        //! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi
975
        float* ComputeCosSinRhoZone(const float dRho, const unsigned int segments, const float minAngle);
976

977
        //! Calculate fixed days (R.D.) from Gregorian date (proleptic Gregorian calendar)
978
        //! @param year
979
        //! @param month
980
        //! @param day
981
        //! @return days from Rata Die
982
        int getFixedFromGregorian(const int year, const int month, const int day);
983

984
        //! Comparison two string versions and return a result in range -1,0,1
985
        //! @param v1 string for version 1
986
        //! @param v2 string for version 2
987
        //! @return result (-1: v1<v2; 0: v1==v2; 1: v1>v2)
988
        int compareVersions(const QString v1, const QString v2);
989

990
        //! Uncompress gzip or zlib compressed data.
991
        QByteArray uncompress(const QByteArray& data);
992

993
        //! Uncompress (gzip/zlib) data from this QIODevice, which must be open and readable.
994
        //! @param device The device to read from, must already be opened with an OpenMode supporting reading
995
        //! @param maxBytes The max. amount of bytes to read from the device, or -1 to read until EOF.  Note that it
996
        //! always stops when inflate() returns Z_STREAM_END. Positive values can be used for interleaving compressed data
997
        //! with other data.
998
        QByteArray uncompress(QIODevice &device, qint64 maxBytes=-1);
999

1000
        //! Greatest Common Divisor (Euclid's algorithm)
1001
        //! @param a first number
1002
        //! @param b second number
1003
        //! @return Greatest Common Divisor
1004
        int gcd(int a, int b);
1005

1006
        //! Least Common Multiple
1007
        //! @param a first number
1008
        //! @param b second number
1009
        //! @return Least Common Multiple
1010
        int lcm(int a, int b);
1011

1012
        //! Given regularly spaced steps x1, x2, x3 and curve values y1, y2, y3,
1013
        //! calculate an intermediate value of the 3 arguments for the given interpolation point n.
1014
        //! @param n Interpolation factor: steps from x2
1015
        //! @param y1 Argument 1
1016
        //! @param y2 Argument 2
1017
        //! @param y3 Argument 3
1018
        //! @return interpolation value
1019
        template<class T> T interpolate3(T n, T y1, T y2, T y3)
3✔
1020
        {
1021
                // See "Astronomical Algorithms" by J. Meeus
1022

1023
                // Equation 3.2
1024
                T a = y2-y1;
3✔
1025
                T b = y3-y2;
3✔
1026
                T c = b-a;
3✔
1027

1028
                // Equation 3.3
1029
                return y2 + n * 0.5f * (a + b + n * c);
3✔
1030
        }
1031

1032
        //! Given regularly spaced steps x1, x2, x3, x4, x5 and curve values y1, y2, y3, y4, y5,
1033
        //! calculate an intermediate value of the 5 arguments for the given interpolation point n.
1034
        //! @param n Interpolation factor: steps from x3
1035
        //! @param y1 Argument 1
1036
        //! @param y2 Argument 2
1037
        //! @param y3 Argument 3
1038
        //! @param y4 Argument 4
1039
        //! @param y5 Argument 5
1040
        //! @return interpolation value
1041
        template<class T> T interpolate5(T n, T y1, T y2, T y3, T y4, T y5)
1✔
1042
        {
1043
                // See "Astronomical Algorithms" by J. Meeus
1044
                // Eq. 3.8
1045
                T A=y2-y1; T B=y3-y2; T C=y4-y3; T D=y5-y4;
1✔
1046
                T E=B-A; T F=C-B; T G=D-C;
1✔
1047
                T H=F-E; T J=G-F;
1✔
1048
                T K=J-H;
1✔
1049

1050
                return (((K*(1.0/24.0)*n + (H+J)/12.0)*n  + (F*0.5-K/24.0))*n + ((B+C)*0.5 - (H+J)/12.0))*n +y3;
1✔
1051
        }
1052

1053
        //! Interval test. This checks whether @p value is within [@p low, @p high]
1054
        template <typename T> bool isWithin(const T& value, const T& low, const T& high)
8✔
1055
        {
1056
                return !(value < low) && !(high < value);
8✔
1057
        }
1058

1059
        template <class Arg1, class Arg2, class Result>
1060
        struct binary_function
1061
        {
1062
                typedef Arg1 first_argument_type;
1063
                typedef Arg2 second_argument_type;
1064
                typedef Result result_type;
1065
        };
1066

1067

1068
#ifdef _MSC_BUILD
1069
        inline double trunc(double x)
1070
        {
1071
                return (x < 0 ? std::ceil(x) : std::floor(x));
1072
        }
1073
        inline float trunc(float x)
1074
        {
1075
                return (x < 0 ? std::ceil(x) : std::floor(x));
1076
        }
1077
#else
1078
        inline double trunc(double x) { return ::trunc(x); }
6✔
1079
        inline float trunc(float x) { return ::trunc(x); }
6✔
1080
#endif
1081
}
1082

1083
#endif // STELUTILS_HPP
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc