• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • plugins
  • render
  • satellites
  • sgp4
sgp4ext.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------
2 *
3 * sgp4ext.cpp
4 *
5 * this file contains extra routines needed for the main test program for sgp4.
6 * these routines are derived from the astro libraries.
7 *
8 * companion code for
9 * fundamentals of astrodynamics and applications
10 * 2007
11 * by david vallado
12 *
13 * (w) 719-573-2600, email dvallado@agi.com
14 *
15 * current :
16 * 7 may 08 david vallado
17 * fix sgn
18 * changes :
19 * 2 apr 07 david vallado
20 * fix jday floor and str lengths
21 * updates for constants
22 * 14 aug 06 david vallado
23 * original baseline
24 * ---------------------------------------------------------------- */
25 
26 #include "sgp4ext.h"
27 
28 
29 double sgn
30  (
31  double x
32  )
33  {
34  if (x < 0.0)
35  {
36  return -1.0;
37  }
38  else
39  {
40  return 1.0;
41  }
42 
43  } // end sgn
44 
45 /* -----------------------------------------------------------------------------
46 *
47 * function mag
48 *
49 * this procedure finds the magnitude of a vector. the tolerance is set to
50 * 0.000001, thus the 1.0e-12 for the squared test of underflows.
51 *
52 * author : david vallado 719-573-2600 1 mar 2001
53 *
54 * inputs description range / units
55 * vec - vector
56 *
57 * outputs :
58 * vec - answer stored in fourth component
59 *
60 * locals :
61 * none.
62 *
63 * coupling :
64 * none.
65 * --------------------------------------------------------------------------- */
66 
67 double mag
68  (
69  double x[3]
70  )
71  {
72  return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
73  } // end mag
74 
75 /* -----------------------------------------------------------------------------
76 *
77 * procedure cross
78 *
79 * this procedure crosses two vectors.
80 *
81 * author : david vallado 719-573-2600 1 mar 2001
82 *
83 * inputs description range / units
84 * vec1 - vector number 1
85 * vec2 - vector number 2
86 *
87 * outputs :
88 * outvec - vector result of a x b
89 *
90 * locals :
91 * none.
92 *
93 * coupling :
94 * mag magnitude of a vector
95  ---------------------------------------------------------------------------- */
96 
97 void cross
98  (
99  double vec1[3], double vec2[3], double outvec[3]
100  )
101  {
102  outvec[0]= vec1[1]*vec2[2] - vec1[2]*vec2[1];
103  outvec[1]= vec1[2]*vec2[0] - vec1[0]*vec2[2];
104  outvec[2]= vec1[0]*vec2[1] - vec1[1]*vec2[0];
105  } // end cross
106 
107 
108 /* -----------------------------------------------------------------------------
109 *
110 * function dot
111 *
112 * this function finds the dot product of two vectors.
113 *
114 * author : david vallado 719-573-2600 1 mar 2001
115 *
116 * inputs description range / units
117 * vec1 - vector number 1
118 * vec2 - vector number 2
119 *
120 * outputs :
121 * dot - result
122 *
123 * locals :
124 * none.
125 *
126 * coupling :
127 * none.
128 *
129 * --------------------------------------------------------------------------- */
130 
131 double dot
132  (
133  double x[3], double y[3]
134  )
135  {
136  return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]);
137  } // end dot
138 
139 /* -----------------------------------------------------------------------------
140 *
141 * procedure angle
142 *
143 * this procedure calculates the angle between two vectors. the output is
144 * set to 999999.1 to indicate an undefined value. be sure to check for
145 * this at the output phase.
146 *
147 * author : david vallado 719-573-2600 1 mar 2001
148 *
149 * inputs description range / units
150 * vec1 - vector number 1
151 * vec2 - vector number 2
152 *
153 * outputs :
154 * theta - angle between the two vectors -pi to pi
155 *
156 * locals :
157 * temp - temporary real variable
158 *
159 * coupling :
160 * dot dot product of two vectors
161 * --------------------------------------------------------------------------- */
162 
163 double angle
164  (
165  double vec1[3],
166  double vec2[3]
167  )
168  {
169  double small, undefined, magv1, magv2, temp;
170  small = 0.00000001;
171  undefined = 999999.1;
172 
173  magv1 = mag(vec1);
174  magv2 = mag(vec2);
175 
176  if (magv1*magv2 > small*small)
177  {
178  temp= dot(vec1,vec2) / (magv1*magv2);
179  if (fabs( temp ) > 1.0)
180  temp= sgn(temp) * 1.0;
181  return acos( temp );
182  }
183  else
184  return undefined;
185  } // end angle
186 
187 
188 /* -----------------------------------------------------------------------------
189 *
190 * function asinh
191 *
192 * this function evaluates the inverse hyperbolic sine function.
193 *
194 * author : david vallado 719-573-2600 1 mar 2001
195 *
196 * inputs description range / units
197 * xval - angle value any real
198 *
199 * outputs :
200 * arcsinh - result any real
201 *
202 * locals :
203 * none.
204 *
205 * coupling :
206 * none.
207 *
208 * --------------------------------------------------------------------------- */
209 
210 double asinh
211  (
212  double xval
213  )
214  {
215  return log( xval + sqrt( xval*xval + 1.0 ) );
216  } // end asinh
217 
218 
219 /* -----------------------------------------------------------------------------
220 *
221 * function newtonnu
222 *
223 * this function solves keplers equation when the true anomaly is known.
224 * the mean and eccentric, parabolic, or hyperbolic anomaly is also found.
225 * the parabolic limit at 168ø is arbitrary. the hyperbolic anomaly is also
226 * limited. the hyperbolic sine is used because it's not double valued.
227 *
228 * author : david vallado 719-573-2600 27 may 2002
229 *
230 * revisions
231 * vallado - fix small 24 sep 2002
232 *
233 * inputs description range / units
234 * ecc - eccentricity 0.0 to
235 * nu - true anomaly -2pi to 2pi rad
236 *
237 * outputs :
238 * e0 - eccentric anomaly 0.0 to 2pi rad 153.02 ø* m - mean anomaly 0.0 to 2pi rad 151.7425 ø * * locals : * e1 - eccentric anomaly, next value rad * sine - sine of e * cose - cosine of e * ktr - index * * coupling : * asinh - arc hyperbolic sine * * references : * vallado 2007, 85, alg 5 * --------------------------------------------------------------------------- */ void newtonnu ( double ecc, double nu, double& e0, double& m ) { double small, sine, cose; // --------------------- implementation --------------------- e0= 999999.9; m = 999999.9; small = 0.00000001; // --------------------------- circular ------------------------ if ( fabs( ecc ) < small ) { m = nu; e0= nu; } else // ---------------------- elliptical ----------------------- if ( ecc < 1.0-small ) { sine= ( sqrt( 1.0 -ecc*ecc ) * sin(nu) ) / ( 1.0 +ecc*cos(nu) ); cose= ( ecc + cos(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = atan2( sine,cose ); m = e0 - ecc*sin(e0); } else // -------------------- hyperbolic -------------------- if ( ecc > 1.0 + small ) { if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < M_PI-acos(1.0 /ecc))) { sine= ( sqrt( ecc*ecc-1.0 ) * sin(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = asinh( sine ); m = ecc*sinh(e0) - e0; } } else // ----------------- parabolic --------------------- if ( fabs(nu) < 168.0*M_PI/180.0 ) { e0= tan( nu*0.5 ); m = e0 + (e0*e0*e0)/3.0; } if ( ecc < 1.0 ) { m = fmod( m,2.0 *M_PI ); if ( m < 0.0 ) m = m + 2.0 *M_PI; e0 = fmod( e0,2.0 *M_PI ); } } // end newtonnu /* ----------------------------------------------------------------------------- * * function rv2coe * * this function finds the classical orbital elements given the geocentric * equatorial position and velocity vectors. * * author : david vallado 719-573-2600 21 jun 2002 * * revisions * vallado - fix special cases 5 sep 2002 * vallado - delete extra check in inclination code 16 oct 2002 * vallado - add constant file use 29 jun 2003 * vallado - add mu 2 apr 2007 * * inputs description range / units * r - ijk position vector km * v - ijk velocity vector km / s * mu - gravitational parameter km3 / s2 * * outputs : * p - semilatus rectum km * a - semimajor axis km * ecc - eccentricity * incl - inclination 0.0 to pi rad * omega - longitude of ascending node 0.0 to 2pi rad * argp - argument of perigee 0.0 to 2pi rad * nu - true anomaly 0.0 to 2pi rad * m - mean anomaly 0.0 to 2pi rad * arglat - argument of latitude (ci) 0.0 to 2pi rad * truelon - true longitude (ce) 0.0 to 2pi rad * lonper - longitude of periapsis (ee) 0.0 to 2pi rad * * locals : * hbar - angular momentum h vector km2 / s * ebar - eccentricity e vector * nbar - line of nodes n vector * c1 - v**2 - u/r * rdotv - r dot v * hk - hk unit vector * sme - specific mechanical energy km2 / s2 * i - index * e - eccentric, parabolic, * hyperbolic anomaly rad * temp - temporary variable * typeorbit - type of orbit ee, ei, ce, ci * * coupling : * mag - magnitude of a vector * cross - cross product of two vectors * angle - find the angle between two vectors * newtonnu - find the mean anomaly * * references : * vallado 2007, 126, alg 9, ex 2-5 * --------------------------------------------------------------------------- */ void rv2coe ( double r[3], double v[3], double mu, double& p, double& a, double& ecc, double& incl, double& omega, double& argp, double& nu, double& m, double& arglat, double& truelon, double& lonper ) { double undefined, small, hbar[3], nbar[3], magr, magv, magn, ebar[3], sme, rdotv, infinite, temp, c1, hk, twopi, magh, halfpi, e; int i; char typeorbit[3]; twopi = 2.0 * M_PI; halfpi = 0.5 * M_PI; small = 0.00000001; undefined = 999999.1; infinite = 999999.9; // ------------------------- implementation ----------------- magr = mag( r ); magv = mag( v ); // ------------------ find h n and e vectors ---------------- cross( r,v, hbar ); magh = mag( hbar ); if ( magh > small ) { nbar[0]= -hbar[1]; nbar[1]= hbar[0]; nbar[2]= 0.0; magn = mag( nbar ); c1 = magv*magv - mu /magr; rdotv = dot( r,v ); for (i= 0; i <= 2; i++) ebar[i]= (c1*r[i] - rdotv*v[i])/mu; ecc = mag( ebar ); // ------------ find a e and semi-latus rectum ---------- sme= ( magv*magv*0.5 ) - ( mu /magr ); if ( fabs( sme ) > small ) a= -mu / (2.0 *sme); else a= infinite; p = magh*magh/mu; // ----------------- find inclination ------------------- hk= hbar[2]/magh; incl= acos( hk ); // -------- determine type of orbit for later use -------- // ------ elliptical, parabolic, hyperbolic inclined ------- strcpy(typeorbit,"ei"); if ( ecc < small ) { // ---------------- circular equatorial --------------- if ((incl<small) | (fabs(incl-M_PI)<small)) strcpy(typeorbit,"ce"); else // -------------- circular inclined --------------- strcpy(typeorbit,"ci"); } else { // - elliptical, parabolic, hyperbolic equatorial -- if ((incl<small) | (fabs(incl-M_PI)<small)) strcpy(typeorbit,"ee"); } // ---------- find longitude of ascending node ------------ if ( magn > small ) { temp= nbar[0] / magn; if ( fabs(temp) > 1.0 ) temp= sgn(temp); omega= acos( temp ); if ( nbar[1] < 0.0 ) omega= twopi - omega; } else omega= undefined; // ---------------- find argument of perigee --------------- if ( strcmp(typeorbit,"ei") == 0 ) { argp = angle( nbar,ebar); if ( ebar[2] < 0.0 ) argp= twopi - argp; } else argp= undefined; // ------------ find true anomaly at epoch ------------- if ( typeorbit[0] == 'e' ) { nu = angle( ebar,r); if ( rdotv < 0.0 ) nu= twopi - nu; } else nu= undefined; // ---- find argument of latitude - circular inclined ----- if ( strcmp(typeorbit,"ci") == 0 ) { arglat = angle( nbar,r ); if ( r[2] < 0.0 ) arglat= twopi - arglat; m = arglat; } else arglat= undefined; // -- find longitude of perigee - elliptical equatorial ---- if (( ecc>small ) && (strcmp(typeorbit,"ee") == 0)) { temp= ebar[0]/ecc; if ( fabs(temp) > 1.0 ) temp= sgn(temp); lonper= acos( temp ); if ( ebar[1] < 0.0 ) lonper= twopi - lonper; if ( incl > halfpi ) lonper= twopi - lonper; } else lonper= undefined; // -------- find true longitude - circular equatorial ------ if (( magr>small ) && ( strcmp(typeorbit,"ce") == 0 )) { temp= r[0]/magr; if ( fabs(temp) > 1.0 ) temp= sgn(temp); truelon= acos( temp ); if ( r[1] < 0.0 ) truelon= twopi - truelon; if ( incl > halfpi ) truelon= twopi - truelon; m = truelon; } else truelon= undefined; // ------------ find mean anomaly for all orbits ----------- if ( typeorbit[0] == 'e' ) newtonnu(ecc,nu, e, m); } else { p = undefined; a = undefined; ecc = undefined; incl = undefined; omega= undefined; argp = undefined; nu = undefined; m = undefined; arglat = undefined; truelon= undefined; lonper = undefined; } } // end rv2coe /* ----------------------------------------------------------------------------- * * procedure jday * * this procedure finds the julian date given the year, month, day, and time. * the julian date is defined by each elapsed day since noon, jan 1, 4713 bc. * * algorithm : calculate the answer in one step for efficiency * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - universal time hour 0 .. 23 * min - universal time min 0 .. 59 * sec - universal time sec 0.0 .. 59.999 * * outputs : * jd - julian date days from 4713 bc * * locals : * none. * * coupling : * none. * * references : * vallado 2007, 189, alg 14, ex 3-14 * * --------------------------------------------------------------------------- */ void jday ( int year, int mon, int day, int hr, int minute, double sec, double& jd ) { jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) + floor( 275 * mon / 9.0 ) + day + 1721013.5 + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; } // end jday /* ----------------------------------------------------------------------------- * * procedure days2mdhms * * this procedure converts the day of the year, days, to the equivalent month * day, hour, minute and second. * * algorithm : set up array for the number of days per month * find leap year - use 1900 because 2000 is a leap year * loop through a temp value while the value is < the days * perform int conversions to the correct day and month * convert remainder into h m s using type conversions * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * days - julian day of the year 0.0 .. 366.0 * * outputs : * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * dayofyr - day of year * temp - temporary extended values * inttemp - temporary int value * i - index * lmonth[12] - int array containing the number of days per month * * coupling : * none. * --------------------------------------------------------------------------- */ void days2mdhms ( int year, double days, int& mon, int& day, int& hr, int& minute, double& sec ) { int i, inttemp, dayofyr; double temp; int lmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; dayofyr = (int)floor(days); /* ----------------- find month and day of month ---------------- */ if ( (year % 4) == 0 ) lmonth[1] = 29; i = 1; inttemp = 0; while ((dayofyr > inttemp + lmonth[i-1]) && (i < 12)) { inttemp = inttemp + lmonth[i-1]; i++; } mon = i; day = dayofyr - inttemp; /* ----------------- find hours minutes and seconds ------------- */ temp = (days - dayofyr) * 24.0; hr = (int)floor(temp); temp = (temp - hr) * 60.0; minute = (int)floor(temp); sec = (temp - minute) * 60.0; } // end days2mdhms /* ----------------------------------------------------------------------------- * * procedure invjday * * this procedure finds the year, month, day, hour, minute and second * given the julian date. tu can be ut1, tdt, tdb, etc. * * algorithm : set up starting values * find leap year - use 1900 because 2000 is a leap year * find the elapsed days through the year in a loop * call routine to find each individual value * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * jd - julian date days from 4713 bc * * outputs : * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * days - day of year plus fractional * portion of a day days * tu - julian centuries from 0 h * jan 0, 1900 * temp - temporary double values * leapyrs - number of leap years from 1900 * * coupling : * days2mdhms - finds month, day, hour, minute and second given days and year * * references : * vallado 2007, 208, alg 22, ex 3-13 * --------------------------------------------------------------------------- */ void invjday ( double jd, int& year, int& mon, int& day, int& hr, int& minute, double& sec ) { int leapyrs; double days, tu, temp; /* --------------- find year and days of the year --------------- */ temp = jd - 2415019.5; tu = temp / 365.25; year = 1900 + (int)floor(tu); leapyrs = (int)floor((year - 1901) * 0.25); // optional nudge by 8.64x10-7 sec to get even outputs days = temp - ((year - 1900) * 365.0 + leapyrs) + 0.00000000001; /* ------------ check for case of beginning of a year ----------- */ if (days < 1.0) { year = year - 1; leapyrs = (int)floor((year - 1901) * 0.25); days = temp - ((year - 1900) * 365.0 + leapyrs); } /* ----------------- find residual data ------------------------- */ days2mdhms(year, days, mon, day, hr, minute, sec); sec = sec - 0.00000086400; } // end invjday
239 * m - mean anomaly 0.0 to 2pi rad 151.7425 ø* * locals : * e1 - eccentric anomaly, next value rad * sine - sine of e * cose - cosine of e * ktr - index * * coupling : * asinh - arc hyperbolic sine * * references : * vallado 2007, 85, alg 5 * --------------------------------------------------------------------------- */ void newtonnu ( double ecc, double nu, double& e0, double& m ) { double small, sine, cose; // --------------------- implementation --------------------- e0= 999999.9; m = 999999.9; small = 0.00000001; // --------------------------- circular ------------------------ if ( fabs( ecc ) < small ) { m = nu; e0= nu; } else // ---------------------- elliptical ----------------------- if ( ecc < 1.0-small ) { sine= ( sqrt( 1.0 -ecc*ecc ) * sin(nu) ) / ( 1.0 +ecc*cos(nu) ); cose= ( ecc + cos(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = atan2( sine,cose ); m = e0 - ecc*sin(e0); } else // -------------------- hyperbolic -------------------- if ( ecc > 1.0 + small ) { if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < M_PI-acos(1.0 /ecc))) { sine= ( sqrt( ecc*ecc-1.0 ) * sin(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = asinh( sine ); m = ecc*sinh(e0) - e0; } } else // ----------------- parabolic --------------------- if ( fabs(nu) < 168.0*M_PI/180.0 ) { e0= tan( nu*0.5 ); m = e0 + (e0*e0*e0)/3.0; } if ( ecc < 1.0 ) { m = fmod( m,2.0 *M_PI ); if ( m < 0.0 ) m = m + 2.0 *M_PI; e0 = fmod( e0,2.0 *M_PI ); } } // end newtonnu /* ----------------------------------------------------------------------------- * * function rv2coe * * this function finds the classical orbital elements given the geocentric * equatorial position and velocity vectors. * * author : david vallado 719-573-2600 21 jun 2002 * * revisions * vallado - fix special cases 5 sep 2002 * vallado - delete extra check in inclination code 16 oct 2002 * vallado - add constant file use 29 jun 2003 * vallado - add mu 2 apr 2007 * * inputs description range / units * r - ijk position vector km * v - ijk velocity vector km / s * mu - gravitational parameter km3 / s2 * * outputs : * p - semilatus rectum km * a - semimajor axis km * ecc - eccentricity * incl - inclination 0.0 to pi rad * omega - longitude of ascending node 0.0 to 2pi rad * argp - argument of perigee 0.0 to 2pi rad * nu - true anomaly 0.0 to 2pi rad * m - mean anomaly 0.0 to 2pi rad * arglat - argument of latitude (ci) 0.0 to 2pi rad * truelon - true longitude (ce) 0.0 to 2pi rad * lonper - longitude of periapsis (ee) 0.0 to 2pi rad * * locals : * hbar - angular momentum h vector km2 / s * ebar - eccentricity e vector * nbar - line of nodes n vector * c1 - v**2 - u/r * rdotv - r dot v * hk - hk unit vector * sme - specific mechanical energy km2 / s2 * i - index * e - eccentric, parabolic, * hyperbolic anomaly rad * temp - temporary variable * typeorbit - type of orbit ee, ei, ce, ci * * coupling : * mag - magnitude of a vector * cross - cross product of two vectors * angle - find the angle between two vectors * newtonnu - find the mean anomaly * * references : * vallado 2007, 126, alg 9, ex 2-5 * --------------------------------------------------------------------------- */ void rv2coe ( double r[3], double v[3], double mu, double& p, double& a, double& ecc, double& incl, double& omega, double& argp, double& nu, double& m, double& arglat, double& truelon, double& lonper ) { double undefined, small, hbar[3], nbar[3], magr, magv, magn, ebar[3], sme, rdotv, infinite, temp, c1, hk, twopi, magh, halfpi, e; int i; char typeorbit[3]; twopi = 2.0 * M_PI; halfpi = 0.5 * M_PI; small = 0.00000001; undefined = 999999.1; infinite = 999999.9; // ------------------------- implementation ----------------- magr = mag( r ); magv = mag( v ); // ------------------ find h n and e vectors ---------------- cross( r,v, hbar ); magh = mag( hbar ); if ( magh > small ) { nbar[0]= -hbar[1]; nbar[1]= hbar[0]; nbar[2]= 0.0; magn = mag( nbar ); c1 = magv*magv - mu /magr; rdotv = dot( r,v ); for (i= 0; i <= 2; i++) ebar[i]= (c1*r[i] - rdotv*v[i])/mu; ecc = mag( ebar ); // ------------ find a e and semi-latus rectum ---------- sme= ( magv*magv*0.5 ) - ( mu /magr ); if ( fabs( sme ) > small ) a= -mu / (2.0 *sme); else a= infinite; p = magh*magh/mu; // ----------------- find inclination ------------------- hk= hbar[2]/magh; incl= acos( hk ); // -------- determine type of orbit for later use -------- // ------ elliptical, parabolic, hyperbolic inclined ------- strcpy(typeorbit,"ei"); if ( ecc < small ) { // ---------------- circular equatorial --------------- if ((incl<small) | (fabs(incl-M_PI)<small)) strcpy(typeorbit,"ce"); else // -------------- circular inclined --------------- strcpy(typeorbit,"ci"); } else { // - elliptical, parabolic, hyperbolic equatorial -- if ((incl<small) | (fabs(incl-M_PI)<small)) strcpy(typeorbit,"ee"); } // ---------- find longitude of ascending node ------------ if ( magn > small ) { temp= nbar[0] / magn; if ( fabs(temp) > 1.0 ) temp= sgn(temp); omega= acos( temp ); if ( nbar[1] < 0.0 ) omega= twopi - omega; } else omega= undefined; // ---------------- find argument of perigee --------------- if ( strcmp(typeorbit,"ei") == 0 ) { argp = angle( nbar,ebar); if ( ebar[2] < 0.0 ) argp= twopi - argp; } else argp= undefined; // ------------ find true anomaly at epoch ------------- if ( typeorbit[0] == 'e' ) { nu = angle( ebar,r); if ( rdotv < 0.0 ) nu= twopi - nu; } else nu= undefined; // ---- find argument of latitude - circular inclined ----- if ( strcmp(typeorbit,"ci") == 0 ) { arglat = angle( nbar,r ); if ( r[2] < 0.0 ) arglat= twopi - arglat; m = arglat; } else arglat= undefined; // -- find longitude of perigee - elliptical equatorial ---- if (( ecc>small ) && (strcmp(typeorbit,"ee") == 0)) { temp= ebar[0]/ecc; if ( fabs(temp) > 1.0 ) temp= sgn(temp); lonper= acos( temp ); if ( ebar[1] < 0.0 ) lonper= twopi - lonper; if ( incl > halfpi ) lonper= twopi - lonper; } else lonper= undefined; // -------- find true longitude - circular equatorial ------ if (( magr>small ) && ( strcmp(typeorbit,"ce") == 0 )) { temp= r[0]/magr; if ( fabs(temp) > 1.0 ) temp= sgn(temp); truelon= acos( temp ); if ( r[1] < 0.0 ) truelon= twopi - truelon; if ( incl > halfpi ) truelon= twopi - truelon; m = truelon; } else truelon= undefined; // ------------ find mean anomaly for all orbits ----------- if ( typeorbit[0] == 'e' ) newtonnu(ecc,nu, e, m); } else { p = undefined; a = undefined; ecc = undefined; incl = undefined; omega= undefined; argp = undefined; nu = undefined; m = undefined; arglat = undefined; truelon= undefined; lonper = undefined; } } // end rv2coe /* ----------------------------------------------------------------------------- * * procedure jday * * this procedure finds the julian date given the year, month, day, and time. * the julian date is defined by each elapsed day since noon, jan 1, 4713 bc. * * algorithm : calculate the answer in one step for efficiency * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - universal time hour 0 .. 23 * min - universal time min 0 .. 59 * sec - universal time sec 0.0 .. 59.999 * * outputs : * jd - julian date days from 4713 bc * * locals : * none. * * coupling : * none. * * references : * vallado 2007, 189, alg 14, ex 3-14 * * --------------------------------------------------------------------------- */ void jday ( int year, int mon, int day, int hr, int minute, double sec, double& jd ) { jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) + floor( 275 * mon / 9.0 ) + day + 1721013.5 + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; } // end jday /* ----------------------------------------------------------------------------- * * procedure days2mdhms * * this procedure converts the day of the year, days, to the equivalent month * day, hour, minute and second. * * algorithm : set up array for the number of days per month * find leap year - use 1900 because 2000 is a leap year * loop through a temp value while the value is < the days * perform int conversions to the correct day and month * convert remainder into h m s using type conversions * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * days - julian day of the year 0.0 .. 366.0 * * outputs : * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * dayofyr - day of year * temp - temporary extended values * inttemp - temporary int value * i - index * lmonth[12] - int array containing the number of days per month * * coupling : * none. * --------------------------------------------------------------------------- */ void days2mdhms ( int year, double days, int& mon, int& day, int& hr, int& minute, double& sec ) { int i, inttemp, dayofyr; double temp; int lmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; dayofyr = (int)floor(days); /* ----------------- find month and day of month ---------------- */ if ( (year % 4) == 0 ) lmonth[1] = 29; i = 1; inttemp = 0; while ((dayofyr > inttemp + lmonth[i-1]) && (i < 12)) { inttemp = inttemp + lmonth[i-1]; i++; } mon = i; day = dayofyr - inttemp; /* ----------------- find hours minutes and seconds ------------- */ temp = (days - dayofyr) * 24.0; hr = (int)floor(temp); temp = (temp - hr) * 60.0; minute = (int)floor(temp); sec = (temp - minute) * 60.0; } // end days2mdhms /* ----------------------------------------------------------------------------- * * procedure invjday * * this procedure finds the year, month, day, hour, minute and second * given the julian date. tu can be ut1, tdt, tdb, etc. * * algorithm : set up starting values * find leap year - use 1900 because 2000 is a leap year * find the elapsed days through the year in a loop * call routine to find each individual value * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * jd - julian date days from 4713 bc * * outputs : * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * days - day of year plus fractional * portion of a day days * tu - julian centuries from 0 h * jan 0, 1900 * temp - temporary double values * leapyrs - number of leap years from 1900 * * coupling : * days2mdhms - finds month, day, hour, minute and second given days and year * * references : * vallado 2007, 208, alg 22, ex 3-13 * --------------------------------------------------------------------------- */ void invjday ( double jd, int& year, int& mon, int& day, int& hr, int& minute, double& sec ) { int leapyrs; double days, tu, temp; /* --------------- find year and days of the year --------------- */ temp = jd - 2415019.5; tu = temp / 365.25; year = 1900 + (int)floor(tu); leapyrs = (int)floor((year - 1901) * 0.25); // optional nudge by 8.64x10-7 sec to get even outputs days = temp - ((year - 1900) * 365.0 + leapyrs) + 0.00000000001; /* ------------ check for case of beginning of a year ----------- */ if (days < 1.0) { year = year - 1; leapyrs = (int)floor((year - 1901) * 0.25); days = temp - ((year - 1900) * 365.0 + leapyrs); } /* ----------------- find residual data ------------------------- */ days2mdhms(year, days, mon, day, hr, minute, sec); sec = sec - 0.00000086400; } // end invjday
240 *
241 * locals :
242 * e1 - eccentric anomaly, next value rad
243 * sine - sine of e
244 * cose - cosine of e
245 * ktr - index
246 *
247 * coupling :
248 * asinh - arc hyperbolic sine
249 *
250 * references :
251 * vallado 2007, 85, alg 5
252 * --------------------------------------------------------------------------- */
253 
254 void newtonnu
255  (
256  double ecc, double nu,
257  double& e0, double& m
258  )
259  {
260  double small, sine, cose;
261 
262  // --------------------- implementation ---------------------
263  e0= 999999.9;
264  m = 999999.9;
265  small = 0.00000001;
266 
267  // --------------------------- circular ------------------------
268  if ( fabs( ecc ) < small )
269  {
270  m = nu;
271  e0= nu;
272  }
273  else
274  // ---------------------- elliptical -----------------------
275  if ( ecc < 1.0-small )
276  {
277  sine= ( sqrt( 1.0 -ecc*ecc ) * sin(nu) ) / ( 1.0 +ecc*cos(nu) );
278  cose= ( ecc + cos(nu) ) / ( 1.0 + ecc*cos(nu) );
279  e0 = atan2( sine,cose );
280  m = e0 - ecc*sin(e0);
281  }
282  else
283  // -------------------- hyperbolic --------------------
284  if ( ecc > 1.0 + small )
285  {
286  if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < M_PI-acos(1.0 /ecc)))
287  {
288  sine= ( sqrt( ecc*ecc-1.0 ) * sin(nu) ) / ( 1.0 + ecc*cos(nu) );
289  e0 = asinh( sine );
290  m = ecc*sinh(e0) - e0;
291  }
292  }
293  else
294  // ----------------- parabolic ---------------------
295  if ( fabs(nu) < 168.0*M_PI/180.0 )
296  {
297  e0= tan( nu*0.5 );
298  m = e0 + (e0*e0*e0)/3.0;
299  }
300 
301  if ( ecc < 1.0 )
302  {
303  m = fmod( m,2.0 *M_PI );
304  if ( m < 0.0 )
305  m = m + 2.0 *M_PI;
306  e0 = fmod( e0,2.0 *M_PI );
307  }
308  } // end newtonnu
309 
310 
311 /* -----------------------------------------------------------------------------
312 *
313 * function rv2coe
314 *
315 * this function finds the classical orbital elements given the geocentric
316 * equatorial position and velocity vectors.
317 *
318 * author : david vallado 719-573-2600 21 jun 2002
319 *
320 * revisions
321 * vallado - fix special cases 5 sep 2002
322 * vallado - delete extra check in inclination code 16 oct 2002
323 * vallado - add constant file use 29 jun 2003
324 * vallado - add mu 2 apr 2007
325 *
326 * inputs description range / units
327 * r - ijk position vector km
328 * v - ijk velocity vector km / s
329 * mu - gravitational parameter km3 / s2
330 *
331 * outputs :
332 * p - semilatus rectum km
333 * a - semimajor axis km
334 * ecc - eccentricity
335 * incl - inclination 0.0 to pi rad
336 * omega - longitude of ascending node 0.0 to 2pi rad
337 * argp - argument of perigee 0.0 to 2pi rad
338 * nu - true anomaly 0.0 to 2pi rad
339 * m - mean anomaly 0.0 to 2pi rad
340 * arglat - argument of latitude (ci) 0.0 to 2pi rad
341 * truelon - true longitude (ce) 0.0 to 2pi rad
342 * lonper - longitude of periapsis (ee) 0.0 to 2pi rad
343 *
344 * locals :
345 * hbar - angular momentum h vector km2 / s
346 * ebar - eccentricity e vector
347 * nbar - line of nodes n vector
348 * c1 - v**2 - u/r
349 * rdotv - r dot v
350 * hk - hk unit vector
351 * sme - specific mechanical energy km2 / s2
352 * i - index
353 * e - eccentric, parabolic,
354 * hyperbolic anomaly rad
355 * temp - temporary variable
356 * typeorbit - type of orbit ee, ei, ce, ci
357 *
358 * coupling :
359 * mag - magnitude of a vector
360 * cross - cross product of two vectors
361 * angle - find the angle between two vectors
362 * newtonnu - find the mean anomaly
363 *
364 * references :
365 * vallado 2007, 126, alg 9, ex 2-5
366 * --------------------------------------------------------------------------- */
367 
368 void rv2coe
369  (
370  double r[3], double v[3], double mu,
371  double& p, double& a, double& ecc, double& incl, double& omega, double& argp,
372  double& nu, double& m, double& arglat, double& truelon, double& lonper
373  )
374  {
375  double undefined, small, hbar[3], nbar[3], magr, magv, magn, ebar[3], sme,
376  rdotv, infinite, temp, c1, hk, twopi, magh, halfpi, e;
377 
378  int i;
379  char typeorbit[3];
380 
381  twopi = 2.0 * M_PI;
382  halfpi = 0.5 * M_PI;
383  small = 0.00000001;
384  undefined = 999999.1;
385  infinite = 999999.9;
386 
387  // ------------------------- implementation -----------------
388  magr = mag( r );
389  magv = mag( v );
390 
391  // ------------------ find h n and e vectors ----------------
392  cross( r,v, hbar );
393  magh = mag( hbar );
394  if ( magh > small )
395  {
396  nbar[0]= -hbar[1];
397  nbar[1]= hbar[0];
398  nbar[2]= 0.0;
399  magn = mag( nbar );
400  c1 = magv*magv - mu /magr;
401  rdotv = dot( r,v );
402  for (i= 0; i <= 2; i++)
403  ebar[i]= (c1*r[i] - rdotv*v[i])/mu;
404  ecc = mag( ebar );
405 
406  // ------------ find a e and semi-latus rectum ----------
407  sme= ( magv*magv*0.5 ) - ( mu /magr );
408  if ( fabs( sme ) > small )
409  a= -mu / (2.0 *sme);
410  else
411  a= infinite;
412  p = magh*magh/mu;
413 
414  // ----------------- find inclination -------------------
415  hk= hbar[2]/magh;
416  incl= acos( hk );
417 
418  // -------- determine type of orbit for later use --------
419  // ------ elliptical, parabolic, hyperbolic inclined -------
420  strcpy(typeorbit,"ei");
421  if ( ecc < small )
422  {
423  // ---------------- circular equatorial ---------------
424  if ((incl<small) | (fabs(incl-M_PI)<small))
425  strcpy(typeorbit,"ce");
426  else
427  // -------------- circular inclined ---------------
428  strcpy(typeorbit,"ci");
429  }
430  else
431  {
432  // - elliptical, parabolic, hyperbolic equatorial --
433  if ((incl<small) | (fabs(incl-M_PI)<small))
434  strcpy(typeorbit,"ee");
435  }
436 
437  // ---------- find longitude of ascending node ------------
438  if ( magn > small )
439  {
440  temp= nbar[0] / magn;
441  if ( fabs(temp) > 1.0 )
442  temp= sgn(temp);
443  omega= acos( temp );
444  if ( nbar[1] < 0.0 )
445  omega= twopi - omega;
446  }
447  else
448  omega= undefined;
449 
450  // ---------------- find argument of perigee ---------------
451  if ( strcmp(typeorbit,"ei") == 0 )
452  {
453  argp = angle( nbar,ebar);
454  if ( ebar[2] < 0.0 )
455  argp= twopi - argp;
456  }
457  else
458  argp= undefined;
459 
460  // ------------ find true anomaly at epoch -------------
461  if ( typeorbit[0] == 'e' )
462  {
463  nu = angle( ebar,r);
464  if ( rdotv < 0.0 )
465  nu= twopi - nu;
466  }
467  else
468  nu= undefined;
469 
470  // ---- find argument of latitude - circular inclined -----
471  if ( strcmp(typeorbit,"ci") == 0 )
472  {
473  arglat = angle( nbar,r );
474  if ( r[2] < 0.0 )
475  arglat= twopi - arglat;
476  m = arglat;
477  }
478  else
479  arglat= undefined;
480 
481  // -- find longitude of perigee - elliptical equatorial ----
482  if (( ecc>small ) && (strcmp(typeorbit,"ee") == 0))
483  {
484  temp= ebar[0]/ecc;
485  if ( fabs(temp) > 1.0 )
486  temp= sgn(temp);
487  lonper= acos( temp );
488  if ( ebar[1] < 0.0 )
489  lonper= twopi - lonper;
490  if ( incl > halfpi )
491  lonper= twopi - lonper;
492  }
493  else
494  lonper= undefined;
495 
496  // -------- find true longitude - circular equatorial ------
497  if (( magr>small ) && ( strcmp(typeorbit,"ce") == 0 ))
498  {
499  temp= r[0]/magr;
500  if ( fabs(temp) > 1.0 )
501  temp= sgn(temp);
502  truelon= acos( temp );
503  if ( r[1] < 0.0 )
504  truelon= twopi - truelon;
505  if ( incl > halfpi )
506  truelon= twopi - truelon;
507  m = truelon;
508  }
509  else
510  truelon= undefined;
511 
512  // ------------ find mean anomaly for all orbits -----------
513  if ( typeorbit[0] == 'e' )
514  newtonnu(ecc,nu, e, m);
515  }
516  else
517  {
518  p = undefined;
519  a = undefined;
520  ecc = undefined;
521  incl = undefined;
522  omega= undefined;
523  argp = undefined;
524  nu = undefined;
525  m = undefined;
526  arglat = undefined;
527  truelon= undefined;
528  lonper = undefined;
529  }
530  } // end rv2coe
531 
532 /* -----------------------------------------------------------------------------
533 *
534 * procedure jday
535 *
536 * this procedure finds the julian date given the year, month, day, and time.
537 * the julian date is defined by each elapsed day since noon, jan 1, 4713 bc.
538 *
539 * algorithm : calculate the answer in one step for efficiency
540 *
541 * author : david vallado 719-573-2600 1 mar 2001
542 *
543 * inputs description range / units
544 * year - year 1900 .. 2100
545 * mon - month 1 .. 12
546 * day - day 1 .. 28,29,30,31
547 * hr - universal time hour 0 .. 23
548 * min - universal time min 0 .. 59
549 * sec - universal time sec 0.0 .. 59.999
550 *
551 * outputs :
552 * jd - julian date days from 4713 bc
553 *
554 * locals :
555 * none.
556 *
557 * coupling :
558 * none.
559 *
560 * references :
561 * vallado 2007, 189, alg 14, ex 3-14
562 *
563 * --------------------------------------------------------------------------- */
564 
565 void jday
566  (
567  int year, int mon, int day, int hr, int minute, double sec,
568  double& jd
569  )
570  {
571  jd = 367.0 * year -
572  floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) +
573  floor( 275 * mon / 9.0 ) +
574  day + 1721013.5 +
575  ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days
576  // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5;
577  } // end jday
578 
579 /* -----------------------------------------------------------------------------
580 *
581 * procedure days2mdhms
582 *
583 * this procedure converts the day of the year, days, to the equivalent month
584 * day, hour, minute and second.
585 *
586 * algorithm : set up array for the number of days per month
587 * find leap year - use 1900 because 2000 is a leap year
588 * loop through a temp value while the value is < the days
589 * perform int conversions to the correct day and month
590 * convert remainder into h m s using type conversions
591 *
592 * author : david vallado 719-573-2600 1 mar 2001
593 *
594 * inputs description range / units
595 * year - year 1900 .. 2100
596 * days - julian day of the year 0.0 .. 366.0
597 *
598 * outputs :
599 * mon - month 1 .. 12
600 * day - day 1 .. 28,29,30,31
601 * hr - hour 0 .. 23
602 * min - minute 0 .. 59
603 * sec - second 0.0 .. 59.999
604 *
605 * locals :
606 * dayofyr - day of year
607 * temp - temporary extended values
608 * inttemp - temporary int value
609 * i - index
610 * lmonth[12] - int array containing the number of days per month
611 *
612 * coupling :
613 * none.
614 * --------------------------------------------------------------------------- */
615 
616 void days2mdhms
617  (
618  int year, double days,
619  int& mon, int& day, int& hr, int& minute, double& sec
620  )
621  {
622  int i, inttemp, dayofyr;
623  double temp;
624  int lmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
625 
626  dayofyr = (int)floor(days);
627  /* ----------------- find month and day of month ---------------- */
628  if ( (year % 4) == 0 )
629  lmonth[1] = 29;
630 
631  i = 1;
632  inttemp = 0;
633  while ((dayofyr > inttemp + lmonth[i-1]) && (i < 12))
634  {
635  inttemp = inttemp + lmonth[i-1];
636  i++;
637  }
638  mon = i;
639  day = dayofyr - inttemp;
640 
641  /* ----------------- find hours minutes and seconds ------------- */
642  temp = (days - dayofyr) * 24.0;
643  hr = (int)floor(temp);
644  temp = (temp - hr) * 60.0;
645  minute = (int)floor(temp);
646  sec = (temp - minute) * 60.0;
647  } // end days2mdhms
648 
649 /* -----------------------------------------------------------------------------
650 *
651 * procedure invjday
652 *
653 * this procedure finds the year, month, day, hour, minute and second
654 * given the julian date. tu can be ut1, tdt, tdb, etc.
655 *
656 * algorithm : set up starting values
657 * find leap year - use 1900 because 2000 is a leap year
658 * find the elapsed days through the year in a loop
659 * call routine to find each individual value
660 *
661 * author : david vallado 719-573-2600 1 mar 2001
662 *
663 * inputs description range / units
664 * jd - julian date days from 4713 bc
665 *
666 * outputs :
667 * year - year 1900 .. 2100
668 * mon - month 1 .. 12
669 * day - day 1 .. 28,29,30,31
670 * hr - hour 0 .. 23
671 * min - minute 0 .. 59
672 * sec - second 0.0 .. 59.999
673 *
674 * locals :
675 * days - day of year plus fractional
676 * portion of a day days
677 * tu - julian centuries from 0 h
678 * jan 0, 1900
679 * temp - temporary double values
680 * leapyrs - number of leap years from 1900
681 *
682 * coupling :
683 * days2mdhms - finds month, day, hour, minute and second given days and year
684 *
685 * references :
686 * vallado 2007, 208, alg 22, ex 3-13
687 * --------------------------------------------------------------------------- */
688 
689 void invjday
690  (
691  double jd,
692  int& year, int& mon, int& day,
693  int& hr, int& minute, double& sec
694  )
695  {
696  int leapyrs;
697  double days, tu, temp;
698 
699  /* --------------- find year and days of the year --------------- */
700  temp = jd - 2415019.5;
701  tu = temp / 365.25;
702  year = 1900 + (int)floor(tu);
703  leapyrs = (int)floor((year - 1901) * 0.25);
704 
705  // optional nudge by 8.64x10-7 sec to get even outputs
706  days = temp - ((year - 1900) * 365.0 + leapyrs) + 0.00000000001;
707 
708  /* ------------ check for case of beginning of a year ----------- */
709  if (days < 1.0)
710  {
711  year = year - 1;
712  leapyrs = (int)floor((year - 1901) * 0.25);
713  days = temp - ((year - 1900) * 365.0 + leapyrs);
714  }
715 
716  /* ----------------- find residual data ------------------------- */
717  days2mdhms(year, days, mon, day, hr, minute, sec);
718  sec = sec - 0.00000086400;
719  } // end invjday
720 
721 
722 
723 
724 
newtonnu
void newtonnu(double ecc, double nu, double &e0, double &m)
Definition: sgp4ext.cpp:255
sgn
double sgn(double x)
Definition: sgp4ext.cpp:30
angle
double angle(double vec1[3], double vec2[3])
Definition: sgp4ext.cpp:164
dot
double dot(double x[3], double y[3])
Definition: sgp4ext.cpp:132
jday
void jday(int year, int mon, int day, int hr, int minute, double sec, double &jd)
Definition: sgp4ext.cpp:566
asinh
double asinh(double xval)
Definition: sgp4ext.cpp:211
sgp4ext.h
cross
void cross(double vec1[3], double vec2[3], double outvec[3])
Definition: sgp4ext.cpp:98
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
days2mdhms
void days2mdhms(int year, double days, int &mon, int &day, int &hr, int &minute, double &sec)
Definition: sgp4ext.cpp:617
mag
double mag(double x[3])
Definition: sgp4ext.cpp:68
rv2coe
void rv2coe(double r[3], double v[3], double mu, double &p, double &a, double &ecc, double &incl, double &omega, double &argp, double &nu, double &m, double &arglat, double &truelon, double &lonper)
Definition: sgp4ext.cpp:369
invjday
void invjday(double jd, int &year, int &mon, int &day, int &hr, int &minute, double &sec)
Definition: sgp4ext.cpp:690
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal