File indexing completed on 2024-04-21 14:46:42
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 }