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

0001 /*
0002     SPDX-FileCopyrightText: 2018 Valentin Boettcher <valentin@boettcher.cf>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "ksearthshadow.h"
0007 #include "kssun.h"
0008 #include "ksmoon.h"
0009 
0010 KSEarthShadow::KSEarthShadow(const KSMoon *moon, const KSSun *sun, const KSPlanet * earth)
0011     : KSPlanetBase (i18n("Earth Shadow")), m_sun { sun }, m_moon { moon }, m_earth {earth}
0012 {
0013 }
0014 
0015 bool KSEarthShadow::shouldUpdate()
0016 {
0017     return (m_moon->illum() > 0.8);
0018 }
0019 
0020 bool KSEarthShadow::isInEclipse()
0021 {
0022     double dist = angularDistanceTo(m_moon).Degrees() * 60;
0023     return (dist - m_moon->angSize() / 2) <= m_penumbra_ang;
0024 }
0025 
0026 KSEarthShadow::ECLIPSE_TYPE KSEarthShadow::getEclipseType()
0027 {
0028     double half_a_moon = m_moon->angSize() / 2;
0029     double dist = angularDistanceTo(m_moon).Degrees() * 60; // arcminutes
0030     if (dist <= (m_penumbra_ang - half_a_moon))
0031     {
0032         if(dist <= (m_umbra_ang - half_a_moon))
0033             return FULL_UMBRA;
0034         else
0035             return FULL_PENUMBRA;
0036     }
0037     else if ((dist - half_a_moon) <= m_penumbra_ang)
0038     {
0039         return PARTIAL;
0040     }
0041 
0042     return NONE;
0043 }
0044 
0045 bool KSEarthShadow::findGeocentricPosition(const KSNumbers *, const KSPlanetBase *)
0046 {
0047     updateCoords();
0048     return true; //TODO: not nice!
0049 }
0050 
0051 
0052 void KSEarthShadow::updateCoords(const KSNumbers *, bool, const CachingDms *, const CachingDms *, bool )
0053 {
0054     updateCoords();
0055 }
0056 
0057 //TODO: Abort if Null
0058 void KSEarthShadow::updateCoords()
0059 {
0060     // flip the sun around to get the 'shadow coordinates'
0061     dms t_ra(m_sun->ra().Degrees() + 180);
0062     t_ra.reduceToRange(dms::ZERO_TO_2PI);
0063     dms t_dec(-1 * (m_sun->dec().Degrees()));
0064 
0065     set(t_ra, t_dec);
0066     Rearth = m_moon->rearth();
0067 }
0068 
0069 
0070 //NOTE: This can easily be generalized to any three bodies.
0071 void KSEarthShadow::calculateShadowRadius()
0072 {
0073     double d_sun = m_sun->rearth() * AU_KM;
0074     double d_moon = m_moon->rearth() * AU_KM;
0075     double r_sun = m_sun->physicalSize() / 2;
0076     double r_earth = m_earth->physicalSize() / 2;
0077 
0078     double umbraRad = 1.01 * r_earth + (r_earth - r_sun) / d_sun * d_moon;
0079     double penumbraRad = 1.01 * r_earth + (r_sun + r_earth) / d_sun * d_moon;
0080 
0081     m_umbra_ang = asin(umbraRad / d_moon) * 60. * 180. / dms::PI;
0082     m_penumbra_ang = asin(penumbraRad / d_moon) * 60. * 180. / dms::PI;
0083 
0084     return;
0085 }