diff --git a/src/lib/marble/Planet.cpp b/src/lib/marble/Planet.cpp index ec3d00275..9409f9be4 100644 --- a/src/lib/marble/Planet.cpp +++ b/src/lib/marble/Planet.cpp @@ -1,276 +1,301 @@ //Copyright 2009 Henry de Valence //Copyright 2009 David Roberts //Copyright 2012 Mohammed Nafees // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // #include "Planet.h" -#include - #include "PlanetFactory.h" #include "MarbleDebug.h" #include "MarbleGlobal.h" #include "MarbleColors.h" +#include "src/lib/astro/solarsystem.h" + +#include +#include + namespace Marble { class PlanetPrivate { public: qreal M_0, M_1; // for calculating mean anomaly qreal C_1, C_2, C_3, C_4, C_5, C_6; // for calculating equation of center qreal Pi; // ecliptic longitude of the perihelion qreal epsilon; // obliquity of the ecliptic plane qreal theta_0, theta_1; // for calculating sidereal time qreal radius; //in metres qreal twilightZone; QString name, id; //localized and nonlocalized names bool atmosphere; QColor atmosphereColor; PlanetPrivate() : M_0(0.0), M_1(0.0), C_1(0.0), C_2(0.0), C_3(0.0), C_4(0.0), C_5(0.0), C_6(0.0), Pi(0.0), epsilon(0.0), theta_0(0.0), theta_1(0.0), radius(10000000.0), twilightZone(0), name(), id(), atmosphere(false) { // nothing to do } }; //Constructor Planet::Planet() : d( new PlanetPrivate ) { // nothing to do } Planet::Planet( const QString& id ) : d( new PlanetPrivate ) { *this = PlanetFactory::construct( id ); } //Copy Constructor Planet::Planet( const Planet& other ) : d( new PlanetPrivate ) { // PlanetPrivate does not have pointer members, so we can just // use its (compiler generated) assignment operator. *d = *other.d; } //Destructor Planet::~Planet() { delete d; } /* Getter functions */ // for calculating mean anomaly qreal Planet::M_0() const { return d->M_0; } qreal Planet::M_1() const { return d->M_1; } // for calculating equation of center qreal Planet::C_1() const { return d->C_1; } qreal Planet::C_2() const { return d->C_2; } qreal Planet::C_3() const { return d->C_3; } qreal Planet::C_4() const { return d->C_4; } qreal Planet::C_5() const { return d->C_5; } qreal Planet::C_6() const { return d->C_6; } // ecliptic longitude of the perihelion qreal Planet::Pi() const { return d->Pi; } // obliquity of the ecliptic plane qreal Planet::epsilon() const { return d->epsilon; } // for calculating sidereal time qreal Planet::theta_0() const { return d->theta_0; } qreal Planet::theta_1() const { return d->theta_1; } // the radius of the planet, in metres qreal Planet::radius() const { return d->radius; } qreal Planet::twilightZone() const { return d->twilightZone; } QString Planet::name() const { return d->name; } QString Planet::id() const { return d->id; } +void Planet::sunPosition(qreal &lon, qreal &lat, const QDateTime &dateTime) const +{ + SolarSystem sys; + sys.setCurrentMJD( + dateTime.date().year(), dateTime.date().month(), dateTime.date().day(), + dateTime.time().hour(), dateTime.time().minute(), + (double)dateTime.time().second()); + const QString pname = d->id.at(0).toUpper() + d->id.right(d->id.size() - 1); + QByteArray name = pname.toLatin1(); + sys.setCentralBody( name.data() ); + + double ra = 0.0; + double decl = 0.0; + sys.getSun(ra, decl); + + double _lon = 0.0; + double _lat = 0.0; + sys.getPlanetographic(ra, decl, _lon, _lat); + + lon = _lon * DEG2RAD; + lat = _lat * DEG2RAD; +} /* Setter functions */ void Planet::setM_0( qreal M_0 ) { d->M_0 = M_0; } void Planet::setM_1( qreal M_1 ) { d->M_1 = M_1; } void Planet::setC_1( qreal C_1 ) { d->C_1 = C_1; } void Planet::setC_2( qreal C_2 ) { d->C_2 = C_2; } void Planet::setC_3( qreal C_3 ) { d->C_3 = C_3; } void Planet::setC_4( qreal C_4 ) { d->C_4 = C_4; } void Planet::setC_5( qreal C_5 ) { d->C_5 = C_5; } void Planet::setC_6( qreal C_6 ) { d->C_6 = C_6; } void Planet::setPi( qreal Pi ) { d->Pi = Pi; } void Planet::setEpsilon( qreal epsilon ) { d->epsilon = epsilon; } void Planet::setTheta_0( qreal theta_0 ) { d->theta_0 = theta_0; } void Planet::setTheta_1( qreal theta_1 ) { d->theta_1 = theta_1; } void Planet::setRadius( qreal radius ) { d->radius = radius; } void Planet::setTwilightZone(qreal twilightZone) { d->twilightZone = twilightZone; } void Planet::setName( const QString& name ) { d->name = name; } void Planet::setId( const QString& id ) { d->id = id; } QString Planet::name( const QString& id ) { return PlanetFactory::localizedName( id ); } QStringList Planet::planetList() { return PlanetFactory::planetList(); } Planet& Planet::operator=(const Planet& rhs) { // PlanetPrivate does not have pointer members, so we can just // use its (compiler generated) assignment operator. *d = *rhs.d; return *this; } bool Planet::hasAtmosphere() const { return d->atmosphere; } void Planet::setHasAtmosphere(bool enabled) { d->atmosphere = enabled; } QColor Planet::atmosphereColor() const { return d->atmosphereColor; } void Planet::setAtmosphereColor(const QColor &color) { d->atmosphereColor = color; } } //namespace Marble diff --git a/src/lib/marble/Planet.h b/src/lib/marble/Planet.h index 10dc58386..c49787715 100644 --- a/src/lib/marble/Planet.h +++ b/src/lib/marble/Planet.h @@ -1,132 +1,142 @@ // Copyright 2009 Henry de Valence // Copyright 2009 David Roberts // Copyright 2012 Mohammed Nafees // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // #ifndef MARBLE_PLANET_H #define MARBLE_PLANET_H #include "marble_export.h" #include +class QDateTime; class QStringList; class QColor; namespace Marble { class PlanetPrivate; class MARBLE_EXPORT Planet { //Not a QObject because we don't need sigs/slots public: /** Constructor to use for a custom planet * All of the orbital elements are left empty, so you can fill them in yourself. */ Planet(); /** * @deprecated Please use PlanetFactory::construct(id) instead. */ MARBLE_DEPRECATED explicit Planet(const QString& id); ///Copy Constructor Planet( const Planet& other ); ///Destructor ~Planet(); /* Getter functions */ /// for calculating mean anomaly qreal M_0() const; qreal M_1() const; /// for calculating equation of center qreal C_1() const; qreal C_2() const; qreal C_3() const; qreal C_4() const; qreal C_5() const; qreal C_6() const; /// ecliptic longitude of the perihelion qreal Pi() const; /// obliquity of the ecliptic plane qreal epsilon() const; /// for calculating sidereal time qreal theta_0() const; qreal theta_1() const; /// the radius of the planet, in metres qreal radius() const; /// the twilight zone of the planet, in radians qreal twilightZone() const; /** The user visible name of the planet */ QString name() const; /** The internal, nonlocalized name of the planet */ QString id() const; + /** + * Fills the longitude and latitude with the planet's sun position. + * + * @param lon the latitude of the sun, in radian + * @param lat the longitude of the sun, in radian + * @param dateTime the time for which the sun position is to be calculated + */ + void sunPosition(qreal &lon, qreal &lat, const QDateTime &dateTime) const; + /* Setter functions */ void setM_0( qreal M_0 ); void setM_1( qreal M_1 ); void setC_1( qreal C_1 ); void setC_2( qreal C_2 ); void setC_3( qreal C_3 ); void setC_4( qreal C_4 ); void setC_5( qreal C_5 ); void setC_6( qreal C_6 ); void setPi( qreal Pi ); void setEpsilon( qreal epsilon ); void setTheta_0( qreal theta_0 ); void setTheta_1( qreal theta_1 ); void setRadius( qreal radius ); void setTwilightZone(qreal twilightZone); void setName( const QString& name ); void setId( const QString& id ); Planet& operator=( const Planet& rhs ); /** * @deprecated Please use PlanetFactory::localizedName(id) instead. */ MARBLE_DEPRECATED static QString name(const QString& id); /** * @deprecated Please use PlanetFactory::planetList() instead. */ MARBLE_DEPRECATED static QStringList planetList(); bool hasAtmosphere() const; void setHasAtmosphere( bool enabled ); QColor atmosphereColor() const; void setAtmosphereColor( const QColor& color ); private: PlanetPrivate * const d; }; } //namespace Marble #endif diff --git a/src/lib/marble/SunLocator.cpp b/src/lib/marble/SunLocator.cpp index bf56ecadb..9dcffaa9f 100644 --- a/src/lib/marble/SunLocator.cpp +++ b/src/lib/marble/SunLocator.cpp @@ -1,217 +1,192 @@ // Copyright 2007-2009 David Roberts // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library. If not, see . #include "SunLocator.h" #include "MarbleGlobal.h" #include "MarbleClock.h" #include "Planet.h" #include "MarbleMath.h" #include "MarbleDebug.h" -#include "src/lib/astro/solarsystem.h" - #include #include // M_PI is sometimes defined in #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288419717 #endif namespace Marble { using std::sin; class SunLocatorPrivate { public: SunLocatorPrivate( const MarbleClock *clock, const Planet *planet ) : m_lon( 0.0 ), m_lat( 0.0 ), m_twilightZone(planet->twilightZone()), m_clock( clock ), m_planet( planet ) { + planet->sunPosition(m_lon, m_lat, clock->dateTime()); } qreal m_lon; qreal m_lat; qreal m_twilightZone; const MarbleClock *const m_clock; const Planet *m_planet; }; SunLocator::SunLocator( const MarbleClock *clock, const Planet *planet ) : QObject(), d( new SunLocatorPrivate( clock, planet )) { } SunLocator::~SunLocator() { delete d; } -void SunLocator::updatePosition() -{ - QString planetId = d->m_planet->id(); - SolarSystem sys; - - QDateTime dateTime = d->m_clock->dateTime(); - sys.setCurrentMJD( - dateTime.date().year(), dateTime.date().month(), dateTime.date().day(), - dateTime.time().hour(), dateTime.time().minute(), - (double)dateTime.time().second()); - QString const pname = planetId.at(0).toUpper() + planetId.right(planetId.size() - 1); - QByteArray name = pname.toLatin1(); - sys.setCentralBody( name.data() ); - - double ra = 0.0; - double decl = 0.0; - sys.getSun( ra, decl ); - double lon = 0.0; - double lat = 0.0; - sys.getPlanetographic (ra, decl, lon, lat); - d->m_lon = lon * DEG2RAD; - d->m_lat = lat * DEG2RAD; -} - qreal SunLocator::shading(qreal lon, qreal a, qreal c) const { // haversine formula qreal b = sin((lon-d->m_lon)/2.0); // qreal g = sin((lat-d->m_lat)/2.0); // qreal h = (g*g)+cos(lat)*cos(d->m_lat)*(b*b); qreal h = (a*a) + c * (b*b); /* h = 0.0 // directly beneath sun h = 0.5 // sunrise/sunset line h = 1.0 // opposite side of earth to the sun theta = 2*asin(sqrt(h)) */ qreal brightness; if ( h <= 0.5 - d->m_twilightZone / 2.0 ) brightness = 1.0; else if ( h >= 0.5 + d->m_twilightZone / 2.0 ) brightness = 0.0; else brightness = ( 0.5 + d->m_twilightZone/2.0 - h ) / d->m_twilightZone; return brightness; } void SunLocator::shadePixel(QRgb &pixcol, qreal brightness) { // daylight - no change if ( brightness > 0.99999 ) return; if ( brightness < 0.00001 ) { // night // Doing "pixcol = qRgb(r/2, g/2, b/2);" by shifting some electrons around ;) // by shifting some electrons around ;) pixcol = qRgb(qRed(pixcol) * 0.35, qGreen(pixcol) * 0.35, qBlue(pixcol) * 0.35); // pixcol = (pixcol & 0xff000000) | ((pixcol >> 1) & 0x7f7f7f); } else { // gradual shadowing int r = qRed( pixcol ); int g = qGreen( pixcol ); int b = qBlue( pixcol ); qreal d = 0.65 * brightness + 0.35; pixcol = qRgb((int)(d * r), (int)(d * g), (int)(d * b)); } } void SunLocator::shadePixelComposite(QRgb &pixcol, const QRgb &dpixcol, qreal brightness) { // daylight - no change if ( brightness > 0.99999 ) return; if ( brightness < 0.00001 ) { // night pixcol = dpixcol; } else { // gradual shadowing qreal& d = brightness; int r = qRed( pixcol ); int g = qGreen( pixcol ); int b = qBlue( pixcol ); int dr = qRed( dpixcol ); int dg = qGreen( dpixcol ); int db = qBlue( dpixcol ); pixcol = qRgb( (int)( d * r + (1 - d) * dr ), (int)( d * g + (1 - d) * dg ), (int)( d * b + (1 - d) * db ) ); } } void SunLocator::update() { - updatePosition(); + d->m_planet->sunPosition(d->m_lon, d->m_lat, d->m_clock->dateTime()); emit positionChanged( getLon(), getLat() ); } void SunLocator::setPlanet( const Planet *planet ) { /* // This won't work as expected if the same pointer // points to different planets if ( planet == d->m_planet ) { return; } */ const Planet *previousPlanet = d->m_planet; mDebug() << "SunLocator::setPlanet(Planet*)"; d->m_planet = planet; d->m_twilightZone = planet->twilightZone(); - updatePosition(); + planet->sunPosition(d->m_lon, d->m_lat, d->m_clock->dateTime()); // Initially there might be no planet set. // In that case we don't want an update. // Update the shading in all other cases. if ( !previousPlanet->id().isEmpty() ) { emit positionChanged( getLon(), getLat() ); } } qreal SunLocator::getLon() const { return d->m_lon * RAD2DEG; } qreal SunLocator::getLat() const { return d->m_lat * RAD2DEG; } } #include "moc_SunLocator.cpp" diff --git a/src/lib/marble/SunLocator.h b/src/lib/marble/SunLocator.h index d231d2a6a..54bead248 100644 --- a/src/lib/marble/SunLocator.h +++ b/src/lib/marble/SunLocator.h @@ -1,65 +1,63 @@ // Copyright 2007-2009 David Roberts // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library. If not, see . #ifndef MARBLE_SUNLOCATOR_H #define MARBLE_SUNLOCATOR_H #include #include //FIXME: This class shouldn't be exposed but is needed by the worldclock plasmoid #include "marble_export.h" namespace Marble { class MarbleClock; class SunLocatorPrivate; class Planet; class MARBLE_EXPORT SunLocator : public QObject { Q_OBJECT public: SunLocator( const MarbleClock *clock, const Planet *planet ); ~SunLocator() override; qreal shading(qreal lon, qreal a, qreal c) const; static void shadePixel(QRgb &pixcol, qreal shade); static void shadePixelComposite(QRgb &pixcol, const QRgb &dpixcol, qreal shade); void setPlanet( const Planet *planet ); qreal getLon() const; qreal getLat() const; public Q_SLOTS: void update(); Q_SIGNALS: void positionChanged( qreal lon, qreal lat ); private: - void updatePosition(); - SunLocatorPrivate * const d; Q_DISABLE_COPY( SunLocator ) }; } #endif