1 /***************************************************************************
2 ksplanet.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 ***************************************************************************/
23 #include "ksnumbers.h"
25 #include "ksfilereader.h"
27 KSPlanet::OrbitDataManager
KSPlanet::odm
;
29 KSPlanet::OrbitDataColl::OrbitDataColl() {
31 for (int i
=0; i
<6; i
++) {
32 Lon
[i
].setAutoDelete(true);
33 Lat
[i
].setAutoDelete(true);
34 Dst
[i
].setAutoDelete(true);
39 KSPlanet::OrbitDataManager::OrbitDataManager() : dict(31, true) {
40 // delete all data automatically to avoid a leak
41 dict
.setAutoDelete(true);
44 bool KSPlanet::OrbitDataManager::readOrbitData(QString fname
,
45 QPtrVector
<KSPlanet::OrbitData
> *vector
) {
50 QPtrList
<OrbitData
> DData
;
52 if ( KSUtils::openDataFile( f
, fname
) ) {
53 KSFileReader
fileReader( f
); // close file is included
54 while ( fileReader
.hasMoreLines() ) {
55 line
= fileReader
.readLine();
56 QTextIStream
instream( &line
);
57 instream
>> A
>> B
>> C
;
58 DData
.append(new OrbitData(A
, B
, C
));
62 QTextStream stream( &f );
63 while ( !stream.eof() ) {
64 line = stream.readLine();
65 QTextIStream instream( &line );
66 instream >> A >> B >> C;
67 DData.append(new OrbitData(A, B, C));
76 DData
.toVector(vector
);
81 KSPlanet::OrbitDataColl
*KSPlanet::OrbitDataManager::loadData(QString n
) {
82 QString fname
, snum
, line
;
87 // kdDebug() << k_funcinfo << " Loading data named " << n << endl;
91 if ((ret
= dict
[n
])) {
92 // kdDebug() << k_funcinfo << " already loaded - returning" << endl;
96 ret
= new OrbitDataColl
;
99 for (int i
=0; i
<6; ++i
) {
101 fname
= n
+ ".L" + snum
+ ".vsop";
102 if (readOrbitData(fname
, &(ret
->Lon
[i
])))
106 if ( nCount
==0 ){ //No longitude data found!
112 for (int i
=0; i
<6; ++i
) {
114 fname
= n
+ ".B" + snum
+ ".vsop";
115 if (readOrbitData(fname
, &(ret
->Lat
[i
])))
120 if (nCount
==0){ //no latitude data found!
125 //Heliocentric Distance
126 for (int i
=0; i
<6; ++i
) {
128 fname
= n
+ ".R" + snum
+ ".vsop";
129 if (readOrbitData(fname
, &(ret
->Dst
[i
])))
134 if (nCount
==0){ //no distance data found!
142 // kdDebug() << k_funcinfo << " successful load" << endl;
147 KSPlanet::KSPlanet( KStarsData
*kd
, QString s
, QString imfile
, double pSize
)
148 : KSPlanetBase(kd
, s
, imfile
, pSize
), data_loaded(false) {
151 bool KSPlanet::loadData() {
152 return (odm
.loadData(name()) != 0);
155 void KSPlanet::calcEcliptic(double Tau
, EclipticPosition
&epret
) const {
161 for (int i
=1; i
<6; ++i
) {
162 Tpow
[i
] = Tpow
[i
-1] * Tau
;
165 if (!(odc
= odm
.loadData(name()))) {
166 epret
.longitude
= 0.0;
167 epret
.latitude
= 0.0;
169 kdError() << "Could not get data for '" << name() << "'" << endl
;
174 for (int i
=0; i
<6; ++i
) {
176 for (uint j
= 0; j
< odc
->Lon
[i
].size(); ++j
) {
177 sum
[i
] += odc
->Lon
[i
][j
]->A
* cos( odc
->Lon
[i
][j
]->B
+ odc
->Lon
[i
][j
]->C
*Tau
);
179 kdDebug() << "sum[" << i <<"] =" << sum[i] <<
180 " A = " << odc->Lon[i][j]->A << " B = " << odc->Lon[i][j]->B <<
181 " C = " << odc->Lon[i][j]->C << endl;
185 //kdDebug() << name() << " : sum[" << i << "] = " << sum[i] <<endl;
188 epret
.longitude
.setRadians( sum
[0] + sum
[1] + sum
[2] + sum
[3] + sum
[4] + sum
[5] );
189 epret
.longitude
.setD( epret
.longitude
.reduce().Degrees() );
191 //Compute Ecliptic Latitude
192 for (uint i
=0; i
<6; ++i
) {
194 for (uint j
= 0; j
< odc
->Lat
[i
].size(); ++j
) {
195 sum
[i
] += odc
->Lat
[i
][j
]->A
* cos( odc
->Lat
[i
][j
]->B
+ odc
->Lat
[i
][j
]->C
*Tau
);
201 epret
.latitude
.setRadians( sum
[0] + sum
[1] + sum
[2] + sum
[3] + sum
[4] + sum
[5] );
203 //Compute Heliocentric Distance
204 for (uint i
=0; i
<6; ++i
) {
206 for (uint j
= 0; j
< odc
->Dst
[i
].size(); ++j
) {
207 sum
[i
] += odc
->Dst
[i
][j
]->A
* cos( odc
->Dst
[i
][j
]->B
+ odc
->Dst
[i
][j
]->C
*Tau
);
212 epret
.radius
= sum
[0] + sum
[1] + sum
[2] + sum
[3] + sum
[4] + sum
[5];
215 kdDebug() << name() << " pre: Lat = " << epret.latitude.toDMSString() << " Long = " <<
216 epret.longitude.toDMSString() << " Dist = " << epret.radius << endl;
221 bool KSPlanet::findGeocentricPosition( const KSNumbers
*num
, const KSPlanetBase
*Earth
) {
223 if ( Earth
!= NULL
) {
224 double sinL
, sinL0
, sinB
, sinB0
;
225 double cosL
, cosL0
, cosB
, cosB0
;
226 double x
= 0.0, y
= 0.0, z
= 0.0;
228 double olddst
= -1000;
231 EclipticPosition trialpos
;
233 double jm
= num
->julianMillenia();
235 Earth
->ecLong()->SinCos( sinL0
, cosL0
);
236 Earth
->ecLat()->SinCos( sinB0
, cosB0
);
238 double eX
= Earth
->rsun()*cosB0
*cosL0
;
239 double eY
= Earth
->rsun()*cosB0
*sinL0
;
240 double eZ
= Earth
->rsun()*sinB0
;
243 while (fabs(dst
- olddst
) > .001) {
244 calcEcliptic(jm
, trialpos
);
246 // We store the heliocentric ecliptic coordinates the first time they are computed.
254 trialpos
.longitude
.SinCos( sinL
, cosL
);
255 trialpos
.latitude
.SinCos( sinB
, cosB
);
257 x
= trialpos
.radius
*cosB
*cosL
- eX
;
258 y
= trialpos
.radius
*cosB
*sinL
- eY
;
259 z
= trialpos
.radius
*sinB
- eZ
;
261 //distance from Earth
262 dst
= sqrt(x
*x
+ y
*y
+ z
*z
);
264 double delay
= (.0057755183 * dst
) / 365250.0;
266 jm
= num
->julianMillenia() - delay
;
270 ep
.longitude
.setRadians( atan( y
/x
) );
271 if (x
<0) ep
.longitude
.setD( ep
.longitude
.Degrees() + 180.0 ); //resolve atan ambiguity
272 ep
.latitude
.setRadians( atan( z
/( sqrt( x
*x
+ y
*y
) ) ) );
273 setRsun( trialpos
.radius
);
276 EclipticToEquatorial( num
->obliquity() );
283 calcEcliptic(num
->julianMillenia(), ep
);
287 //determine the position angle