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 //--------------------------------------------------------------------------------