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

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
SunLocator.cpp
Go to the documentation of this file.
1 // Copyright 2007-2009 David Roberts <dvdr18@gmail.com>
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library. If not, see <http://www.gnu.org/licenses/>.
15 
16 #include "SunLocator.h"
17 
18 #include "MarbleGlobal.h"
19 #include "MarbleClock.h"
20 #include "Planet.h"
21 #include "MarbleMath.h"
22 
23 #include "MarbleDebug.h"
24 
25 #include <cmath>
26 // M_PI is sometimes defined in <cmath>
27 #ifndef M_PI
28 #define M_PI 3.14159265358979323846264338327950288419717
29 #endif
30 
31 namespace Marble
32 {
33 
34 using std::sin;
35 using std::cos;
36 using std::asin;
37 using std::abs;
38 
39 
40 // epoch J2000 = 1 January 2000, noon Terrestrial Time (11:58:55.816 UTC)
41 const int J2000 = 2451545;
42 
43 // taking the full moon of 15 January 1900 19:07 UTC as the epoch for the moon
44 // value from http://home.hiwaay.net/~krcool/Astro/moon/fullmoon.htm
45 const qreal MOON_EPOCH = 2415035.297;
46 const qreal MOON_SYNODIC_PERIOD = 29.530588;
47 
48 // emit updateSun() every update_interval ms
49 const int update_interval = 60000;
50 
51 class SunLocatorPrivate
52 {
53 public:
54  SunLocatorPrivate( const MarbleClock *clock, const Planet *planet )
55  : m_lon( 0.0 ),
56  m_lat( 0.0 ),
57  m_clock( clock ),
58  m_planet( planet )
59  {
60  }
61 
62  qreal m_lon;
63  qreal m_lat;
64 
65  const MarbleClock *const m_clock;
66  const Planet *m_planet;
67 };
68 
69 
70 SunLocator::SunLocator( const MarbleClock *clock, const Planet *planet )
71  : QObject(),
72  d( new SunLocatorPrivate( clock, planet ))
73 {
74 }
75 
76 SunLocator::~SunLocator()
77 {
78  delete d;
79 }
80 
81 void SunLocator::updatePosition()
82 {
83  if( d->m_planet->id() == "moon" ) {
84  // days since the first full moon of the 20th century
85  qreal days = (qreal)d->m_clock->dateTime().date().toJulianDay() + d->m_clock->dayFraction() - MOON_EPOCH;
86 
87  // number of orbits the moon has made (relative to the sun as observed from earth)
88  days /= MOON_SYNODIC_PERIOD;
89 
90  // take fractional part
91  days = days - (int)days;
92 
93  // for dates before MOON_EPOCH
94  if (days < 0.0)
95  days += 1.0;
96 
97  mDebug() << "MOON:" << (int)(days*100) << "% of orbit completed and"
98  << (int)(abs((days-0.5)*2) * 100) << "% illuminated";
99 
100  d->m_lon = (1-days) * 2*M_PI;
101 
102  // not necessarily accurate but close enough
103  // (only differs by about +-6 degrees of this value)
104  d->m_lat = 0.0;
105  return;
106  }
107 
108  // find current Julian day number relative to epoch J2000
109  long day = d->m_clock->dateTime().date().toJulianDay() - J2000;
110 
111  // from http://www.astro.uu.nl/~strous/AA/en/reken/zonpositie.html
112  // mean anomaly
113  qreal M = d->m_planet->M_0() + d->m_planet->M_1()*day;
114 
115  // equation of center
116  qreal C = d->m_planet->C_1()*sin(M) + d->m_planet->C_2()*sin(2*M)
117  + d->m_planet->C_3()*sin(3*M) + d->m_planet->C_4()*sin(4*M)
118  + d->m_planet->C_5()*sin(5*M) + d->m_planet->C_6()*sin(6*M);
119 
120  // true anomaly
121  qreal nu = M + C;
122 
123  // ecliptic longitude of sun as seen from planet
124  qreal lambda_sun = nu + d->m_planet->Pi() + M_PI;
125 
126  // declination of sun as seen from planet
127  qreal delta_sun = asin(sin(d->m_planet->epsilon())*sin(lambda_sun));
128 
129  // right ascension of sun as seen from planet
130  qreal alpha_sun = atan2(cos(d->m_planet->epsilon())*sin(lambda_sun), cos(lambda_sun));
131 
132  // solar noon occurs when sidereal time is equal to alpha_sun
133  qreal theta = alpha_sun;
134 
135  // convert sidereal time to geographic longitude
136  d->m_lon = M_PI - (d->m_planet->theta_0() + d->m_planet->theta_1()
137  * (day + d->m_clock->dayFraction()) - theta);
138 
139  while(d->m_lon < 0)
140  d->m_lon += 2*M_PI;
141 
142  d->m_lat = delta_sun;
143 }
144 
145 
146 qreal SunLocator::shading(qreal lon, qreal a, qreal c) const
147 {
148  // haversine formula
149  qreal b = sin((lon-d->m_lon)/2.0);
150 // qreal g = sin((lat-d->m_lat)/2.0);
151 // qreal h = (g*g)+cos(lat)*cos(d->m_lat)*(b*b);
152  qreal h = (a*a) + c * (b*b);
153 
154  /*
155  h = 0.0 // directly beneath sun
156  h = 0.5 // sunrise/sunset line
157  h = 1.0 // opposite side of earth to the sun
158  theta = 2*asin(sqrt(h))
159  */
160 
161  qreal twilightZone = 0.0;
162 
163  if ( d->m_planet->id() == "earth" || d->m_planet->id() == "venus" ) {
164  twilightZone = 0.1; // this equals 18 deg astronomical twilight.
165  }
166 
167  qreal brightness;
168  if ( h <= 0.5 - twilightZone / 2.0 )
169  brightness = 1.0;
170  else if ( h >= 0.5 + twilightZone / 2.0 )
171  brightness = 0.0;
172  else
173  brightness = ( 0.5 + twilightZone/2.0 - h ) / twilightZone;
174 
175  return brightness;
176 }
177 
178 void SunLocator::shadePixel(QRgb& pixcol, qreal brightness) const
179 {
180  // daylight - no change
181  if ( brightness > 0.99999 )
182  return;
183 
184  if ( brightness < 0.00001 ) {
185  // night
186  // Doing "pixcol = qRgb(r/2, g/2, b/2);" by shifting some electrons around ;)
187  // by shifting some electrons around ;)
188  pixcol = qRgb(qRed(pixcol) * 0.35, qGreen(pixcol) * 0.35, qBlue(pixcol) * 0.35);
189  // pixcol = (pixcol & 0xff000000) | ((pixcol >> 1) & 0x7f7f7f);
190  } else {
191  // gradual shadowing
192  int r = qRed( pixcol );
193  int g = qGreen( pixcol );
194  int b = qBlue( pixcol );
195  qreal d = 0.65 * brightness + 0.35;
196  pixcol = qRgb((int)(d * r), (int)(d * g), (int)(d * b));
197  }
198 }
199 
200 void SunLocator::shadePixelComposite(QRgb& pixcol, const QRgb& dpixcol,
201  qreal brightness) const
202 {
203  // daylight - no change
204  if ( brightness > 0.99999 )
205  return;
206 
207  if ( brightness < 0.00001 ) {
208  // night
209  pixcol = dpixcol;
210  } else {
211  // gradual shadowing
212  qreal& d = brightness;
213 
214  int r = qRed( pixcol );
215  int g = qGreen( pixcol );
216  int b = qBlue( pixcol );
217 
218  int dr = qRed( dpixcol );
219  int dg = qGreen( dpixcol );
220  int db = qBlue( dpixcol );
221 
222  pixcol = qRgb( (int)( d * r + (1 - d) * dr ),
223  (int)( d * g + (1 - d) * dg ),
224  (int)( d * b + (1 - d) * db ) );
225  }
226 }
227 
228 void SunLocator::update()
229 {
230  updatePosition();
231 
232  emit positionChanged( getLon(), getLat() );
233 }
234 
235 void SunLocator::setPlanet( const Planet *planet )
236 {
237  /*
238  // This won't work as expected if the same pointer
239  // points to different planets
240  if ( planet == d->m_planet ) {
241  return;
242  }
243  */
244 
245  const Planet *previousPlanet = d->m_planet;
246 
247  mDebug() << "SunLocator::setPlanet(Planet*)";
248  d->m_planet = planet;
249  updatePosition();
250 
251  // Initially there might be no planet set.
252  // In that case we don't want an update.
253  // Update the shading in all other cases.
254  if ( !previousPlanet->id().isEmpty() ) {
255  emit positionChanged( getLon(), getLat() );
256  }
257 }
258 
259 qreal SunLocator::getLon() const
260 {
261  return d->m_lon * RAD2DEG;
262 }
263 
264 qreal SunLocator::getLat() const
265 {
266  return d->m_lat * RAD2DEG;
267 }
268 
269 }
270 
271 #include "SunLocator.moc"
Marble::RAD2DEG
const qreal RAD2DEG
Definition: MarbleGlobal.h:201
Marble::Planet::id
QString id() const
The internal, nonlocalized name of the planet.
Definition: Planet.cpp:262
Marble::update_interval
const int update_interval
Definition: SunLocator.cpp:49
MarbleMath.h
Marble::SunLocator::update
void update()
Definition: SunLocator.cpp:228
Marble::J2000
const int J2000
Definition: SunLocator.cpp:41
SunLocator.h
Planet.h
QObject
MarbleDebug.h
M_PI
#define M_PI
Definition: SunLocator.cpp:28
Marble::SunLocator::getLat
qreal getLat() const
Definition: SunLocator.cpp:264
Marble::Planet
Definition: Planet.h:25
Marble::MOON_SYNODIC_PERIOD
const qreal MOON_SYNODIC_PERIOD
Definition: SunLocator.cpp:46
Marble::SunLocator::setPlanet
void setPlanet(const Planet *planet)
Definition: SunLocator.cpp:235
Marble::SunLocator::shading
qreal shading(qreal lon, qreal a, qreal c) const
Definition: SunLocator.cpp:146
MarbleGlobal.h
abs
double abs(const Vec3 &c)
Definition: attlib.cpp:101
Marble::MOON_EPOCH
const qreal MOON_EPOCH
Definition: SunLocator.cpp:45
MarbleClock.h
Marble::SunLocator::getLon
qreal getLon() const
Definition: SunLocator.cpp:259
Marble::SunLocator::shadePixelComposite
void shadePixelComposite(QRgb &pixcol, const QRgb &dpixcol, qreal shade) const
Definition: SunLocator.cpp:200
Marble::SunLocator::shadePixel
void shadePixel(QRgb &pixcol, qreal shade) const
Definition: SunLocator.cpp:178
Marble::SunLocator::SunLocator
SunLocator(const MarbleClock *clock, const Planet *planet)
Definition: SunLocator.cpp:70
Marble::SunLocator::~SunLocator
virtual ~SunLocator()
Definition: SunLocator.cpp:76
Marble::SunLocator::positionChanged
void positionChanged(qreal lon, qreal lat)
Marble::MarbleClock
Definition: MarbleClock.h:25
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • 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