1 /*
2     SPDX-FileCopyrightText: 2021 Hy Murveit <hy@murveit.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "greatcircle.h"
8 
9 #include "kstars_debug.h"
10 #include "Options.h"
11 #include "skymap.h"
12 #include "skyqpainter.h"
13 #include "projections/projector.h"
14 #include "skypoint.h"
15 #include "kstars.h"
16 
17 #include <QStatusBar>
18 
19 namespace
20 {
21 
d2r(double degrees)22 double d2r(double degrees)
23 {
24     return degrees * 2.0 * M_PI / 360.0;
25 }
26 
r2d(double radians)27 double r2d(double radians)
28 {
29     return (radians * 360.0 / (2 * M_PI));
30 }
31 
32 }  // namespace
33 
34 // This implements the equations in:
35 // https://en.wikipedia.org/wiki/Great-circle_navigation
36 
GreatCircle(double az1,double alt1,double az2,double alt2)37 GreatCircle::GreatCircle(double az1, double alt1, double az2, double alt2) {
38     // convert inputs to radians.
39     az1 = d2r(az1);
40     az2 = d2r(az2);
41     alt1 = d2r(alt1);
42     alt2 = d2r(alt2);
43 
44     const double daz = az2 - az1;
45     const double alpha1 = atan2(
46                 (cos(alt2) * sin(daz)),
47                 (cos(alt1) * sin(alt2) - (sin(alt1) * cos(alt2) * cos(daz))));
48 
49     const double term1 = cos(alt1) * sin(alt2) - (sin(alt1) * cos(alt2) * cos(daz));
50     const double term2 = cos(alt2) * sin(daz);
51     const double sigma12 = atan2(
52                 sqrt(  term1 * term1 + term2 * term2),
53                 (sin(alt1) * sin(alt2) + (cos(alt1) * cos(alt2) * cos(daz))));
54 
55     const double term3 = cos(alpha1);
56     const double term4 = sin(alpha1);
57     const double term5 = sin(alt1);
58     const double alpha0 = atan2(
59                 (sin(alpha1) * cos(alt1)),
60                 sqrt(term3 * term3 + term4 * term4 * term5 * term5));
61 
62     if ((alt1 == 0) && (alpha1 == 0.5 * M_PI))
63         sigma01 = 0;
64     else
65         sigma01 = atan2(tan(alt1), cos(alpha1));
66 
67     sigma02 = sigma01 + sigma12;
68 
69     const double lambda01 = atan2(sin(alpha0) * sin(sigma01), cos(sigma01));
70 
71     lambda0 = az1 - lambda01;
72 
73     cosAlpha0 = cos(alpha0);
74     sinAlpha0 = sin(alpha0);
75 }
76 
waypoint(double fraction,double * az,double * alt)77 void GreatCircle::waypoint(double fraction, double *az, double *alt)
78 {
79     double sigma = (1-fraction) * sigma01 + fraction * sigma02;
80     double cosSigma = cos(sigma);
81     double sinSigma = sin(sigma);
82 
83     *alt = r2d(atan2(
84                    (cosAlpha0 * sinSigma),
85                    (sqrt(cosSigma * cosSigma + sinAlpha0 * sinAlpha0 * sinSigma * sinSigma))));
86 
87     double LL0 = atan2((sinAlpha0 * sinSigma), cosSigma);
88 
89     *az = r2d(LL0 + lambda0);
90 }
91