• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kstars

  • sources
  • kde-4.12
  • kdeedu
  • kstars
  • kstars
  • skyobjects
ksmoon.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ksmoon.cpp - K Desktop Planetarium
3  -------------------
4  begin : Sun Aug 26 2001
5  copyright : (C) 2001 by Jason Harris
6  email : kstars@30doradus.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "ksmoon.h"
19 
20 #include <cstdlib>
21 #include <cmath>
22 #if defined(_MSC_VER)
23 #include <float.h>
24 #endif
25 
26 #include <QFile>
27 #include <QTextStream>
28 
29 #include "ksnumbers.h"
30 #include "ksutils.h"
31 #include "kssun.h"
32 #include "kstarsdata.h"
33 #include "kspopupmenu.h"
34 #include "skycomponents/skymapcomposite.h"
35 #include "texturemanager.h"
36 
37 using namespace std;
38 
39 namespace {
40  // Convert degrees to radians and put it into [0,2*pi] range
41  double degToRad(double x) {
42  return dms::DegToRad * KSUtils::reduceAngle(x, 0.0, 360.0);
43  }
44 
45  /*
46  * Data used to calculate moon magnitude.
47  *
48  * Formula and data were obtained from SkyChart v3.x Beta
49  *
50  */
51  // intensities in Table 1 of M. Minnaert (1961),
52  // Phase Frac. Phase Frac. Phase Frac.
53  // angle ill. Mag angle ill. Mag angle ill. Mag
54  // 0 1.00 -12.7 60 0.75 -11.0 120 0.25 -8.7
55  // 10 0.99 -12.4 70 0.67 -10.8 130 0.18 -8.2
56  // 20 0.97 -12.1 80 0.59 -10.4 140 0.12 -7.6
57  // 30 0.93 -11.8 90 0.50 -10.0 150 0.07 -6.7
58  // 40 0.88 -11.5 100 0.41 -9.6 160 0.03 -3.4
59  // 50 0.82 -11.2 110 0.33 -9.2
60  static const double MagArray[19] = {
61  -12.7, -12.4, -12.1, -11.8, -11.5, -11.2, -11.0, -10.8, -10.4, -10.0,
62  -9.6, -9.2, -8.7, -8.2, -7.6, -6.7, -3.4, 0, 0};
63 }
64 
65 KSMoon::KSMoon()
66  : KSPlanetBase( I18N_NOOP( "Moon" ), QString(), QColor("white"), 3474.8 /*diameter in km*/ )
67 {
68  instance_count++;
69  //Reset object type
70  setType( SkyObject::MOON );
71 }
72 
73 KSMoon::KSMoon(const KSMoon& o) :
74  KSPlanetBase(o)
75 {
76  instance_count++;
77 }
78 
79 KSMoon* KSMoon::clone() const
80 {
81  return new KSMoon(*this);
82 }
83 
84 KSMoon::~KSMoon() {
85  instance_count--;
86  if(instance_count <= 0) {
87  LRData.clear();
88  BData.clear();
89  data_loaded = false;
90  }
91 }
92 
93 bool KSMoon::data_loaded = false;
94 int KSMoon::instance_count = 0;
95 QList<KSMoon::MoonLRData> KSMoon::LRData;
96 QList<KSMoon::MoonBData> KSMoon::BData;
97 
98 
99 bool KSMoon::loadData() {
100  if (data_loaded)
101  return true;
102 
103  QStringList fields;
104  QFile f;
105 
106  if ( KSUtils::openDataFile( f, "moonLR.dat" ) ) {
107  QTextStream stream( &f );
108  while ( !stream.atEnd() ) {
109  fields = stream.readLine().split( ' ', QString::SkipEmptyParts );
110 
111  if ( fields.size() == 6 ) {
112  LRData.append( MoonLRData() );
113  LRData.last().nd = fields[0].toInt();
114  LRData.last().nm = fields[1].toInt();
115  LRData.last().nm1 = fields[2].toInt();
116  LRData.last().nf = fields[3].toInt();
117  LRData.last().Li = fields[4].toDouble();
118  LRData.last().Ri = fields[5].toDouble();
119  }
120  }
121  f.close();
122  } else
123  return false;
124 
125 
126  if ( KSUtils::openDataFile( f, "moonB.dat" ) ) {
127  QTextStream stream( &f );
128  while ( !stream.atEnd() ) {
129  fields = stream.readLine().split( ' ', QString::SkipEmptyParts );
130 
131  if ( fields.size() == 5 ) {
132  BData.append( MoonBData() );
133  BData.last().nd = fields[0].toInt();
134  BData.last().nm = fields[1].toInt();
135  BData.last().nm1 = fields[2].toInt();
136  BData.last().nf = fields[3].toInt();
137  BData.last().Bi = fields[4].toDouble();
138  }
139  }
140  f.close();
141  }
142 
143  data_loaded = true;
144  return true;
145 }
146 
147 bool KSMoon::findGeocentricPosition( const KSNumbers *num, const KSPlanetBase* ) {
148  //Algorithms in this subroutine are taken from Chapter 45 of "Astronomical Algorithms"
149  //by Jean Meeus (1991, Willmann-Bell, Inc. ISBN 0-943396-35-2. http://www.willbell.com/math/mc1.htm)
150  QString fname, snum, line;
151  QFile f;
152 
153  double T, L, D, M, M1, F, A1, A2, A3;
154  double sumL, sumR, sumB;
155 
156  //Julian centuries since J2000
157  T = num->julianCenturies();
158 
159  double Et = 1.0 - 0.002516*T - 0.0000074*T*T;
160 
161  //Moon's mean longitude
162  L = degToRad( 218.3164591 + 481267.88134236*T - 0.0013268*T*T + T*T*T/538841.0 - T*T*T*T/65194000.0 );
163  //Moon's mean elongation
164  D = degToRad( 297.8502042 + 445267.1115168*T - 0.0016300*T*T + T*T*T/545868.0 - T*T*T*T/113065000.0 );
165  //Sun's mean anomaly
166  M = degToRad( 357.5291092 + 35999.0502909*T - 0.0001536*T*T + T*T*T/24490000.0 );
167  //Moon's mean anomaly
168  M1= degToRad( 134.9634114 + 477198.8676313*T + 0.0089970*T*T + T*T*T/69699.0 - T*T*T*T/14712000.0 );
169  //Moon's argument of latitude (angle from ascending node)
170  F = degToRad( 93.2720993 + 483202.0175273*T - 0.0034029*T*T - T*T*T/3526000.0 + T*T*T*T/863310000.0 );
171 
172  A1 = degToRad( 119.75 + 131.849*T );
173  A2 = degToRad( 53.09 + 479264.290*T );
174  A3 = degToRad( 313.45 + 481226.484*T );
175 
176  //Calculate the series expansions stored in moonLR.txt and moonB.txt.
177  //
178  sumL = 0.0;
179  sumR = 0.0;
180 
181  if (!loadData()) return false;
182 
183  for ( int i=0; i < LRData.size(); ++i ) {
184  const MoonLRData& mlrd = LRData[i];
185 
186  double E = 1.0;
187  if ( mlrd.nm ) { //if M != 0, include changing eccentricity of Earth's orbit
188  E = Et;
189  if ( abs( mlrd.nm )==2 ) E = E*E; //use E^2
190  }
191  sumL += E*mlrd.Li*sin( mlrd.nd*D + mlrd.nm*M + mlrd.nm1*M1 + mlrd.nf*F );
192  sumR += E*mlrd.Ri*cos( mlrd.nd*D + mlrd.nm*M + mlrd.nm1*M1 + mlrd.nf*F );
193  }
194 
195  sumB = 0.0;
196  for ( int i=0; i < BData.size(); ++i ) {
197  const MoonBData& mbd = BData[i];
198 
199  double E = 1.0;
200  if ( mbd.nm ) { //if M != 0, include changing eccentricity of Earth's orbit
201  E = Et;
202  if ( abs( mbd.nm )==2 ) E = E*E; //use E^2
203  }
204  sumB += E*mbd.Bi*sin( mbd.nd*D + mbd.nm*M + mbd.nm1*M1 + mbd.nf*F );
205  }
206 
207  //Additive terms for sumL and sumB
208  sumL += ( 3958.0*sin( A1 ) + 1962.0*sin( L-F ) + 318.0*sin( A2 ) );
209  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 ) );
210 
211  //Geocentric coordinates
212  setEcLong( dms( sumL/1000000.0 + L * 180.0 / dms::PI) ); //convert radians to degrees
213  setEcLat( dms( sumB/1000000.0 ) );
214  Rearth = ( 385000.56 + sumR/1000.0 )/AU_KM; //distance from Earth, in AU
215 
216  EclipticToEquatorial( num->obliquity() );
217 
218  //Determine position angle
219  findPA( num );
220 
221  return true;
222 }
223 
224 void KSMoon::findMagnitude(const KSNumbers*)
225 {
226  // This block of code to compute Moon magnitude (and the
227  // relevant data put into ksplanetbase.h) was taken from
228  // SkyChart v3 Beta
229  double phd = phase().Degrees();
230  if( isnan( phd ) ) // Avoid nanny phases.
231  return;
232  int p = floor( phd );
233  if( p > 180 )
234  p = p - 360;
235  int i = p / 10;
236  int k = p % 10;
237  int j = (i + 1 > 18) ? 18 : i + 1;
238  i = 18 - abs(i);
239  j = 18 - abs(j);
240  setMag( MagArray[i] + (MagArray[j] - MagArray[i]) * k / 10 );
241 }
242 
243 void KSMoon::findPhase( const KSSun *Sun ) {
244 
245  if( !Sun )
246  Sun = ( const KSSun* ) KStarsData::Instance()->skyComposite()->findByName( "Sun" );
247 
248  Phase = (ecLong() - Sun->ecLong()).Degrees(); // Phase is obviously in degrees
249  double DegPhase = dms( Phase ).reduce().Degrees();
250  iPhase = int( 0.1*DegPhase+0.5 ) % 36; // iPhase must be in [0,36) range
251 
252  m_image = TextureManager::getImage(
253  QString("moon%1").arg(iPhase,2,10,QChar('0')));
254 }
255 
256 QString KSMoon::phaseName() const {
257  double f = illum();
258  double p = abs(dms(Phase).reduce().Degrees());
259 
260  //First, handle the major phases
261  if ( f > 0.99 ) return i18nc( "moon phase, 100 percent illuminated", "Full moon" );
262  if ( f < 0.01 ) return i18nc( "moon phase, 0 percent illuminated", "New moon" );
263  if ( fabs( f - 0.50 ) < 0.01 ) {
264  if ( p < 180.0 ) return i18nc( "moon phase, half-illuminated and growing", "First quarter" );
265  else return i18nc( "moon phase, half-illuminated and shrinking", "Third quarter" );
266  }
267 
268  //Next, handle the more general cases
269  if ( p < 90.0 ) return i18nc( "moon phase between new moon and 1st quarter", "Waxing crescent" );
270  else if ( p < 180.0 ) return i18nc( "moon phase between 1st quarter and full moon", "Waxing gibbous" );
271  else if ( p < 270.0 ) return i18nc( "moon phase between full moon and 3rd quarter", "Waning gibbous" );
272  else if ( p < 360.0 ) return i18nc( "moon phase between 3rd quarter and new moon", "Waning crescent" );
273 
274  else return i18n( "unknown" );
275 }
276 
277 void KSMoon::initPopupMenu( KSPopupMenu* pmenu ) {
278  pmenu->createMoonMenu( this );
279 }
280 
281 SkyObject::UID KSMoon::getUID() const
282 {
283  return solarsysUID(UID_SOL_BIGOBJ) | 10;
284 }
KSPlanetBase::findPhase
virtual void findPhase()
Determine the phase of the planet.
Definition: ksplanetbase.cpp:277
KSMoon::illum
double illum() const
Definition: ksmoon.h:58
KSUtils::reduceAngle
T reduceAngle(T x, T min, T max)
Put angle into range.
Definition: ksutils.h:74
KSPopupMenu
The KStars Popup Menu.
Definition: kspopupmenu.h:43
KSSun
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition: kssun.h:31
KStarsData::Instance
static KStarsData * Instance()
Definition: kstarsdata.h:92
dms::Degrees
const double & Degrees() const
Definition: dms.h:98
KSPlanetBase::m_image
QImage m_image
Definition: ksplanetbase.h:245
TextureManager::getImage
static const QImage & getImage(const QString &name)
Return texture image.
Definition: texturemanager.cpp:44
KSUtils::openDataFile
bool openDataFile(QFile &file, const QString &filename)
Attempt to open the data file named filename, using the QFile object "file".
KSMoon::~KSMoon
~KSMoon()
Destructor (empty).
Definition: ksmoon.cpp:84
KSPlanetBase::UID_SOL_BIGOBJ
static const UID UID_SOL_BIGOBJ
Big object.
Definition: ksplanetbase.h:203
NaN::f
const float f
Definition: nan.h:36
kspopupmenu.h
F
#define F
Definition: satellite.cpp:58
texturemanager.h
KSPlanetBase::Phase
double Phase
Definition: ksplanetbase.h:244
AU_KM
#define AU_KM
Definition: kstarsdata.h:42
KSPlanetBase::findPA
void findPA(const KSNumbers *num)
Determine the position angle of the planet for a given date (used internally by findPosition() ) ...
Definition: ksplanetbase.cpp:240
KSPopupMenu::createMoonMenu
void createMoonMenu(KSMoon *moon)
Definition: kspopupmenu.cpp:210
skymapcomposite.h
KSPlanetBase::solarsysUID
UID solarsysUID(UID type) const
Compute high 32-bits of UID.
Definition: ksplanetbase.h:210
KSMoon::getUID
virtual SkyObject::UID getUID() const
Return UID for object.
Definition: ksmoon.cpp:281
i18nc
i18nc("string from libindi, used in the config dialog","100x")
SkyObject::UID
qint64 UID
Type for Unique object IDenticator.
Definition: skyobject.h:53
SkyObject::MOON
Definition: skyobject.h:110
ksnumbers.h
KSNumbers::obliquity
const dms * obliquity() const
Definition: ksnumbers.h:58
KSMoon::loadData
virtual bool loadData()
reimplemented from KSPlanetBase
Definition: ksmoon.cpp:99
KSPlanetBase::EclipticToEquatorial
void EclipticToEquatorial(const dms *Obliquity)
Convert Ecliptic logitude/latitude to Right Ascension/Declination.
Definition: ksplanetbase.cpp:101
KStarsData::skyComposite
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:146
KSMoon::clone
virtual KSMoon * clone() const
Create copy of object.
Definition: ksmoon.cpp:79
dms
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:42
SkyObject::setType
void setType(int t)
Set the object's type identifier to the argument.
Definition: skyobject.h:171
KSMoon::phaseName
QString phaseName() const
Definition: ksmoon.cpp:256
SkyObject::setMag
void setMag(float m)
Set the object's sorting magnitude.
Definition: skyobject.h:409
QTextStream
KSNumbers
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition: ksnumbers.h:43
KSPlanetBase::ecLong
const dms & ecLong() const
Definition: ksplanetbase.h:91
kssun.h
KSPlanetBase::setEcLat
void setEcLat(dms elat)
Set Ecliptic Geocentric Latitude according to argument.
Definition: ksplanetbase.h:104
KSMoon
A subclass of SkyObject that provides information needed for the Moon.
Definition: ksmoon.h:36
PI
#define PI
Definition: satellite.cpp:43
ksmoon.h
SkyMapComposite::findByName
virtual SkyObject * findByName(const QString &name)
Search the children of this SkyMapComposite for a SkyObject whose name matches the argument...
Definition: skymapcomposite.cpp:426
KSPlanetBase
A subclass of TrailObject that provides additional information needed for most solar system objects...
Definition: ksplanetbase.h:63
KSPlanetBase::Rearth
double Rearth
Definition: ksplanetbase.h:243
kstarsdata.h
KSPlanetBase::setEcLong
void setEcLong(dms elong)
Set Ecliptic Geocentric Longitude according to argument.
Definition: ksplanetbase.h:99
KSNumbers::julianCenturies
double julianCenturies() const
Definition: ksnumbers.h:90
KSMoon::KSMoon
KSMoon()
Default constructor.
Definition: ksmoon.cpp:65
ksutils.h
KSMoon::findGeocentricPosition
virtual bool findGeocentricPosition(const KSNumbers *num, const KSPlanetBase *)
Reimplemented from KSPlanetBase, this function employs unique algorithms for estimating the lunar coo...
Definition: ksmoon.cpp:147
KSPlanetBase::phase
dms phase()
Definition: ksplanetbase.h:187
QList
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:36:20 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

Skip menu "kstars"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal