00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019
00020 #include <qfile.h>
00021 #include <qpoint.h>
00022 #include <qwmatrix.h>
00023
00024 #include "ksplanetbase.h"
00025 #include "ksplanet.h"
00026 #include "kstarsdata.h"
00027 #include "ksutils.h"
00028 #include "ksnumbers.h"
00029 #include "kspopupmenu.h"
00030
00031
00032 KSPlanetBase::KSPlanetBase( KStarsData *kd, QString s, QString image_file, double pSize )
00033 : SkyObject( 2, 0.0, 0.0, 0.0, s, "" ), Rearth(0.0), Image(0), data(kd) {
00034
00035 if (! image_file.isEmpty()) {
00036 QFile imFile;
00037
00038 if ( KSUtils::openDataFile( imFile, image_file ) ) {
00039 imFile.close();
00040 Image0.load( imFile.name() );
00041 Image = Image0.convertDepth( 32 );
00042 Image0 = Image;
00043 }
00044 }
00045 PositionAngle = 0.0;
00046 ImageAngle = 0.0;
00047 PhysicalSize = pSize;
00048 Trail.setAutoDelete( TRUE );
00049 }
00050
00051 void KSPlanetBase::EquatorialToEcliptic( const dms *Obliquity ) {
00052 findEcliptic( Obliquity, ep.longitude, ep.latitude );
00053 }
00054
00055 void KSPlanetBase::EclipticToEquatorial( const dms *Obliquity ) {
00056 setFromEcliptic( Obliquity, &ep.longitude, &ep.latitude );
00057 }
00058
00059 void KSPlanetBase::updateCoords( KSNumbers *num, bool includePlanets, const dms *lat, const dms *LST ){
00060 if ( includePlanets ) {
00061 data->earth()->findPosition( num );
00062
00063 if ( lat && LST ) {
00064 findPosition( num, lat, LST, data->earth() );
00065 if ( hasTrail() ) Trail.removeLast();
00066 } else {
00067 findGeocentricPosition( num, data->earth() );
00068 }
00069 }
00070 }
00071
00072 void KSPlanetBase::findPosition( const KSNumbers *num, const dms *lat, const dms *LST, const KSPlanetBase *Earth ) {
00073 findGeocentricPosition( num, Earth );
00074
00075 if ( Earth ) setRearth( Earth );
00076
00077 if ( lat && LST )
00078 localizeCoords( num, lat, LST );
00079
00080 if ( hasTrail() ) {
00081 Trail.append( new SkyPoint( ra(), dec() ) );
00082 if ( Trail.count() > MAXTRAIL ) Trail.removeFirst();
00083 }
00084
00085 if ( isMajorPlanet() )
00086 findMagnitude(num);
00087 }
00088
00089 bool KSPlanetBase::isMajorPlanet() const {
00090 if ( name() == "Mercury" || name() == "Venus" || name() == "Mars" ||
00091 name() == "Jupiter" || name() == "Saturn" || name() == "Uranus" ||
00092 name() == "Neptune" || name() == "Pluto" )
00093 return true;
00094 return false;
00095 }
00096
00097 void KSPlanetBase::localizeCoords( const KSNumbers *num, const dms *lat, const dms *LST ) {
00098
00099 dms HA, HA2;
00100 double rsinp, rcosp, u, sinHA, cosHA, sinDec, cosDec, D;
00101 double cosHA2;
00102 double r = Rearth * AU_KM;
00103 u = atan( 0.996647*tan( lat->radians() ) );
00104 rsinp = 0.996647*sin( u );
00105 rcosp = cos( u );
00106 HA.setD( LST->Degrees() - ra()->Degrees() );
00107 HA.SinCos( sinHA, cosHA );
00108 dec()->SinCos( sinDec, cosDec );
00109
00110 D = atan( ( rcosp*sinHA )/( r*cosDec/6378.14 - rcosp*cosHA ) );
00111 dms temp;
00112 temp.setRadians( ra()->radians() - D );
00113 setRA( temp );
00114
00115 HA2.setD( LST->Degrees() - ra()->Degrees() );
00116 cosHA2 = cos( HA2.radians() );
00117 temp.setRadians( atan( cosHA2*( r*sinDec/6378.14 - rsinp )/( r*cosDec*cosHA/6378.14 - rcosp ) ) );
00118 setDec( temp );
00119
00120 EquatorialToEcliptic( num->obliquity() );
00121 }
00122
00123 void KSPlanetBase::setRearth( const KSPlanetBase *Earth ) {
00124 double sinL, sinB, sinL0, sinB0;
00125 double cosL, cosB, cosL0, cosB0;
00126 double x,y,z;
00127
00128
00129 if ( name() == "Moon" ) {
00130 return;
00131 }
00132
00133 if ( name() == "Earth" ) {
00134 Rearth = 0.0;
00135 return;
00136 }
00137
00138 if ( ! Earth && name() != "Moon" ) {
00139 kdDebug() << i18n( "KSPlanetBase::setRearth(): Error: Need an Earth pointer. (" ) << name() << ")" << endl;
00140 Rearth = 1.0;
00141 return;
00142 }
00143
00144 Earth->ecLong()->SinCos( sinL0, cosL0 );
00145 Earth->ecLat()->SinCos( sinB0, cosB0 );
00146 double eX = Earth->rsun()*cosB0*cosL0;
00147 double eY = Earth->rsun()*cosB0*sinL0;
00148 double eZ = Earth->rsun()*sinB0;
00149
00150 helEcLong()->SinCos( sinL, cosL );
00151 helEcLat()->SinCos( sinB, cosB );
00152 x = rsun()*cosB*cosL - eX;
00153 y = rsun()*cosB*sinL - eY;
00154 z = rsun()*sinB - eZ;
00155
00156 Rearth = sqrt(x*x + y*y + z*z);
00157
00158
00159 AngularSize = asin(PhysicalSize/Rearth/AU_KM)*60.*180./dms::PI;
00160 }
00161
00162 void KSPlanetBase::updateTrail( dms *LST, const dms *lat ) {
00163 for ( SkyPoint *sp = Trail.first(); sp; sp = Trail.next() )
00164 sp->EquatorialToHorizontal( LST, lat );
00165 }
00166
00167 void KSPlanetBase::findPA( const KSNumbers *num ) {
00168
00169
00170
00171 SkyPoint test;
00172 dms newELat( ecLat()->Degrees() + 1.0 );
00173 test.setFromEcliptic( num->obliquity(), ecLong(), &newELat );
00174 double dx = test.ra()->Degrees() - ra()->Degrees();
00175 double dy = dec()->Degrees() - test.dec()->Degrees();
00176 double pa;
00177 if ( dy ) {
00178 pa = atan( dx/dy )*180.0/dms::PI;
00179 } else {
00180 pa = 90.0;
00181 if ( dx > 0 ) pa = -90.0;
00182 }
00183 setPA( pa );
00184 }
00185
00186 void KSPlanetBase::rotateImage( double imAngle ) {
00187 ImageAngle = imAngle;
00188 QWMatrix m;
00189 m.rotate( ImageAngle );
00190 Image = Image0.xForm( m );
00191 }
00192
00193 void KSPlanetBase::scaleRotateImage( int scale, double imAngle ) {
00194 ImageAngle = imAngle;
00195 QWMatrix m;
00196 m.rotate( ImageAngle );
00197 Image = Image0.xForm( m ).smoothScale( scale, scale );
00198 }
00199
00200 void KSPlanetBase::findMagnitude(const KSNumbers *num) {
00201
00202 double cosDec, sinDec;
00203 dec()->SinCos(cosDec, sinDec);
00204
00205
00206 double earthSun = 1.;
00207 double cosPhase = (rsun()*rsun() + rearth()*rearth() - earthSun*earthSun)
00208 / (2 * rsun() * rearth() );
00209 double phase = acos ( cosPhase ) * 180.0 / dms::PI;
00210
00211
00212
00213
00214
00215
00216
00217 float magnitude = 30;
00218
00219 double param = 5 * log10(rsun() * rearth() );
00220 double f1 = phase/100.;
00221
00222 if ( name() == "Mercury" ) {
00223 if ( phase > 150. ) f1 = 1.5;
00224 magnitude = -0.36 + param + 3.8*f1 - 2.73*f1*f1 + 2*f1*f1*f1;
00225 }
00226 if ( name() =="Venus")
00227 magnitude = -4.29 + param + 0.09*f1 + 2.39*f1*f1 - 0.65*f1*f1*f1;
00228 if( name() == "Mars")
00229 magnitude = -1.52 + param + 0.016*phase;
00230 if( name() == "Jupiter")
00231 magnitude = -9.25 + param + 0.005*phase;
00232
00233 if( name() == "Saturn") {
00234 double T = num->julianCenturies();
00235 double a0 = (40.66-4.695*T)* dms::PI / 180.;
00236 double d0 = (83.52+0.403*T)* dms::PI / 180.;
00237 double sinx = -cos(d0)*cosDec*cos(a0 - ra()->radians());
00238 sinx = fabs(sinx-sin(d0)*sinDec);
00239 double rings = -2.6*sinx + 1.25*sinx*sinx;
00240 magnitude = -8.88 + param + 0.044*phase + rings;
00241 }
00242
00243 if( name() == "Uranus")
00244 magnitude = -7.19 + param + 0.0028*phase;
00245 if( name() == "Neptune")
00246 magnitude = -6.87 + param;
00247 if( name() == "Pluto" )
00248 magnitude = -1.01 + param + 0.041*phase;
00249
00250 setMag(magnitude);
00251 }