1 /*****************************************************************************\ 2 * Lunar.h 3 * 4 * Lunar is a class that can calculate lunar fundmentals for any reasonable 5 * time. 6 * 7 * author: mark huss (mark@mhuss.com) 8 * Based on Bill Gray's open-source code at projectpluto.com 9 * 10 \*****************************************************************************/ 11 12 #if !defined( LUNAR__H ) 13 #define LUNAR__H 14 15 #include <math.h> 16 #include "AstroOps.h" 17 18 // A struct to hold the fundmental elements 19 // The member names should be familiar to Meeus fans ;-) 20 // 21 struct LunarFundamentals { 22 double Lp; 23 double D; 24 double M; 25 double Mp; 26 double F; 27 double A1; 28 double A2; 29 double A3; 30 double T; 31 LunarFundamentalsLunarFundamentals32 LunarFundamentals():Lp(0.),D(0.),M(0.),Mp(0.),F(0.),A1(0.),A2(0.),A3(0.),T(0.) {} 33 }; 34 35 // terms for longitude & radius 36 // 37 static const int N_LTERM1 = 60; 38 struct LunarTerms1 { 39 char d, m, mp, f; 40 long sl, sr; 41 }; 42 43 // terms for latitude 44 // 45 static const int N_LTERM2 = 60; 46 struct LunarTerms2 { 47 char d, m, mp, f; 48 long sb; 49 }; 50 51 // our main class -- calculates Lunar fundamentals, lat, lon & distance 52 // 53 class Lunar { 54 public: 55 // default c'tor Lunar()56 Lunar() : m_initialized( false ), m_lon(-1.), m_lat(-1.), m_r(-1.) 57 {} 58 59 // data & time c'tor 60 // t = decimal julian centuries Lunar(double t)61 Lunar( double t ) 62 { 63 calcFundamentals( t ); 64 } 65 66 static const double SYNODIC_MONTH = 29.530588861; 67 68 double illuminatedFraction(); 69 70 static double ageOfMoonInDays( double jd ); 71 72 73 74 // calculates the fundamanentals given the time 75 // t = decimal julian centuries 76 // 77 void calcFundamentals( double t ); 78 79 // 80 // NOTE: calcFundamentals() must be called before calling the functions 81 // below, or an invalid result (-1.) will be returned. 82 // 83 84 double phaseAngle(); 85 // returns lunar latitude 86 double latitude(); // returns -1 if not initialized latitudeRadians()87 double latitudeRadians() { // returns -1 if not initialized 88 return ( m_initialized ) ? Astro::toRadians( latitude() ) : -1.; 89 } 90 91 // returns lunar longitude longitude()92 double longitude() // returns -1 if not initialized 93 { 94 if ( m_lon < 0. ) 95 calcLonRad(); 96 return m_lon; 97 } 98 longitudeRadians()99 double longitudeRadians() // returns -1 if not initialized 100 { 101 return ( m_initialized ) ? Astro::toRadians( longitude() ) : -1.; 102 } 103 104 // returns lunar distance radius()105 double radius() // returns -1 if not initialized 106 { 107 if ( m_r < 0. ) 108 calcLonRad(); 109 return m_r; 110 } 111 112 // calculate all three location elements of the spec'd body at the given time 113 // calcAllLocs(double & lon,double & lat,double & rad,double t)114 void calcAllLocs( 115 double& lon, // returned longitude 116 double& lat, // returned latitude 117 double& rad, // returned radius vector 118 double t) // time in decimal centuries 119 { 120 calcFundamentals( t ); 121 lon = longitudeRadians(); 122 lat = latitudeRadians(); 123 rad = radius(); 124 } 125 126 private: 127 // reduce (0 < d < 360) a positive angle and convert to radians 128 // normalize(double d)129 double normalize( double d ) { 130 return Astro::toRadians( AstroOps::normalizeDegrees( d ) ); 131 } 132 133 // calculate an individual fundimental 134 // tptr - points to array of doubles 135 // t - time in decimal Julian centuries 136 // 137 double getFund( const double* tptr, double t ); 138 139 // calculate longitude and radius 140 // 141 // NOTE: calcFundamentals() must have been called first 142 // 143 void calcLonRad(); 144 145 // ***** data ***** 146 147 // our calculated fundmentals 148 // 149 LunarFundamentals m_f; 150 151 // true if calcFundamentals has been called 152 bool m_initialized; 153 154 // longitude, latitude, and radius (stored in _degrees_) 155 double m_lon, m_lat, m_r; 156 }; 157 158 #endif /* #if !defined( LUNAR__H ) */ 159