1 /***************************************************************************
2 ksplanetbase.cpp - K Desktop Planetarium
4 begin : Sun Jul 22 2001
5 copyright : (C) 2001 by Jason Harris
6 email : jharris@30doradus.org
7 ***************************************************************************/
9 /***************************************************************************
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. *
16 ***************************************************************************/
24 #include "ksplanetbase.h"
26 #include "kstarsdata.h"
28 #include "ksnumbers.h"
29 #include "kspopupmenu.h"
32 KSPlanetBase::KSPlanetBase( KStarsData
*kd
, QString s
, QString image_file
, double pSize
)
33 : SkyObject( 2, 0.0, 0.0, 0.0, s
, "" ), Rearth(0.0), Image(0), data(kd
) {
35 if (! image_file
.isEmpty()) {
38 if ( KSUtils::openDataFile( imFile
, image_file
) ) {
40 Image0
.load( imFile
.name() );
41 Image
= Image0
.convertDepth( 32 );
48 Trail
.setAutoDelete( TRUE
);
51 void KSPlanetBase::EquatorialToEcliptic( const dms
*Obliquity
) {
52 findEcliptic( Obliquity
, ep
.longitude
, ep
.latitude
);
55 void KSPlanetBase::EclipticToEquatorial( const dms
*Obliquity
) {
56 setFromEcliptic( Obliquity
, &ep
.longitude
, &ep
.latitude
);
59 void KSPlanetBase::updateCoords( KSNumbers
*num
, bool includePlanets
, const dms
*lat
, const dms
*LST
){
60 if ( includePlanets
) {
61 data
->earth()->findPosition( num
); //since we don't pass lat & LST, localizeCoords will be skipped
64 findPosition( num
, lat
, LST
, data
->earth() );
65 if ( hasTrail() ) Trail
.removeLast();
67 findGeocentricPosition( num
, data
->earth() );
72 void KSPlanetBase::findPosition( const KSNumbers
*num
, const dms
*lat
, const dms
*LST
, const KSPlanetBase
*Earth
) {
73 findGeocentricPosition( num
, Earth
); //private function, reimplemented in each subclass
75 if ( Earth
) setRearth( Earth
);
78 localizeCoords( num
, lat
, LST
); //correct for figure-of-the-Earth
81 Trail
.append( new SkyPoint( ra(), dec() ) );
82 if ( Trail
.count() > MAXTRAIL
) Trail
.removeFirst();
85 if ( isMajorPlanet() )
89 bool KSPlanetBase::isMajorPlanet() const {
90 if ( name() == "Mercury" || name() == "Venus" || name() == "Mars" ||
91 name() == "Jupiter" || name() == "Saturn" || name() == "Uranus" ||
92 name() == "Neptune" || name() == "Pluto" )
98 void KSPlanetBase::localizeCoords( const KSNumbers
*num
, const dms
*lat
, const dms
*LST
) {
99 //convert geocentric coordinates to local apparent coordinates (topocentric coordinates)
100 dms HA
, HA2
; //Hour Angle, before and after correction
101 double rsinp
, rcosp
, u
, sinHA
, cosHA
, sinDec
, cosDec
, D
;
103 double r
= Rearth
* AU_KM
; //distance from Earth, in km
104 u
= atan( 0.996647*tan( lat
->radians() ) );
105 rsinp
= 0.996647*sin( u
);
107 HA
.setD( LST
->Degrees() - ra()->Degrees() );
108 HA
.SinCos( sinHA
, cosHA
);
109 dec()->SinCos( sinDec
, cosDec
);
111 D
= atan( ( rcosp
*sinHA
)/( r
*cosDec
/6378.14 - rcosp
*cosHA
) );
113 temp
.setRadians( ra()->radians() - D
);
116 HA2
.setD( LST
->Degrees() - ra()->Degrees() );
117 cosHA2
= cos( HA2
.radians() );
118 temp
.setRadians( atan( cosHA2
*( r
*sinDec
/6378.14 - rsinp
)/( r
*cosDec
*cosHA
/6378.14 - rcosp
) ) );
121 EquatorialToEcliptic( num
->obliquity() );
124 void KSPlanetBase::setRearth( const KSPlanetBase
*Earth
) {
125 double sinL
, sinB
, sinL0
, sinB0
;
126 double cosL
, cosB
, cosL0
, cosB0
;
129 //The Moon's Rearth is set in its findGeocentricPosition()...
130 if ( name() == "Moon" ) {
134 if ( name() == "Earth" ) {
139 if ( ! Earth
&& name() != "Moon" ) {
140 kdDebug() << i18n( "KSPlanetBase::setRearth(): Error: Need an Earth pointer. (" ) << name() << ")" << endl
;
145 Earth
->ecLong()->SinCos( sinL0
, cosL0
);
146 Earth
->ecLat()->SinCos( sinB0
, cosB0
);
147 double eX
= Earth
->rsun()*cosB0
*cosL0
;
148 double eY
= Earth
->rsun()*cosB0
*sinL0
;
149 double eZ
= Earth
->rsun()*sinB0
;
151 ecLong()->SinCos( sinL
, cosL
);
152 ecLat()->SinCos( sinB
, cosB
);
153 x
= rsun()*cosB
*cosL
- eX
;
154 y
= rsun()*cosB
*sinL
- eY
;
155 z
= rsun()*sinB
- eZ
;
157 Rearth
= sqrt(x
*x
+ y
*y
+ z
*z
);
159 //Set angular size, in arcmin
160 AngularSize
= asin(PhysicalSize
/Rearth
/AU_KM
)*60.*180./dms::PI
;
163 void KSPlanetBase::updateTrail( dms
*LST
, const dms
*lat
) {
164 for ( SkyPoint
*sp
= Trail
.first(); sp
; sp
= Trail
.next() )
165 sp
->EquatorialToHorizontal( LST
, lat
);
168 void KSPlanetBase::findPA( const KSNumbers
*num
) {
169 //Determine position angle of planet (assuming that it is aligned with
170 //the Ecliptic, which is only roughly correct).
171 //Displace a point along +Ecliptic Latitude by 1 degree
173 dms
newELat( ecLat()->Degrees() + 1.0 );
174 test
.setFromEcliptic( num
->obliquity(), ecLong(), &newELat
);
175 double dx
= test
.ra()->Degrees() - ra()->Degrees();
176 double dy
= dec()->Degrees() - test
.dec()->Degrees();
179 pa
= atan( dx
/dy
)*180.0/dms::PI
;
182 if ( dx
> 0 ) pa
= -90.0;
187 void KSPlanetBase::rotateImage( double imAngle
) {
188 ImageAngle
= imAngle
;
190 m
.rotate( ImageAngle
);
191 Image
= Image0
.xForm( m
);
194 void KSPlanetBase::scaleRotateImage( int scale
, double imAngle
) {
195 ImageAngle
= imAngle
;
197 m
.rotate( ImageAngle
);
198 Image
= Image0
.xForm( m
).smoothScale( scale
, scale
);
201 void KSPlanetBase::findMagnitude(const KSNumbers
*num
) {
203 double cosDec
, sinDec
;
204 dec()->SinCos(cosDec
, sinDec
);
206 // I would rather like to obtain the Earth Sun distance rather than assigning it
207 // by hand..... Still TODO
208 // double earthSun = Earth->rsun();
209 double earthSun
= 1.;
211 /* Phase of the planet in degrees */
213 double cosPhase
= (rsun()*rsun() + rearth()*rearth() - earthSun
*earthSun
) / (2 * rsun() * rearth() );
214 double phase
= acos ( cosPhase
) * dms::PI
/ 180.;
216 /* Computation of the visual magnitude (V band) of the planet.
217 * Algorithm provided by Pere Planesas (Observatorio Astronomico Nacional)
218 * It has some simmilarity to J. Meeus algorithm in Astronomical Algorithms, Chapter 40.
221 // Initialized to the faintest magnitude observable with the HST
222 float magnitude
= 30;
224 double param
= 5 * log10(rsun() * rearth() );
225 double f1
= phase
/100.;
226 if ( name() == "Mercury" ) {
229 magnitude
= -0.36 + param
+ 3.8*f1
- 2.73*f1
*f1
+ 2*f1
*f1
*f1
;
231 if ( name() =="Venus")
232 magnitude
= -4.29 + param
+ 0.09*f1
+ 2.39*f1
*f1
- 0.65*f1
*f1
*f1
;
233 if( name() == "Mars")
234 magnitude
= -1.52 + param
+ 0.016*phase
;
235 if( name() == "Jupiter")
236 magnitude
= -9.25 + param
+ 0.005*phase
;
238 if( name() == "Saturn") {
239 double T
= num
->julianCenturies();
240 double a0
= (40.66-4.695*T
)* dms::PI
/ 180.;
241 double d0
= (83.52+0.403*T
)* dms::PI
/ 180.;
242 double sinx
= -cos(d0
)*cosDec
*cos(a0
- ra()->radians());
243 sinx
= fabs(sinx
-sin(d0
)*sinDec
);
244 double rings
= -2.6*sinx
+ 1.25*sinx
*sinx
;
245 magnitude
= -8.88 + param
+ 0.044*phase
+ rings
;
248 if( name() == "Uranus")
249 magnitude
= -7.19 + param
+ 0.0028*phase
;
250 if( name() == "Neptune")
251 magnitude
= -6.87 + param
;
252 if( name() == "Pluto")
253 magnitude
= -1.01 + param
+ 0.041*phase
;