summaryrefslogtreecommitdiffstats
path: root/kstars/kstars/ksplanetbase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kstars/kstars/ksplanetbase.cpp')
-rw-r--r--kstars/kstars/ksplanetbase.cpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/kstars/kstars/ksplanetbase.cpp b/kstars/kstars/ksplanetbase.cpp
new file mode 100644
index 00000000..4eb92f03
--- /dev/null
+++ b/kstars/kstars/ksplanetbase.cpp
@@ -0,0 +1,251 @@
+/***************************************************************************
+ ksplanetbase.cpp - K Desktop Planetarium
+ -------------------
+ begin : Sun Jul 22 2001
+ copyright : (C) 2001 by Jason Harris
+ email : jharris@30doradus.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <math.h>
+
+#include <qfile.h>
+#include <qpoint.h>
+#include <qwmatrix.h>
+
+#include "ksplanetbase.h"
+#include "ksplanet.h"
+#include "kstarsdata.h"
+#include "ksutils.h"
+#include "ksnumbers.h"
+#include "kspopupmenu.h"
+
+
+KSPlanetBase::KSPlanetBase( KStarsData *kd, QString s, QString image_file, double pSize )
+ : SkyObject( 2, 0.0, 0.0, 0.0, s, "" ), Rearth(0.0), Image(0), data(kd) {
+
+ if (! image_file.isEmpty()) {
+ QFile imFile;
+
+ if ( KSUtils::openDataFile( imFile, image_file ) ) {
+ imFile.close();
+ Image0.load( imFile.name() );
+ Image = Image0.convertDepth( 32 );
+ Image0 = Image;
+ }
+ }
+ PositionAngle = 0.0;
+ ImageAngle = 0.0;
+ PhysicalSize = pSize;
+ Trail.setAutoDelete( TRUE );
+}
+
+void KSPlanetBase::EquatorialToEcliptic( const dms *Obliquity ) {
+ findEcliptic( Obliquity, ep.longitude, ep.latitude );
+}
+
+void KSPlanetBase::EclipticToEquatorial( const dms *Obliquity ) {
+ setFromEcliptic( Obliquity, &ep.longitude, &ep.latitude );
+}
+
+void KSPlanetBase::updateCoords( KSNumbers *num, bool includePlanets, const dms *lat, const dms *LST ){
+ if ( includePlanets ) {
+ data->earth()->findPosition( num ); //since we don't pass lat & LST, localizeCoords will be skipped
+
+ if ( lat && LST ) {
+ findPosition( num, lat, LST, data->earth() );
+ if ( hasTrail() ) Trail.removeLast();
+ } else {
+ findGeocentricPosition( num, data->earth() );
+ }
+ }
+}
+
+void KSPlanetBase::findPosition( const KSNumbers *num, const dms *lat, const dms *LST, const KSPlanetBase *Earth ) {
+ findGeocentricPosition( num, Earth ); //private function, reimplemented in each subclass
+
+ if ( Earth ) setRearth( Earth );
+
+ if ( lat && LST )
+ localizeCoords( num, lat, LST ); //correct for figure-of-the-Earth
+
+ if ( hasTrail() ) {
+ Trail.append( new SkyPoint( ra(), dec() ) );
+ if ( Trail.count() > MAXTRAIL ) Trail.removeFirst();
+ }
+
+ if ( isMajorPlanet() )
+ findMagnitude(num);
+}
+
+bool KSPlanetBase::isMajorPlanet() const {
+ if ( name() == "Mercury" || name() == "Venus" || name() == "Mars" ||
+ name() == "Jupiter" || name() == "Saturn" || name() == "Uranus" ||
+ name() == "Neptune" || name() == "Pluto" )
+ return true;
+ return false;
+}
+
+void KSPlanetBase::localizeCoords( const KSNumbers *num, const dms *lat, const dms *LST ) {
+ //convert geocentric coordinates to local apparent coordinates (topocentric coordinates)
+ dms HA, HA2; //Hour Angle, before and after correction
+ double rsinp, rcosp, u, sinHA, cosHA, sinDec, cosDec, D;
+ double cosHA2;
+ double r = Rearth * AU_KM; //distance from Earth, in km
+ u = atan( 0.996647*tan( lat->radians() ) );
+ rsinp = 0.996647*sin( u );
+ rcosp = cos( u );
+ HA.setD( LST->Degrees() - ra()->Degrees() );
+ HA.SinCos( sinHA, cosHA );
+ dec()->SinCos( sinDec, cosDec );
+
+ D = atan( ( rcosp*sinHA )/( r*cosDec/6378.14 - rcosp*cosHA ) );
+ dms temp;
+ temp.setRadians( ra()->radians() - D );
+ setRA( temp );
+
+ HA2.setD( LST->Degrees() - ra()->Degrees() );
+ cosHA2 = cos( HA2.radians() );
+ temp.setRadians( atan( cosHA2*( r*sinDec/6378.14 - rsinp )/( r*cosDec*cosHA/6378.14 - rcosp ) ) );
+ setDec( temp );
+
+ EquatorialToEcliptic( num->obliquity() );
+}
+
+void KSPlanetBase::setRearth( const KSPlanetBase *Earth ) {
+ double sinL, sinB, sinL0, sinB0;
+ double cosL, cosB, cosL0, cosB0;
+ double x,y,z;
+
+ //The Moon's Rearth is set in its findGeocentricPosition()...
+ if ( name() == "Moon" ) {
+ return;
+ }
+
+ if ( name() == "Earth" ) {
+ Rearth = 0.0;
+ return;
+ }
+
+ if ( ! Earth && name() != "Moon" ) {
+ kdDebug() << i18n( "KSPlanetBase::setRearth(): Error: Need an Earth pointer. (" ) << name() << ")" << endl;
+ Rearth = 1.0;
+ return;
+ }
+
+ Earth->ecLong()->SinCos( sinL0, cosL0 );
+ Earth->ecLat()->SinCos( sinB0, cosB0 );
+ double eX = Earth->rsun()*cosB0*cosL0;
+ double eY = Earth->rsun()*cosB0*sinL0;
+ double eZ = Earth->rsun()*sinB0;
+
+ helEcLong()->SinCos( sinL, cosL );
+ helEcLat()->SinCos( sinB, cosB );
+ x = rsun()*cosB*cosL - eX;
+ y = rsun()*cosB*sinL - eY;
+ z = rsun()*sinB - eZ;
+
+ Rearth = sqrt(x*x + y*y + z*z);
+
+ //Set angular size, in arcmin
+ AngularSize = asin(PhysicalSize/Rearth/AU_KM)*60.*180./dms::PI;
+}
+
+void KSPlanetBase::updateTrail( dms *LST, const dms *lat ) {
+ for ( SkyPoint *sp = Trail.first(); sp; sp = Trail.next() )
+ sp->EquatorialToHorizontal( LST, lat );
+}
+
+void KSPlanetBase::findPA( const KSNumbers *num ) {
+ //Determine position angle of planet (assuming that it is aligned with
+ //the Ecliptic, which is only roughly correct).
+ //Displace a point along +Ecliptic Latitude by 1 degree
+ SkyPoint test;
+ dms newELat( ecLat()->Degrees() + 1.0 );
+ test.setFromEcliptic( num->obliquity(), ecLong(), &newELat );
+ double dx = test.ra()->Degrees() - ra()->Degrees();
+ double dy = dec()->Degrees() - test.dec()->Degrees();
+ double pa;
+ if ( dy ) {
+ pa = atan( dx/dy )*180.0/dms::PI;
+ } else {
+ pa = 90.0;
+ if ( dx > 0 ) pa = -90.0;
+ }
+ setPA( pa );
+}
+
+void KSPlanetBase::rotateImage( double imAngle ) {
+ ImageAngle = imAngle;
+ QWMatrix m;
+ m.rotate( ImageAngle );
+ Image = Image0.xForm( m );
+}
+
+void KSPlanetBase::scaleRotateImage( int scale, double imAngle ) {
+ ImageAngle = imAngle;
+ QWMatrix m;
+ m.rotate( ImageAngle );
+ Image = Image0.xForm( m ).smoothScale( scale, scale );
+}
+
+void KSPlanetBase::findMagnitude(const KSNumbers *num) {
+
+ double cosDec, sinDec;
+ dec()->SinCos(cosDec, sinDec);
+
+ /* Phase of the planet in degrees */
+ double earthSun = 1.;
+ double cosPhase = (rsun()*rsun() + rearth()*rearth() - earthSun*earthSun)
+ / (2 * rsun() * rearth() );
+ double phase = acos ( cosPhase ) * 180.0 / dms::PI;
+
+ /* Computation of the visual magnitude (V band) of the planet.
+ * Algorithm provided by Pere Planesas (Observatorio Astronomico Nacional)
+ * It has some simmilarity to J. Meeus algorithm in Astronomical Algorithms, Chapter 40.
+ * */
+
+ // Initialized to the faintest magnitude observable with the HST
+ float magnitude = 30;
+
+ double param = 5 * log10(rsun() * rearth() );
+ double f1 = phase/100.;
+
+ if ( name() == "Mercury" ) {
+ if ( phase > 150. ) f1 = 1.5;
+ magnitude = -0.36 + param + 3.8*f1 - 2.73*f1*f1 + 2*f1*f1*f1;
+ }
+ if ( name() =="Venus")
+ magnitude = -4.29 + param + 0.09*f1 + 2.39*f1*f1 - 0.65*f1*f1*f1;
+ if( name() == "Mars")
+ magnitude = -1.52 + param + 0.016*phase;
+ if( name() == "Jupiter")
+ magnitude = -9.25 + param + 0.005*phase;
+
+ if( name() == "Saturn") {
+ double T = num->julianCenturies();
+ double a0 = (40.66-4.695*T)* dms::PI / 180.;
+ double d0 = (83.52+0.403*T)* dms::PI / 180.;
+ double sinx = -cos(d0)*cosDec*cos(a0 - ra()->radians());
+ sinx = fabs(sinx-sin(d0)*sinDec);
+ double rings = -2.6*sinx + 1.25*sinx*sinx;
+ magnitude = -8.88 + param + 0.044*phase + rings;
+ }
+
+ if( name() == "Uranus")
+ magnitude = -7.19 + param + 0.0028*phase;
+ if( name() == "Neptune")
+ magnitude = -6.87 + param;
+ if( name() == "Pluto" )
+ magnitude = -1.01 + param + 0.041*phase;
+
+ setMag(magnitude);
+}