00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <math.h>
00020
00021 #include <qfile.h>
00022
00023 #include "ksnumbers.h"
00024 #include "ksutils.h"
00025 #include "kssun.h"
00026 #include "ksmoon.h"
00027 #include "kstarsdata.h"
00028
00029 KSMoon::KSMoon(KStarsData *kd)
00030 : KSPlanetBase( kd, I18N_NOOP("Moon"), "", 3474.8 ) {
00031 BData.setAutoDelete(true);
00032 LRData.setAutoDelete(true);
00033 }
00034
00035 KSMoon::~KSMoon() {
00036 }
00037
00038 bool KSMoon::data_loaded = false;
00039 QPtrList<KSMoon::MoonLRData> KSMoon::LRData;
00040 QPtrList<KSMoon::MoonBData> KSMoon::BData;
00041
00042 bool KSMoon::loadData() {
00043 if (data_loaded) return true;
00044
00045 QString line;
00046 QFile f;
00047 int nd, nm, nm1, nf;
00048 double Li, Ri, Bi;
00049
00050 if ( KSUtils::openDataFile( f, "moonLR.dat" ) ) {
00051 QTextStream stream( &f );
00052 while ( !stream.eof() ) {
00053 line = stream.readLine();
00054 QTextIStream instream( &line );
00055 instream >> nd >> nm >> nm1 >> nf >> Li >> Ri;
00056 LRData.append(new MoonLRData(nd, nm, nm1, nf, Li, Ri));
00057 }
00058 f.close();
00059 } else
00060 return false;
00061
00062
00063 if ( KSUtils::openDataFile( f, "moonB.dat" ) ) {
00064 QTextStream stream( &f );
00065 while ( !stream.eof() ) {
00066 line = stream.readLine();
00067 QTextIStream instream( &line );
00068 instream >> nd >> nm >> nm1 >> nf >> Bi;
00069 BData.append(new MoonBData(nd, nm, nm1, nf, Bi));
00070 }
00071 f.close();
00072 }
00073
00074 data_loaded = true;
00075 return true;
00076 }
00077
00078 bool KSMoon::findGeocentricPosition( const KSNumbers *num, const KSPlanetBase* ) {
00079
00080
00081 QString fname, snum, line;
00082 QFile f;
00083 double DegtoRad;
00084 double T, L, D, M, M1, F, E, A1, A2, A3;
00085 double sumL, sumR, sumB;
00086
00087 DegtoRad = acos( -1.0 )/180.0;
00088
00089
00090 T = num->julianCenturies();
00091
00092 double Et = 1.0 - 0.002516*T - 0.0000074*T*T;
00093
00094
00095 L = 218.3164591 + 481267.88134236*T - 0.0013268*T*T + T*T*T/538841.0 - T*T*T*T/65194000.0;
00096 while ( L > 360.0 ) L -= 360.0;
00097 while ( L < 0.0 ) L += 360.0;
00098 L *= DegtoRad;
00099
00100 D = 297.8502042 + 445267.1115168*T - 0.0016300*T*T + T*T*T/545868.0 - T*T*T*T/113065000.0;
00101 while ( D > 360.0 ) D -= 360.0;
00102 while ( D < 0.0 ) D += 360.0;
00103 D *= DegtoRad;
00104
00105 M = 357.5291092 + 35999.0502909*T - 0.0001536*T*T + T*T*T/24490000.0;
00106 while ( M > 360.0 ) M -= 360.0;
00107 while ( M < 0.0 ) M += 360.0;
00108 M *= DegtoRad;
00109
00110 M1= 134.9634114 + 477198.8676313*T + 0.0089970*T*T + T*T*T/69699.0 - T*T*T*T/14712000.0;
00111 while ( M1 > 360.0 ) M1 -= 360.0;
00112 while ( M1 < 0.0 ) M1 += 360.0;
00113 M1 *= DegtoRad;
00114
00115 F = 93.2720993 + 483202.0175273*T - 0.0034029*T*T - T*T*T/3526000.0 + T*T*T*T/863310000.0;
00116 while ( F > 360.0 ) F -= 360.0;
00117 while ( F < 0.0 ) F += 360.0;
00118 F *= DegtoRad;
00119
00120 A1 = 119.75 + 131.849*T;
00121 A2 = 53.09 + 479264.290*T;
00122 A3 = 313.45 + 481226.484*T;
00123 while ( A1 > 360.0 ) A1 -= 360.0;
00124 while ( A1 < 0.0 ) A1 += 360.0;
00125 while ( A2 > 360.0 ) A2 -= 360.0;
00126 while ( A2 < 0.0 ) A2 += 360.0;
00127 while ( A3 > 360.0 ) A3 -= 360.0;
00128 while ( A3 < 0.0 ) A3 += 360.0;
00129 A1 *= DegtoRad;
00130 A2 *= DegtoRad;
00131 A3 *= DegtoRad;
00132
00133
00134
00135 sumL = 0.0;
00136 sumR = 0.0;
00137
00138 if (!loadData()) return false;
00139
00140 for (MoonLRData *mlrd = LRData.first(); mlrd != 0; mlrd = LRData.next()) {
00141
00142 E = 1.0;
00143 if ( mlrd->nm ) {
00144 E = Et;
00145 if ( abs( mlrd->nm )==2 ) E = E*E;
00146 }
00147 sumL += E*mlrd->Li*sin( mlrd->nd*D + mlrd->nm*M + mlrd->nm1*M1 + mlrd->nf*F );
00148 sumR += E*mlrd->Ri*cos( mlrd->nd*D + mlrd->nm*M + mlrd->nm1*M1 + mlrd->nf*F );
00149 }
00150
00151 sumB = 0.0;
00152 for (MoonBData *mbd = BData.first(); mbd != 0; mbd = BData.next()) {
00153
00154 E = 1.0;
00155 if ( mbd->nm ) {
00156 E = Et;
00157 if ( abs( mbd->nm )==2 ) E = E*E;
00158 }
00159 sumB += E*mbd->Bi*sin( mbd->nd*D + mbd->nm*M + mbd->nm1*M1 + mbd->nf*F );
00160 }
00161
00162
00163 sumL += ( 3958.0*sin( A1 ) + 1962.0*sin( L-F ) + 318.0*sin( A2 ) );
00164 sumB += ( -2235.0*sin( L ) + 382.0*sin( A3 ) + 175.0*sin( A1-F ) + 175.0*sin( A1+F ) + 127.0*sin( L-M1 ) - 115.0*sin( L+M1 ) );
00165
00166
00167 setEcLong( ( L + DegtoRad*sumL/1000000.0 ) * 180./dms::PI );
00168 setEcLat( ( DegtoRad*sumB/1000000.0 ) * 180./dms::PI );
00169 Rearth = ( 385000.56 + sumR/1000.0 )/AU_KM;
00170 setAngularSize( asin(physicalSize()/Rearth/AU_KM)*60.*180./dms::PI );
00171
00172 EclipticToEquatorial( num->obliquity() );
00173
00174
00175 findPA( num );
00176
00177 return true;
00178 }
00179
00180 void KSMoon::findPhase( const KSSun *Sun ) {
00181 Phase.setD( ecLong()->Degrees() - Sun->ecLong()->Degrees() );
00182 Phase.setD( Phase.reduce().Degrees() );
00183 int iPhase = int( 0.1*Phase.Degrees()+0.5 );
00184 if (iPhase==36) iPhase = 0;
00185 QString sPhase;
00186 sPhase = sPhase.sprintf( "%02d", iPhase );
00187 QString imName = "moon" + sPhase + ".png";
00188
00189 QFile imFile;
00190 if ( KSUtils::openDataFile( imFile, imName ) ) {
00191 imFile.close();
00192 image0()->load( imFile.name() );
00193 image()->load( imFile.name() );
00194
00195 }
00196 }
00197
00198 QString KSMoon::phaseName() const {
00199 double f = illum();
00200 double p = phase().Degrees();
00201
00202
00203 if ( f > 0.99 ) return i18n( "moon phase, 100 percent illuminated", "Full moon" );
00204 if ( f < 0.01 ) return i18n( "moon phase, 0 percent illuminated", "New moon" );
00205 if ( fabs( f - 0.50 ) < 0.01 ) {
00206 if ( p < 180.0 ) return i18n( "moon phase, half-illuminated and growing", "First quarter" );
00207 else return i18n( "moon phase, half-illuminated and shrinking", "Third quarter" );
00208 }
00209
00210
00211 if ( p < 90.0 ) return i18n( "moon phase between new moon and 1st quarter", "Waxing crescent" );
00212 else if ( p < 180.0 ) return i18n( "moon phase between 1st quarter and full moon", "Waxing gibbous" );
00213 else if ( p < 270.0 ) return i18n( "moon phase between full moon and 3rd quarter", "Waning gibbous" );
00214 else if ( p < 360.0 ) return i18n( "moon phase between 3rd quarter and new moon", "Waning crescent" );
00215
00216 else return i18n( "unknown" );
00217 }