File indexing completed on 2024-04-14 03:43:19

0001 /*
0002     SPDX-FileCopyrightText: 2021 Hy Murveit <hy@murveit.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "greatcircle.h"
0008 
0009 #include "kstars_debug.h"
0010 #include "Options.h"
0011 #include "skymap.h"
0012 #include "skyqpainter.h"
0013 #include "projections/projector.h"
0014 #include "skypoint.h"
0015 #include "kstars.h"
0016 
0017 #include <QStatusBar>
0018 
0019 namespace
0020 {
0021 
0022 double d2r(double degrees)
0023 {
0024     return degrees * 2.0 * M_PI / 360.0;
0025 }
0026 
0027 double r2d(double radians)
0028 {
0029     return (radians * 360.0 / (2 * M_PI));
0030 }
0031 
0032 }  // namespace
0033 
0034 // This implements the equations in:
0035 // https://en.wikipedia.org/wiki/Great-circle_navigation
0036 
0037 GreatCircle::GreatCircle(double az1, double alt1, double az2, double alt2) {
0038     // convert inputs to radians.
0039     az1 = d2r(az1);
0040     az2 = d2r(az2);
0041     alt1 = d2r(alt1);
0042     alt2 = d2r(alt2);
0043 
0044     const double daz = az2 - az1;
0045     const double alpha1 = atan2(
0046                 (cos(alt2) * sin(daz)),
0047                 (cos(alt1) * sin(alt2) - (sin(alt1) * cos(alt2) * cos(daz))));
0048 
0049     const double term1 = cos(alt1) * sin(alt2) - (sin(alt1) * cos(alt2) * cos(daz));
0050     const double term2 = cos(alt2) * sin(daz);
0051     const double sigma12 = atan2(
0052                 sqrt(  term1 * term1 + term2 * term2),
0053                 (sin(alt1) * sin(alt2) + (cos(alt1) * cos(alt2) * cos(daz))));
0054 
0055     const double term3 = cos(alpha1);
0056     const double term4 = sin(alpha1);
0057     const double term5 = sin(alt1);
0058     const double alpha0 = atan2(
0059                 (sin(alpha1) * cos(alt1)),
0060                 sqrt(term3 * term3 + term4 * term4 * term5 * term5));
0061 
0062     if ((alt1 == 0) && (alpha1 == 0.5 * M_PI))
0063         sigma01 = 0;
0064     else
0065         sigma01 = atan2(tan(alt1), cos(alpha1));
0066 
0067     sigma02 = sigma01 + sigma12;
0068 
0069     const double lambda01 = atan2(sin(alpha0) * sin(sigma01), cos(sigma01));
0070 
0071     lambda0 = az1 - lambda01;
0072 
0073     cosAlpha0 = cos(alpha0);
0074     sinAlpha0 = sin(alpha0);
0075 }
0076 
0077 void GreatCircle::waypoint(double fraction, double *az, double *alt)
0078 {
0079     double sigma = (1-fraction) * sigma01 + fraction * sigma02;
0080     double cosSigma = cos(sigma);
0081     double sinSigma = sin(sigma);
0082 
0083     *alt = r2d(atan2(
0084                    (cosAlpha0 * sinSigma),
0085                    (sqrt(cosSigma * cosSigma + sinAlpha0 * sinAlpha0 * sinSigma * sinSigma))));
0086 
0087     double LL0 = atan2((sinAlpha0 * sinSigma), cosSigma);
0088     
0089     *az = r2d(LL0 + lambda0);
0090 }