1 /***************************************************************************
2 kspluto.cpp - K Desktop Planetarium
4 begin : Mon Sep 24 2001
5 copyright : (C) 2001 by Jason Harris
6 email : kstars@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 ***************************************************************************/
25 #include "ksnumbers.h"
28 // There are systems that #define B0 as a special termios flag (for baud rate)
32 int KSPluto::DATAARRAYSIZE
= 106;
33 bool KSPluto::data_loaded
= false;
34 double *KSPluto::freq
= 0;
35 KSPluto::XYZData
*KSPluto::xdata
= 0;
36 KSPluto::XYZData
*KSPluto::ydata
= 0;
37 KSPluto::XYZData
*KSPluto::zdata
= 0;
38 int KSPluto::objects
= 0;
40 KSPluto::KSPluto(KStarsData
*kd
, QString fn
, double pSize
) : KSPlanetBase( kd
, I18N_NOOP( "Pluto" ), fn
, pSize
) {
46 // delete arrays if all other objects are closed
67 bool KSPluto::loadData() {
68 return loadData("pluto");
71 bool KSPluto::loadData(QString fn
) {
72 QString fname
, snum
, line
;
75 if (data_loaded
) return true;
77 // kdDebug() << "inside pluto loadData" << endl;
78 freq
= new double[DATAARRAYSIZE
];
79 xdata
= new XYZData
[DATAARRAYSIZE
];
80 ydata
= new XYZData
[DATAARRAYSIZE
];
81 zdata
= new XYZData
[DATAARRAYSIZE
];
83 //read in the periodic frequencies
85 if ( KSUtils::openDataFile( f
, fn
.lower() + ".freq" ) ) {
86 QTextStream
stream( &f
);
87 while ( !stream
.eof() ) {
88 line
= stream
.readLine();
89 QTextIStream
instream( &line
);
90 instream
>> freq
[n
++];
92 if (n
> DATAARRAYSIZE
) {
93 kdDebug() << "We tried to read more than " << DATAARRAYSIZE
<<
94 "elements into KSPluto::freq" << endl
;
101 if (n
==0) return false;
104 if ( KSUtils::openDataFile( f
, fn
.lower() + ".x" ) ) {
105 QTextStream
stream( &f
);
106 while ( !stream
.eof() ) {
108 line
= stream
.readLine();
109 QTextIStream
instream( &line
);
110 instream
>> ac
>> as
;
111 xdata
[n
++] = XYZData(ac
, as
);
113 if (n
> DATAARRAYSIZE
) {
114 kdDebug() << "We tried to read more than " << DATAARRAYSIZE
<<
115 "elements into KSPluto::xdata" << endl
;
122 if (n
==0) return false;
125 if ( KSUtils::openDataFile( f
, fn
.lower() + ".y" ) ) {
126 QTextStream
stream( &f
);
127 while ( !stream
.eof() ) {
129 line
= stream
.readLine();
130 QTextIStream
instream( &line
);
131 instream
>> ac
>> as
;
132 ydata
[n
++] = XYZData(ac
, as
);
134 if (n
> DATAARRAYSIZE
) {
135 kdDebug() << "We tried to read more than " << DATAARRAYSIZE
<<
136 "elements into KSPluto::ydata" << endl
;
143 if (n
==0) return false;
146 if ( KSUtils::openDataFile( f
, fn
.lower() + ".z" ) ) {
147 QTextStream
stream( &f
);
148 while ( !stream
.eof() ) {
150 line
= stream
.readLine();
151 QTextIStream
instream( &line
);
152 instream
>> ac
>> as
;
153 zdata
[n
++] = XYZData(ac
, as
);
155 if (n
> DATAARRAYSIZE
) {
156 kdDebug() << "We tried to read more than " << DATAARRAYSIZE
<<
157 "elements into KSPluto::zdata" << endl
;
164 if (n
==0) return false;
171 KSPluto::XYZpos
KSPluto::calcRectCoords(double jd
) {
176 double T
= 2.0*(jd
- 2341972.5)/146120.0 - 1.0;
180 //compute secular terms
181 X
= 98083308510. - 1465718392.*T
+ 11528487809.*T
*T
+ 55397965917.*T
*T
*T
;
182 Y
= 101846243715. + 57789.*T
- 5487929294.*T
*T
+ 8520205290.*T
*T
*T
;
183 Z
= 2183700004. + 433209785.*T
- 4911803413.*T
*T
- 14029741184.*T
*T
*T
;
186 // compute periodic X terms
187 for(int n
=0; n
< DATAARRAYSIZE
; ++n
) {
188 double tempdouble
= xdata
[n
].ac
*cos( freq
[n
]*U
) + xdata
[n
].as
*sin( freq
[n
]*U
);
189 if (n
> 81) tempdouble
*= T
;
190 if (n
> 100) tempdouble
*= T
;
195 // compute periodic Y terms
196 for(int n
=0; n
< DATAARRAYSIZE
; ++n
) {
197 double tempdouble
= ydata
[n
].ac
*cos( freq
[n
]*U
) + ydata
[n
].as
*sin( freq
[n
]*U
);
198 if (n
> 81) tempdouble
*= T
;
199 if (n
> 100) tempdouble
*= T
;
204 // compute periodic Z terms
205 for(int n
=0; n
< DATAARRAYSIZE
; ++n
) {
206 double tempdouble
= zdata
[n
].ac
*cos( freq
[n
]*U
) + zdata
[n
].as
*sin( freq
[n
]*U
);
207 if (n
> 81) tempdouble
*= T
;
208 if (n
> 100) tempdouble
*= T
;
213 return XYZpos(X
,Y
,Z
);
216 bool KSPluto::findGeocentricPosition( const KSNumbers
*num
, const KSPlanetBase
*Earth
) {
217 double X0
, Y0
, Z0
, RARad
;
218 dms L0
, B0
; //geocentric ecliptic coords of Sun
219 dms EarthLong
, EarthLat
; //heliocentric ecliptic coords of Earth
220 double sinL0
, cosL0
, sinB0
, cosB0
;
224 double olddst
= -1000;
227 double jd
= num
->julianDay();
229 Earth
->ecLong()->SinCos( sinL0
, cosL0
);
230 Earth
->ecLat()->SinCos( sinB0
, cosB0
);
232 double eX
= Earth
->rsun()*cosB0
*cosL0
;
233 double eY
= Earth
->rsun()*cosB0
*sinL0
;
234 double eZ
= Earth
->rsun()*sinB0
;
236 while (fabs(dst
-olddst
) > .001) {
237 pos
= calcRectCoords(jd
);
238 //convert X, Y, Z to AU (given in 1.0E10 AU)
239 pos
.X
/= 10000000000.0; pos
.Y
/= 10000000000.0; pos
.Z
/= 10000000000.0;
242 kdDebug() << "pluto: X = " << pos.X << " Y = " << pos.Y << " Z = " << pos.Z << endl;
245 double dX
= pos
.X
- eX
;
246 double dY
= pos
.Y
- eY
;
247 double dZ
= pos
.Z
- eZ
;
250 dst
= sqrt( dX
* dX
+ dY
* dY
+ dZ
* dZ
);
251 double delay
= .0057755183 * dst
;
253 jd
= num
->julianDay() - delay
;
257 //Compute the heliocentric ecliptic coords
258 setRsun( sqrt( pos
.X
*pos
.X
+ pos
.Y
*pos
.Y
+ pos
.Z
*pos
.Z
) );
259 L0
.setRadians( atan( pos
.Y
/ pos
.X
) );
260 if ( pos
.X
< 0.0 ) L0
.setD( L0
.Degrees() + 180.0 );
262 // if ( pos.X > 0.0 && pos.Y < 0.0 ) L += 360.0;
265 B0
.setRadians( asin( pos
.Z
/ rsun() ) );
268 //L0, B0 are Sun's Ecliptic coords (L0 = Learth + 180; B0 = -Bearth)
269 L0
.setD( Earth
->ecLong()->Degrees() + 180.0 );
270 L0
.setD( L0
.reduce().Degrees() );
271 B0
.setD( -1.0*Earth
->ecLat()->Degrees() );
273 L0
.SinCos( sinL0
, cosL0
);
274 B0
.SinCos( sinB0
, cosB0
);
277 num
->obliquity()->SinCos( sinOb
, cosOb
);
279 X0
= Earth
->rsun()*cosB0
*cosL0
;
280 Y0
= Earth
->rsun()*( cosB0
*sinL0
*cosOb
- sinB0
*sinOb
);
281 Z0
= Earth
->rsun()*( cosB0
*sinL0
*sinOb
+ sinB0
*cosOb
);
283 //transform to geocentric rectangular coordinates by adding Sun's values
284 pos
.X
+= X0
; pos
.Y
+= Y0
; pos
.Z
+= Z0
;
286 //Use Meeus's Eq. 32.10 to find Rsun, RA and Dec:
287 RARad
= atan( pos
.Y
/ pos
.X
);
288 if ( pos
.X
<0 ) RARad
+= dms::PI
;
289 if ( pos
.X
>0 && pos
.Y
<0 ) RARad
+= 2.0*dms::PI
;
290 dms newRA
; newRA
.setRadians( RARad
);
291 dms newDec
; newDec
.setRadians( asin( pos
.Z
/rsun() ) );
295 //compute Ecliptic coordinates
296 EquatorialToEcliptic( num
->obliquity() );
298 //determine the position angle