File indexing completed on 2024-04-21 05:46:36

0001 // SPDX-License-Identifier: GPL-3.0-or-later
0002 /*
0003   Copyright 2021 Martin Koller, kollix@aon.at
0004 
0005   This file is part of liquidshell.
0006 
0007   liquidshell is free software: you can redistribute it and/or modify
0008   it under the terms of the GNU General Public License as published by
0009   the Free Software Foundation, either version 3 of the License, or
0010   (at your option) any later version.
0011 
0012   liquidshell is distributed in the hope that it will be useful,
0013   but WITHOUT ANY WARRANTY; without even the implied warranty of
0014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0015   GNU General Public License for more details.
0016 
0017   You should have received a copy of the GNU General Public License
0018   along with liquidshell.  If not, see <http://www.gnu.org/licenses/>.
0019 */
0020 
0021 // original code from http://www.voidware.com/phase.c
0022 // adjusted for liquidshell
0023 
0024 #include <Moon.hxx>
0025 #include <cmath>
0026 
0027 #define PI  3.1415926535897932384626433832795
0028 #define RAD  (PI/180.0)
0029 #define SMALL_FLOAT  (1e-12)
0030 
0031 //--------------------------------------------------------------------------------
0032 
0033 int Moon::phase(const QDate &date)
0034 {
0035   double j = date.toJulianDay() - 2444238.5;
0036   double ls = sun_position(j);
0037   double lm = moon_position(j, ls);
0038   double t = lm - ls;
0039 
0040   if (t < 0) t += 360;
0041   return static_cast<int>((t / 360.0) * 55);
0042 }
0043 
0044 //--------------------------------------------------------------------------------
0045 
0046 double Moon::sun_position(double j)
0047 {
0048   double n, x, e, l, dl, v;
0049   int i;
0050   n = 360 / 365.2422 * j;
0051   i = n / 360;
0052   n = n - i * 360.0;
0053   x = n - 3.762863;
0054 
0055   if (x < 0) x += 360;
0056 
0057   x *= RAD;
0058   e = x;
0059 
0060   do
0061   {
0062     dl = e - .016718 * std::sin(e) - x;
0063     e = e - dl / (1 - .016718 * std::cos(e));
0064   }
0065   while (std::fabs(dl) >= SMALL_FLOAT);
0066 
0067   v = 360 / PI * std::atan(1.01686011182 * std::tan(e / 2));
0068   l = v + 282.596403;
0069   i = l / 360;
0070   l = l - i * 360.0;
0071   return l;
0072 }
0073 
0074 //--------------------------------------------------------------------------------
0075 
0076 double Moon::moon_position(double j, double ls)
0077 {
0078   double ms, l, mm, n, ev, sms, ae, ec;
0079   int i;
0080   /* ls = sun_position(j) */
0081   ms = 0.985647332099 * j - 3.762863;
0082 
0083   if (ms < 0) ms += 360.0;
0084 
0085   l = 13.176396 * j + 64.975464;
0086   i = l / 360;
0087   l = l - i * 360.0;
0088 
0089   if (l < 0) l += 360.0;
0090 
0091   mm = l - 0.1114041 * j - 349.383063;
0092   i = mm / 360;
0093   mm -= i * 360.0;
0094   n = 151.950429 - 0.0529539 * j;
0095   i = n / 360;
0096   n -= i * 360.0;
0097   ev = 1.2739 * std::sin((2 * (l - ls) - mm) * RAD);
0098   sms =  std::sin(ms * RAD);
0099   ae = 0.1858 * sms;
0100   mm += ev - ae - 0.37 * sms;
0101   ec = 6.2886 * std::sin(mm * RAD);
0102   l += ev + ec - ae + 0.214 * std::sin(2 * mm * RAD);
0103   l = 0.6583 * std::sin(2 * (l - ls) * RAD) + l;
0104   return l;
0105 }
0106 
0107 //--------------------------------------------------------------------------------