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

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • astro
astrolib.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2013 Gerhard Holtkamp
9 //
10 
11 /* =========================================================================
12  Procedures needed for standard astronomy programs.
13  The majority of procedures in this unit are taken from Montenbruck,
14  Pfleger "Astronomie mit dem Personal Computer", Springer Verlag, 1989
15  as well as from the "Explanatory Supplement to the Astronomical Almanac"
16  University Science Books, Mill Valley, California, 1992
17  and modified correspondingly.
18 
19  License: GNU LGPL Version 2+
20  Copyright : Gerhard HOLTKAMP 28-JAN-2013
21  ========================================================================= */
22 
23 #include "astrolib.h"
24 
25 #include <cmath>
26 using namespace std;
27 
28 #include "attlib.h"
29 
30 double frac (double f)
31  { return fmod(f,1.0); }
32 
33 /*--------------- Function ddd ------------------------------------------*/
34 
35 double ddd (int d, int m, double s)
36  {
37  /*
38  Conversion from Degrees, Minutes, Seconds into decimal degrees
39 
40  INPUT :
41  d : degrees
42  m : minutes
43  s : seconds (and fractions)
44 
45  OUTPUT :
46  dd : decimal degrees
47  */
48  double dd;
49 
50  if ( (d < 0) || (m < 0) || (s < 0)) dd = -1.0;
51  else dd = 1.0;
52  dd = dd * (fabs(double(d)) + fabs(double(m))/60.0 + fabs(s)/3600.0);
53 
54  return dd;
55  }
56 
57 /*--------------- Function dms ------------------------------------------*/
58 
59 void dms (double dd, int &d, int &m, double &s)
60  /*
61  Conversion from decimal degrees into Degrees, Minutes, Seconds
62 
63  INPUT :
64  dd : decimal degrees
65 
66  OUTPUT :
67  d : degrees
68  m : minutes
69  s : seconds (and fractions)
70  */
71  {
72  double d1;
73 
74  d1 = fabs(dd);
75  // d = int(floor(d1));
76  d = int(d1);
77  d1 = (d1 - d) * 60.0;
78  // m = int(floor(d1));
79  m = int(d1);
80  s = (d1 - m) * 60.0;
81  if (dd < 0)
82  {
83  if (d != 0) d = -d;
84  else
85  {
86  if (m != 0) m = -m;
87  else s = -s;
88  };
89  };
90  }
91 
92  /*------------ FUNCTION mjd ----------------------------------------------*/
93 
94 double mjd (int day, int month, int year, double hour)
95 /*
96  Modified Julian Date ( MJD = Julian Date - 2400000.5)
97  valid for every date
98  Julian Calendar up to 4-OCT-1582,
99  Gregorian Calendar from 15-OCT-1582.
100  */
101  {
102  double a;
103  long int b, c;
104 
105  a = 10000.0 * year + 100.0 * month + day;
106  if (month <= 2)
107  {
108  month = month + 12;
109  year = year - 1;
110  };
111  if (a <= 15821004.1)
112  {
113  b = ((year+4716)/4) - 1181;
114  if (year < -4716)
115  {
116  c = year + 4717;
117  c = -c;
118  c = c / 4;
119  c = -c;
120  b = c - 1182;
121  };
122  }
123  else b = (year/400) - (year/100) + (year/4);
124  // { b = -2 + floor((year+4716)/4) - 1179;}
125  // else {b = floor(year/400) - floor(year/100) + floor(year/4);};
126 
127  a = 365.0 * year - 679004.0;
128  a = a + b + int(30.6001 * (month + 1)) + day + hour / 24.0;
129 
130  return a;
131  }
132 
133 /*---------------- Function julcent ---------------------------------------*/
134 
135 double julcent (double mjuld)
136  {
137  /*
138  Julian Centuries since J2000.0 of Modified Julian Date mjuld.
139  */
140  return (mjuld - 51544.5) / 36525.0;
141  }
142 
143 /*---------------- Function caldat -----------------------------------------*/
144 
145 void caldat (double mjd, int &day, int &month, int &year, double &hour)
146  /*
147  Calculate the calendar date from the Modified Julian Date
148 
149  INPUT :
150  mjd : Modified Julian Date (Julian Date - 2400000.5)
151 
152  OUTPUT :
153  day, month, year : corresponding date
154  hour : corresponding hours of the above date
155  */
156  {
157  long int b, c, d, e, f, jd0;
158 
159  jd0 = long(mjd + 2400001.0);
160  if (jd0 < 2299161) c = jd0 + 1524; /* Julian calendar */
161  else
162  { /* Gregorian calendar */
163  b = long (( jd0 - 1867216.25) / 36524.25);
164  c = jd0 + b - (b/4) + 1525;
165  };
166 
167  if (mjd < -2400001.0) // special case for year < -4712
168  {
169  if (mjd == floor(mjd)) jd0 = jd0 + 1;
170  c = long((-jd0 - 0.1)/ 365.25);
171  c = c + 1;
172  year = -4712 - c;
173  d = c / 4;
174  d = c * 365 + d; // number of days from JAN 1, -4712
175  f = d + jd0; // day of the year
176  if ((c % 4) == 0) e = 61;
177  else e = 60;
178  if (f == 0)
179  {
180  year = year - 1;
181  month = 12;
182  day = 31;
183  f = 500; // set as a marker
184  };
185  if (f < e)
186  {
187  if (f < 32)
188  {
189  month = 1;
190  day = f;
191  }
192  else
193  {
194  month = 2;
195  day = f - 31;
196  };
197  }
198  else
199  {
200  if (f < 500)
201  {
202  f = f - e;
203  month = long((f + 123.0) / 30.6001);
204  day = f - long(month * 30.6001) + 123;
205  month = month - 1;
206  };
207  };
208  }
209  else // normal case
210  {
211  d = long ((c - 122.1) / 365.25);
212  e = 365 * d + (d/4);
213  f = long ((c - e) / 30.6001);
214  day = c - e - long(30.6001 * f);
215  month = f - 1 - 12 * (f / 14);
216  year = d - 4715 - ((7 + month) / 10);
217  };
218 
219  hour = 24.0 * (mjd - floor(mjd));
220  }
221 
222 /*---------------- Function DefTdUt --------------------------------------*/
223 double DefTdUt (int yi)
224  {
225  /*
226  Get a suitable default for value of TDT - UT in year yi in seconds.
227  */
228 
229  const int td[9] = {55,55,56,56,57,58,58,59,60};
230  double t, result;
231  int yy, yr;
232 
233  yr = yi;
234 
235  if (yr > 1899)
236  {
237  if (yr >= 2000) // this corrects for observations until 2013
238  {
239  if (yr > 2006) yr -= 1;
240  if (yr > 2006) yr -= 1; // no leap second at the end of 2007
241  if (yr > 2007) yr -= 1; // no leap second at the end of 2009
242  if (yr > 2007) yr -= 1; // no leap second at the end of 2010
243  if (yr > 2008) yr -= 1; // no leap second at the end of 2012
244  yr -= 6;
245  if (yr < 1999) yr = 1999;
246  };
247  t = yr - 2000;
248  t = t / 100.0;
249  result = (((-339.84*t - 516.12)*t -160.22)*t + 92.23)*t + 71.28;
250  if (yr > 2013)
251  {
252  t = yr - 2013;
253  t = t / 100.0;
254  result = (27.5*t + 75.0)*t + 73.0;
255  }
256  else if (yr > 1994)
257  {
258  result -= 6.28;
259  }
260  else if (yr > 1985)
261  {
262  yy = yr - 1986;
263  result = td[yy];
264  };
265  };
266 
267  if (yr < 1900)
268  {
269  t = yr - 1800;
270  t = t / 100;
271  if (yr > 1649)
272  {
273  t = t - 0.19;
274  result = 5.156 + 13.3066 * t * t;
275  if (yr > 1864) result = -0.6*(yr - 1865) + 6;
276  if (yr > 1884) result = -0.2*(yr - 1885) - 6;
277  }
278  else
279  {
280  if (yr > 947) result = 25.5 * t*t;
281  else result = 1360 + (44.3*t + 320.0) * t;
282  };
283  };
284 
285 // round to full seconds
286 
287  if (result < 0)
288  {
289  t = -result;
290  t += 0.5;
291  result = - floor(t);
292  }
293  else result = floor(result + 0.5);
294 
295  result += 0.184; // because of TT = TAI + 32.184;
296 
297  return result;
298  }
299 
300 /*---------------- Function lsidtim -------------------------------------*/
301 
302 double lsidtim (double jd, double lambda, double ep2)
303  {
304  /* Calculate the Apparent Local Mean Sidereal Time (in decimal hours) for
305  the Modified Julian Date jd and geographic longitude lambda (in degrees)
306  and with the correction (AST - MST) eps (given in seconds)
307  */
308  double lmst;
309  double t, ut, gmst;
310  int mjd0;
311 
312  mjd0 = int(jd);
313  ut = (jd - mjd0)*24.0;
314  t = (mjd0 - 51544.5) / 36525.0;
315  gmst = 6.697374558 + 1.0027379093*ut
316  + (8640184.812866 + (0.093104 - 6.2e-6*t)*t)*t/3600.0;
317  lmst = 24.0 * frac((gmst + lambda/15.0) / 24.0);
318  lmst = lmst + ep2 / 3600.0;
319 
320  return lmst;
321  }
322 
323 /*---------------- Function eps -----------------------------------------*/
324 
325 double eps (double t) // obliquity of ecliptic
326  {
327  /*
328  Obliquety of ecliptic eps (in radians)
329  at time t (in Julian Centuries from J2000.0)
330  */
331  double tp;
332 
333  tp = 23.43929111 - (46.815+(0.00059-0.001813*t)*t)*t/3600.0;
334  tp = 1.74532925199e-2 * tp;
335 
336  return tp;
337  }
338 
339 /*---------------- Function eclequ -----------------------------------------*/
340 
341 Vec3 eclequ (double t, Vec3& r1) // ecliptic -> equatorial
342  {
343  /*
344  Convert position vector r1 from ecliptic into equatorial coordinates
345  at t (in Julian Centuries from J2000.0 )
346  */
347 
348  Mat3 m;
349  Vec3 r2;
350 
351  m = xrot (-eps(t));
352  r2 = mxvct (m, r1);
353  return r2;
354  }
355 
356 /*---------------- Function equecl -----------------------------------------*/
357 
358 Vec3 equecl (double t, Vec3& r1) // equatorial -> ecliptic
359  {
360  /*
361  Convert position vector r1 from equatorial into ecliptic coordinates
362  at t (in Julian Centuries from J2000.0)
363  */
364 
365  Mat3 m;
366  Vec3 r2;
367 
368  m = xrot (eps(t));
369  r2 = mxvct (m, r1);
370  return r2;
371  }
372 
373 /*---------------- Function pmatecl -----------------------------------------*/
374 
375 Mat3 pmatecl (double t1, double t2) // ecl. precession
376  {
377  /*
378  Calculate ecliptic precession matrix a from t1 to t2
379  (times in Julian Centuries from J2000.0)
380  */
381 
382  const double secrad = 4.8481368111e-6; // arcsec -> radians
383 
384  double ppi, pii, pa, dt;
385  Mat3 m1, m2, a;
386 
387  dt = t2 - t1;
388  ppi = 174.876383889 + (((3289.4789+0.60622*t1)*t1) +
389  ((-869.8089-0.50491*t1) + 0.03536*dt)*dt) / 3600.0;
390  ppi = ppi * 1.74532925199e-2;
391  pii = ((47.0029-(0.06603-0.000598*t1)*t1) +
392  ((-0.03302+0.000598*t1)+0.00006*dt)*dt)*dt * secrad;
393  pa = ((5029.0966+(2.22226-0.000042*t1)*t1) +
394  ((1.11113-0.000042*t1)-0.000006*dt)*dt)*dt * secrad;
395 
396  pa = ppi + pa;
397  m1 = zrot (-pa);
398  m2 = xrot (pii);
399  m1 = m1 * m2;
400  m2 = zrot (ppi);
401  a = m1 * m2;
402 
403  return a;
404  }
405 
406 /*---------------- Function pmatequ --------------------------------------*/
407 
408 Mat3 pmatequ (double t1, double t2) // equ. precession
409  {
410  /*
411  Calculate equatorial precession matrix a from t1 to t2
412  (times in Julian Centuries from J2000.0)
413  */
414  const double secrad = 4.8481368111e-6; // arcsec -> radians
415 
416  double dt, zeta, z, theta;
417  Mat3 m1, m2, a;
418 
419  dt = t2 - t1;
420  zeta = ((2306.2181+(1.39656-0.000139*t1)*t1) +
421  ((0.30188-0.000345*t1)+0.017998*dt)*dt)*dt * secrad;
422  z = zeta + ((0.7928+0.000411*t1)+0.000205*dt)*dt*dt * secrad;
423  theta = ((2004.3109-(0.8533+0.000217*t1)*t1) -
424  ((0.42665+0.000217*t1)+0.041833*dt)*dt)*dt * secrad;
425 
426  m1 = zrot (-z);
427  m2 = yrot (theta);
428  m1 = m1 * m2;
429  m2 = zrot (-zeta);
430  a = m1 * m2;
431 
432  return a;
433  }
434 
435 /*---------------- Function nutmat --------------------------------------*/
436 
437 Mat3 nutmat (double t, double& ep2, bool hpr)
438  {
439  /*
440  Calculate nutation matrix a from mean to true equatorial coordinates
441  at time t (in Julian Centuries from J2000.0)
442  Also calculates the correction ep2 for apparent sidereal time in sec
443 
444  if hpr is true a high precision is used, otherwise a low precision
445  (only the first 50 terms of the nutation theory are used)
446  */
447  const int ntb1 = 15;
448  const int tb1[ntb1][5] =
449  {
450  { 0, 0, 0, 0, 1}, // 1
451  { 0, 0, 0, 0, 2}, // 2
452  { 0, 0, 2,-2, 2}, // 9
453  { 0, 1, 0, 0, 0}, // 10
454  { 0, 1, 2,-2, 2}, // 11
455  { 0,-1, 2,-2, 2}, // 12
456  { 0, 0, 2,-2, 1}, // 13
457  { 0, 2, 0, 0, 0}, // 16
458  { 0, 2, 2,-2, 2}, // 18
459  { 0, 0, 2, 0, 2}, // 31
460  { 1, 0, 0, 0, 0}, // 32
461  { 0, 0, 2, 0, 1}, // 33
462  { 1, 0, 2, 0, 2}, // 34
463  { 1, 0, 0, 0, 1}, // 38
464  { -1, 0, 0, 0, 1}, // 39
465  };
466 
467  const int ntb2 = 35;
468  const int tb2[ntb2][5] =
469  {
470  { -2, 0, 2, 0, 1}, // 3
471  { 2, 0,-2, 0, 0}, // 4
472  { -2, 0, 2, 0, 2}, // 5
473  { 1,-1, 0,-1, 0}, // 6
474  { 0,-2, 2,-2, 1}, // 7
475  { 2, 0,-2, 0, 1}, // 8
476  { 2, 0, 0,-2, 0}, // 14
477  { 0, 0, 2,-2, 0}, // 15
478  { 0, 1, 0, 0, 1}, // 17
479  { 0,-1, 0, 0, 1}, // 19
480  { -2, 0, 0, 2, 1}, // 20
481  { 0,-1, 2,-2, 1}, // 21
482  { 2, 0, 0,-2, 1}, // 22
483  { 0, 1, 2,-2, 1}, // 23
484  { 1, 0, 0,-1, 0}, // 24
485  { 2, 1, 0,-2, 0}, // 25
486  { 0, 0,-2, 2, 1}, // 26
487  { 0, 1,-2, 2, 0}, // 27
488  { 0, 1, 0, 0, 2}, // 28
489  { -1, 0, 0, 1, 1}, // 29
490  { 0, 1, 2,-2, 0}, // 30
491  { 1, 0, 0,-2, 0}, // 35
492  { -1, 0, 2, 0, 2}, // 36
493  { 0, 0, 0, 2, 0}, // 37
494  { -1, 0, 2, 2, 2}, // 40
495  { 1, 0, 2, 0, 1}, // 41
496  { 0, 0, 2, 2, 2}, // 42
497  { 2, 0, 0, 0, 0}, // 43
498  { 1, 0, 2,-2, 2}, // 44
499  { 2, 0, 2, 0, 2}, // 45
500  { 0, 0, 2, 0, 0}, // 46
501  { -1, 0, 2, 0, 1}, // 47
502  { -1, 0, 0, 2, 1}, // 48
503  { 1, 0, 0,-2, 1}, // 49
504  { -1, 0, 2, 2, 1}, // 50
505  };
506 
507  const double tb3[ntb1][4] =
508  {
509  {-171996.0,-174.2, 92025.0, 8.9 }, // 1
510  { 2062.0, 0.2, -895.0, 0.5 }, // 2
511  { -13187.0, -1.6, 5736.0, -3.1 }, // 9
512  { 1426.0, -3.4, 54.0, -0.1 }, // 10
513  { -517.0, 1.2, 224.0, -0.6 }, // 11
514  { 217.0, -0.5, -95.0, 0.3 }, // 12
515  { 129.0, 0.1, -70.0, 0.0 }, // 13
516  { 17.0, -0.1, 0.0, 0.0 }, // 16
517  { -16.0, 0.1, 7.0, 0.0 }, // 18
518  { -2274.0, -0.2, 977.0, -0.5 }, // 31
519  { 712.0, 0.1, -7.0, 0.0 }, // 32
520  { -386.0, -0.4, 200.0, 0.0 }, // 33
521  { -301.0, 0.0, 129.0, -0.1 }, // 34
522  { 63.0, 0.1, -33.0, 0.0 }, // 38
523  { -58.0, -0.1, 32.0, 0.0 }, // 39
524  };
525 
526  const double tb4[ntb2][2] =
527  {
528  { 46.0, -24.0}, // 3
529  { 11.0, 0.0 }, // 4
530  { -3.0, 1.0 }, // 5
531  { -3.0, 0.0 }, // 6
532  { -2.0, 1.0 }, // 7
533  { 1.0, 0.0 }, // 8
534  { 48.0, 1.0 }, // 14
535  {-22.0, 0.0 }, // 15
536  {-15.0, 9.0 }, // 17
537  {-12.0, 6.0 }, // 19
538  { -6.0, 3.0 }, // 20
539  { -5.0, 3.0 }, // 21
540  { 4.0, -2.0 }, // 22
541  { 4.0, -2.0 }, // 23
542  { -4.0, 0.0 }, // 24
543  { 1.0, 0.0 }, // 25
544  { 1.0, 0.0 }, // 26
545  { -1.0, 0.0 }, // 27
546  { 1.0, 0.0 }, // 28
547  { 1.0, 0.0 }, // 29
548  { -1.0, 0.0 }, // 30
549  {-158.0,-1.0 }, // 35
550  {123.0,-53.0 }, // 36
551  { 63.0, -2.0 }, // 37
552  {-59.0, 26.0 }, // 40
553  {-51.0, 27.0 }, // 41
554  {-38.0, 16.0 }, // 42
555  { 29.0, -1.0 }, // 43
556  { 29.0,-12.0 }, // 44
557  {-31.0, 13.0 }, // 45
558  { 26.0, -1.0 }, // 46
559  { 21.0,-10.0 }, // 47
560  { 16.0, -8.0 }, // 48
561  {-13.0, 7.0 }, // 49
562  {-10.0, 5.0 }, // 50
563  };
564 
565  const double secrad = 4.8481368111e-6; // arcsec -> radians
566  const double p2 = 2.0 * M_PI;
567 
568  double ls, lm, d, f, n, dpsi, deps, ep0;
569  int j;
570  Mat3 m1, m2, a;
571 
572  if (hpr)
573  {
574  lm = 2.355548393544 +
575  (8328.691422883903 + (0.000151795164 + 0.000000310281*t)*t)*t;
576  ls = 6.240035939326 +
577  (628.301956024185 + (-0.000002797375 - 0.000000058178*t)*t)*t;
578  f = 1.627901933972 +
579  (8433.466158318464 + (-0.000064271750 + 0.000000053330*t)*t)*t;
580  d = 5.198469513580 +
581  (7771.377146170650 + (-0.000033408511 + 0.000000092115*t)*t)*t;
582  n = 2.182438624361 +
583  (-33.757045933754 + (0.000036142860 + 0.000000038785*t)*t)*t;
584 
585  lm = fmod(lm,p2);
586  ls = fmod(ls,p2);
587  f = fmod(f,p2);
588  d = fmod(d,p2);
589  n = fmod(n,p2);
590 
591  dpsi = 0.0;
592  deps = 0.0;
593  for(j=0; j<ntb1; j++)
594  {
595  ep0 = tb1[j][0]*lm + tb1[j][1]*ls + tb1[j][2]*f + tb1[j][3]*d + tb1[j][4]*n;
596  dpsi = dpsi + (tb3[j][0]+tb3[j][1]*t) * sin(ep0);
597  deps = deps + (tb3[j][2]+tb3[j][3]*t) * cos(ep0);
598  };
599  for(j=0; j<ntb2; j++)
600  {
601  ep0 = tb2[j][0]*lm + tb2[j][1]*ls + tb2[j][2]*f + tb2[j][3]*d + tb2[j][4]*n;
602  dpsi = dpsi + tb4[j][0] * sin(ep0);
603  deps = deps + tb4[j][1] * cos(ep0);
604  };
605  dpsi = 1.0e-4 * dpsi * secrad;
606  deps = 1.0e-4 * deps * secrad;
607  }
608 
609  else // low precision
610  {
611  ls = p2 * frac (0.993133+99.997306*t); // mean anomaly sun
612  d = p2 * frac (0.827362+1236.853087*t); // diff long. moon-sun
613  f = p2 * frac (0.259089+1342.227826*t); // dist. node
614  n = p2 * frac (0.347346 - 5.372447*t); // long. node
615 
616  dpsi = (-17.2*sin(n) - 1.319*sin(2*(f-d+n)) - 0.227*sin(2*(f+n))
617  + 0.206*sin(2*n) + 0.143*sin(ls)) * secrad;
618  deps = (+9.203*cos(n) + 0.574*cos(2*(f-d+n)) + 0.098*cos(2*(f+n))
619  -0.09*cos(2*n) ) * secrad;
620  };
621 
622  ep0 = eps (t);
623  ep2 = ep0 + deps;
624  m1 = xrot (ep0);
625  m2 = zrot (-dpsi);
626  m1 *= m2;
627  m2 = xrot (-ep2);
628  a = m2 * m1;
629  ep2 = dpsi * cos (ep2);
630  ep2 *= 13750.9870831; // convert radians into time-seconds
631 
632  return a;
633  }
634 
635 /*---------------- Function nutecl --------------------------------------*/
636 
637 Mat3 nutecl (double t, double& ep2) // nutation matrix (ecliptic)
638  {
639  /*
640  Calculate nutation matrix a from mean to true ecliptic coordinates
641  at time t (in Julian Centuries from J2000.0)
642  Also calculates the correction ep2 for apparent sidereal time in sec
643  */
644 
645  const double secrad = 4.8481368111e-6; // arcsec -> radians
646  const double p2 = 2.0 * M_PI;
647 
648  double ls, d, f, n, dpsi, deps, ep0;
649  Mat3 m1, m2, a;
650 
651  ls = p2 * frac (0.993133+99.997306*t); // mean anomaly sun
652  d = p2 * frac (0.827362+1236.853087*t); // diff long. moon-sun
653  f = p2 * frac (0.259089+1342.227826*t); // dist. node
654  n = p2 * frac (0.347346 - 5.372447*t); // long. node
655 
656  dpsi = (-17.2*sin(n) - 1.319*sin(2*(f-d+n)) - 0.227*sin(2*(f+n))
657  + 0.206*sin(2*n) + 0.143*sin(ls)) * secrad;
658 
659  deps = (+9.203*cos(n) + 0.574*cos(2*(f-d+n)) + 0.098*cos(2*(f+n))
660  -0.09*cos(2*n) ) * secrad;
661 
662  ep0 = eps (t);
663  ep2 = ep0 + deps;
664  m1 = xrot (-deps);
665  m2 = zrot (-dpsi);
666  a = m1 * m2;
667  ep2 = dpsi * cos (ep2);
668  ep2 *= 13750.9870831; // convert radians into time-seconds
669 
670  return a;
671  }
672 
673 /*---------------- Function pmatequ --------------------------------------*/
674 
675 Mat3 PoleMx (double xp, double yp)
676  {
677  /* Returns Polar Motion matrix.
678  xp and yp are the coordinates of the Celestial Ephemeris Pole
679  with respect to the IERS Reference Pole in arcsec as published
680  in the IERS Bulletin B.
681  */
682  const double arctrd = M_PI / (180.0*3600.0);
683  Mat3 res;
684  double xr, yr;
685 
686  xr = xp * arctrd;
687  yr = yp * arctrd;
688  res.assign(1.0,0.0,xr,0.0,1.0,-yr,-xr,yr,1.0);
689 
690  return res;
691  }
692 
693 /*---------------- Function aberrat --------------------------------------*/
694 
695 Vec3 aberrat (double t, Vec3& ve) // aberration
696  {
697  /*
698  Correct position vector ve for aberration into new position va
699  at time t (in Julian Centuries from J2000.0)
700  */
701  const double p2 = 2.0 * M_PI;
702 
703  double l, cl, d0;
704  Vec3 va;
705 
706  d0 = abs(ve);
707  l = p2 * frac(0.27908+100.00214*t);
708  cl = cos(l)*d0;
709  va[0] = ve[0] - 9.934e-5 * sin(l) * d0;
710  va[1] = ve[1] + 9.125e-5 * cl;
711  va[2] = ve[2] + 3.927e-5 * cl;
712 
713  return va;
714  }
715 
716 /*--------------------- Function GeoPos ----------------------------------*/
717 
718 Vec3 GeoPos (double jd, double ep2, double lat, double lng, double ht)
719  {
720  /* Return the geocentric vector (in the equatorial system) of the
721  geographic position given by the latitude lat and longitude lng
722  (in radians) and height ht (in m) at the MJD-time jd (UT).
723  ep2 : correction for apparent sidereal time in sec
724 
725  The length unit of the vector is in terms of the equatorial
726  Earth radius (6378.137 km)
727  */
728  double const e2 = 6.69438499959e-3;
729  double np, h, sp;
730 
731  Vec3 r;
732 
733  sp = sin(lat);
734  h = ht / 6378.137e3;
735  np = 1.0 / (sqrt(1.0 - e2*sp*sp));
736  r[2] = ((1.0 - e2)*np + h)*sp;
737 
738  sp = (np + h) * cos(lat);
739  np = lsidtim(jd, (lng*180.0/M_PI), ep2) * M_PI/12.0;
740 
741  r[0] = sp * cos(np);
742  r[1] = sp * sin(np);
743 
744  return r;
745  }
746 
747 Vec3 GeoPos (double jd, double ep2, double lat, double lng, double ht,
748  double xp, double yp)
749  {
750  /* Return the geocentric vector (in the equatorial system) of the
751  geographic position given by the latitude lat and longitude lng
752  (in radians) and height ht (in m) at the MJD-time jd (UT).
753 
754  ep2 : correction for apparent sidereal time in sec
755  xp, yp: coordinates of polar motion in arcsec.
756 
757  The length unit of the vector is in terms of the equatorial
758  Earth radius (6378.137 km)
759  */
760  double const e2 = 6.69438499959e-3;
761  double np, h, sp;
762  Mat3 prx;
763  Vec3 r;
764 
765  sp = sin(lat);
766  h = ht / 6378.137e3;
767  np = 1.0 / (sqrt(1.0 - e2*sp*sp));
768  r[2] = ((1.0 - e2)*np + h)*sp;
769  sp = (np + h) * cos(lat);
770  r[0] = sp * cos(lng);
771  r[1] = sp * sin(lng);
772 
773  // correct for polar motion
774  if ((xp != 0) || (yp != 0))
775  {
776  prx = mxtrn(PoleMx(xp, yp));
777  r = mxvct(prx, r);
778  };
779 
780  // convert into equatorial
781  np = lsidtim(jd, 0.0, ep2) * M_PI/12.0;
782  prx = zrot(-np);
783  r = mxvct(prx, r);
784 
785  return r;
786  }
787 
788 /*--------------------- Function EquHor ----------------------------------*/
789 
790 Vec3 EquHor (double jd, double ep2, double lat, double lng, Vec3 r)
791  {
792  /* convert vector r from the equatorial system into the horizontal system.
793  jd = MJD-time (UT)
794  ep2 : correction for apparent sidereal time in sec
795  lat, lng : geographic latitude and longitude (in radians)
796  */
797  double lst;
798  Vec3 s;
799  Mat3 mx;
800 
801  lst = lsidtim(jd, (lng*180.0/M_PI), ep2) * M_PI/12.0;
802  mx = zrot(lst);
803  s = mxvct(mx, r);
804  mx = yrot(M_PI/2.0 - lat);
805  s = mxvct(mx, s);
806 
807  return s;
808  }
809 
810 /*--------------------- Function HorEqu ----------------------------------*/
811 
812 
813 Vec3 HorEqu (double jd, double ep2, double lat, double lng, Vec3 r)
814  {
815  /* convert vector r from the horizontal system into the equatorial system.
816  jd = MJD-time (UT)
817  ep2 : correction for apparent sidereal time in sec
818  lat, lng : geographic latitude and longitude (in radians)
819  */
820  double lst;
821  Vec3 s;
822  Mat3 mx;
823 
824  mx = yrot(lat - M_PI/2.0);
825  s = mxvct(mx, r);
826  lst = -lsidtim(jd, (lng*180.0/M_PI), ep2) * M_PI/12.0;
827  mx = zrot(lst);
828  s = mxvct(mx, s);
829 
830  return s;
831  }
832 
833 /*--------------------- Function AppPos ----------------------------------*/
834 
835 void AppPos (double jd, double ep2, double lat, double lng, double ht,
836  int solsys, Vec3 r, double& azim, double& elev, double& dist)
837  {
838  /* get apparent position in the horizontal system
839  jd = MJD-time (UT)
840  ep2 : correction for apparent sidereal time in sec
841  lat, lng : geographic latitude and longitude (in radians)
842  ht : height above normal in meters.
843  solsys : = 1 if object is in solar system and parallax has to be
844  taken into account, 0 otherwise.
845  r = vector of celestial object. The unit of lenght of this vector
846  has to be in terms of the equatorial Earth radius (6378.14 km)
847  if solsys = 1, otherwise it's arbitrary.
848  azim : azimuth in radians (0 is to the North).
849  elev : elevation in radians
850  dist : distance (if solsys = 1; otherwise abs(r))
851  */
852  Vec3 s;
853 
854  // correct for topocentric position (parallax)
855  if (solsys) s = r - GeoPos(jd, ep2, lat, lng, ht);
856  else s = r;
857 
858  s = EquHor(jd, ep2, lat, lng, s);
859  s = carpol(s);
860  dist = s[0];
861  elev = s[2];
862  azim = M_PI - s[1];
863  }
864 
865 /*--------------------- Function AppRADec ----------------------------------*/
866 
867 void AppRADec (double jd, double ep2, double lat, double lng,
868  double azim, double elev, double& ra, double& dec)
869  {
870  /* get apparent position in the horizontal system
871  jd = MJD-time (UT)
872  ep2 : correction for apparent sidereal time in sec
873  lat, lng : geographic latitude and longitude (in radians)
874  azim : azimuth in radians (0 is to the North).
875  elev : elevation in radians
876  ra : Right Ascension (in radians)
877  dec : Declination (in radians)
878  */
879  Vec3 s;
880 
881  s[0] = 1.0;
882  s[1] = M_PI - azim;
883  s[2] = elev;
884  s = polcar(s);
885  s = HorEqu(jd, ep2, lat, lng, s);
886  s = carpol(s);
887  dec = s[2];
888  ra = s[1];
889  }
890 
891 /*------------------------- Refract ---------------------------------*/
892 
893 double Refract (double h, double p, double t)
894  {
895  /* Calculate atmospheric refraction with low precision
896  h = height (in radians) of object
897  p = presure (in millibars)
898  t = temperature (in degrees Celsius)
899 
900  RETURN: refraction angle in radians
901  */
902  double const raddeg = 180.0 / M_PI;
903  double r;
904 
905  r = h * raddeg;
906  r = (r + 7.31 / (r + 4.4)) / raddeg;
907  r = (0.28*p/(t+273.0)) * 0.0167 / tan(r);
908  r = r / raddeg;
909 
910  return r;
911  }
912 
913 /*---------------- Function eccanom --------------------------------------*/
914 
915 double eccanom (double man, double ecc)
916  {
917  /*
918  Solve Kepler equation for eccentric anomaly of elliptical orbits.
919  man : Mean Anomaly (in radians)
920  ecc : eccentricity
921  */
922  const double p2 = 2.0*M_PI;
923  const double eps = 1E-11;
924  const int maxit = 15;
925 
926  double m, e, f;
927  int i, mi;
928 
929  m=man/p2;
930  mi = int(m);
931  m=p2*(m-mi);
932  if (m < 0) m=m+p2;
933  if (ecc < 0.8) e=m;
934  else e=M_PI;
935  f = e - ecc*sin(e) - m;
936  i=0;
937 
938  while ((fabs(f) > eps) && (i < maxit))
939  {
940  e = e - f / (1.0 - ecc*cos(e));
941  f = e - ecc*sin(e) - m;
942  i = i + 1;
943  }
944 
945  return e;
946  }
947 
948 
949 /*---------------- Function hypanom --------------------------------------*/
950 
951 double hypanom (double mh, double ecc)
952  {
953  /*
954  Solve Kepler equation for eccentric anomaly of hyperbolic orbits.
955  mh : Mean Anomaly
956  ecc : eccentricity
957  */
958  const double eps = 1E-11;
959  const int maxit = 15;
960 
961  double h, f;
962  int i;
963 
964  h = log (2.0*fabs(mh)/ecc+1.8);
965  if (mh < 0.0) h = -h;
966  f = ecc * sinh(h) - h - mh;
967  i = 0;
968 
969  while ((fabs(f) > eps*(1.0+fabs(h+mh))) && (i < maxit))
970  {
971  h = h - f / (ecc*cosh(h) - 1.0);
972  f = ecc*sinh(h) - h - mh;
973  i = i + 1;
974  }
975 
976  return h;
977  }
978 
979 
980 /*------------------ Function ellip ------------------------------------*/
981 
982 void ellip (double gm, double t0, double t, double a, double ecc,
983  double m0, Vec3& r1, Vec3& v1)
984  {
985  /*
986  Calculate position r1 and velocity v1 of for elliptic orbit at time t.
987  gm : Gravitational Constant
988  t0 : epoch
989  a : semim-ajor axis
990  ecc : eccentricity
991  m0 : Mean Anomaly at epoch (in radians).
992  The units must be consistent with each other.
993  */
994  double m, e, fac, k, c, s;
995 
996  if (fabs(a) < 1e-60) a = 1e-60;
997  k = gm / a;
998  if (k >= 0) k = sqrt(k);
999  else k = 0; // just in case
1000 
1001  m = k * (t - t0) / a + m0;
1002  e = eccanom(m, ecc);
1003  fac = sqrt(1.0 - ecc*ecc);
1004  c = cos(e);
1005  s = sin(e);
1006  r1.assign (a*(c - ecc), a*fac*s, 0.0);
1007  m = 1.0 - ecc*c;
1008  v1.assign (-k*s/m, k*fac*c/m, 0.0);
1009  }
1010 
1011 /*---------------- Function hyperb --------------------------------------*/
1012 
1013 void hyperb (double gm, double t0, double t, double a, double ecc,
1014  Vec3& r1, Vec3& v1)
1015  {
1016  /*
1017  Calculate position r1 and velocity v1 of for hyperbolic orbit at time t.
1018  gm : Gravitational Constant
1019  t0 : time of perihelion passage
1020  a : semi-major axis
1021  ecc : eccentricity
1022  The units must be consistent with each other.
1023  */
1024  double mh, h, fac, k, c, s;
1025 
1026  a = fabs(a);
1027  if (a < 1e-60) a = 1e-60;
1028  k = gm / a;
1029  if (k >= 0) k = sqrt(k);
1030  else k = 0; // just in case
1031 
1032  mh = k * (t - t0) / a;
1033  h = hypanom (mh, ecc);
1034  fac = sqrt(ecc*ecc-1.0);
1035  c = cosh(h);
1036  s = sinh(h);
1037  r1.assign (a*(ecc-c), a*fac*s, 0.0);
1038  mh = ecc*c - 1.0;
1039  v1.assign (-k*s/mh, k*fac*c/mh, 0.0);
1040  }
1041 
1042 /*---------------- Function parab --------------------------------------*/
1043 
1044  void stumpff (double e2, double& c1, double& c2, double& c3)
1045  {
1046  /*
1047  Calculation of Stumpff functions c1=sin(e)/c,
1048  c2=(1-cos(e))/e^2 and c3=(e-sin(e))/e^3 for the
1049  argument e2=e^2 (e: eccentric anomaly)
1050  */
1051  const double eps=1E-12;
1052  double n, add;
1053 
1054  c1=0.0; c2=0.0; c3=0.0; add=1.0; n=1.0;
1055  do
1056  {
1057  c1=c1+add; add=add/(2.0*n);
1058  c2=c2+add; add=add/(2.0*n+1);
1059  c3=c3+add; add=-e2*add;
1060  n=n+1.0;
1061  } while (abs(add)>eps);
1062  }
1063 
1064 void parab (double gm, double t0, double t, double q, double ecc,
1065  Vec3& r1, Vec3& v1)
1066  {
1067  /*
1068  Calculate position r1 and velocity v1 of for parabolic
1069  (or near parabolic) orbit at time t using Stumpff's method.
1070  gm : Gravitational Constant
1071  t0 : time of perihelion passage
1072  q : perihelion distance
1073  ecc : eccentricity
1074  The units must be consistent with each other.
1075  */
1076  const double eps = 1E-9;
1077  const int maxit = 15;
1078 
1079  double e2, e20, fac, c1, c2, c3, k, tau, a, u, u2;
1080  double x, y;
1081  int i, fle;
1082 
1083  ecc = fabs(ecc);
1084  e2=0.0; fac=0.5*ecc; i=0;
1085 
1086  q = fabs(q);
1087  if (q < 1e-40) q = 1e-40;
1088  k = gm / (q*(1+ecc));
1089 
1090  if (k >= 0) k = sqrt(k);
1091  else k = 0; // just in case
1092 
1093  tau = gm / (q*q*q);
1094  if (tau >= 0) tau= 1.5*sqrt(tau)*(t-t0);
1095  else tau = 0;
1096 
1097  do
1098  {
1099  i = i + 1;
1100  e20 = e2;
1101  if (fac < 0.0) a = -1.0;
1102  else a = tau * sqrt(fac);
1103  a = sqrt(a*a+1.0)+a;
1104  if (a > 0.0) a = exp(log(a)/3.0);
1105  if (a == 0.0) u = 0.0;
1106  else u = a - 1.0/a;
1107  u2 = u*u;
1108  if (fac != 0) e2 = u2*(1.0-ecc)/fac;
1109  else e2 = 1;
1110  stumpff (e2, c1, c2, c3);
1111  fac = 3.0*ecc*c3;
1112  fle = (abs(e2-e20) < eps) || (i > maxit);
1113  } while (!fle);
1114 
1115  if (fac != 0)
1116  {
1117  tau = q*(1.0+u2*c2*ecc/fac);
1118  x = q*(1.0-u2*c2/fac);
1119  y = (1.0+ecc)/fac;
1120  if (y >= 0) y = q*sqrt(y)*u*c1;
1121  else y = 0;
1122  r1.assign (x, y, 0.0);
1123  v1.assign (-k*y/tau, k*(x/tau+ecc), 0.0);
1124  }
1125  else // just in case
1126  {
1127  r1.assign (0, 0, 0);
1128  v1.assign (0, 0, 0);
1129  };
1130  }
1131 
1132 /*---------------- Function kepler --------------------------------------*/
1133 
1134 void kepler (double gm, double t0, double t, double m0, double a, double ecc,
1135  double ran, double aper, double inc, Vec3& r1, Vec3& v1)
1136  {
1137  /*
1138  Calculate position r1 and velocity v1 of body at time t as an
1139  undisturbed 2-body Kepler problem.
1140 
1141  gm : Gravitational Constant
1142  t0 : time of perihelion passage (hyperbolic or near-parabolic)
1143  epoch of m0 for elliptical orbits.
1144  m0 : Mean Anomaly at epoch for elliptical orbits in degrees in the
1145  range 0 to 360. If m0 < 0 the calculations will be done as
1146  near-parabolic. Set m0 = 0 for hyperbolic orbits.
1147  a : semi-major axis for elliptical (positive) or hyperbolic orbits
1148  (negative). If m0 < 0, a signifies perihelion distance q instead
1149  ecc : eccentricity
1150  ran : Right Ascension of Ascending Node (in degrees)
1151  aper : Argument of Perihelion (in degrees)
1152  inc : Inclination (in degrees)
1153 
1154  The units must be consistent with each other.
1155 
1156  NOTE : If ecc = 1 the orbit will always be calculated as a parabolic one.
1157  If ecc < 1 (elliptical orbits) two possibilities exist:
1158  If m0 >= 0 the calculation will be done in the classical
1159  way with m0 signifying the mean anomaly at time t0 and
1160  a the semi-major axis.
1161  If m0 < 0 the orbit will be calculated as a near-parabolic
1162  orbit with a signifying the perihelion distance at time t0.
1163  (This latter method will be useful for high eccentricity
1164  comet orbits for which typically q is given instead of a)
1165  If ecc > 1 (hyperbolic orbits) two possibilities exist:
1166  If m0 >= 0 (the value is ignored for hyperbolic orbits)
1167  a classical hyperbolic calculation is performed with a
1168  signifying the semi-major axis (negative for hyperbolas).
1169  If m0 < 0 the orbit will be calculated as a near-parabolic
1170  orbit with a signifying the perihelion distance. (This can
1171  be useful for comet orbits which would rarely have an
1172  eccentricity >> 1)
1173  In either case t0 signifies the time of perihelion passage.
1174  */
1175  const double dgrd = M_PI / 180.0;
1176  enum {ell, par, hyp} kepc;
1177  Mat3 m1,m2;
1178 
1179  kepc = ell; // just to keep the compiler happy
1180 
1181  // convert into radians
1182  m0 *= dgrd;
1183  ran *= dgrd;
1184  aper *= dgrd;
1185  inc *= dgrd;
1186 
1187  // calculate the position and velocity within the orbit plane
1188  if (ecc == 1.0) kepc = par;
1189  if (ecc < 1.0)
1190  {
1191  if (m0 < 0.0) kepc = par;
1192  else kepc = ell;
1193  }
1194  if (ecc > 1.0)
1195  {
1196  if (m0 < 0.0) kepc = par;
1197  else kepc = hyp;
1198  }
1199 
1200  switch (kepc)
1201  {
1202  case ell : ellip (gm, t0, t, a, ecc, m0, r1, v1); break;
1203  case par : parab (gm, t0, t, a, ecc, r1, v1); break;
1204  case hyp : hyperb (gm, t0, t, a, ecc, r1, v1); break;
1205  }
1206 
1207  // convert into reference plane
1208  m1 = zrot (-aper);
1209  m2 = xrot (-inc);
1210  m1 *= m2;
1211  m2 = zrot (-ran);
1212  m2 = m2 * m1;
1213 
1214  r1 = mxvct (m2, r1);
1215  v1 = mxvct (m2, v1);
1216  }
1217 
1218 /*---------------- Function oscelm --------------------------------------*/
1219 
1220 void oscelm (double gm, double t, Vec3& r1, Vec3& v1,
1221  double& t0, double& m0, double& a, double& ecc,
1222  double& ran, double& aper, double& inc)
1223  {
1224  /*
1225  Get the osculating Kepler elements at epoch t from position r1 and
1226  velocity v1 of body.
1227 
1228  gm : Gravitational Constant. If set negative, its absolute value will
1229  be taken as gm and the perihelion distance will be returned
1230  instead of the semimajor axis.
1231  t0 : time of perihelion passage
1232  m0 : Mean Anomaly at epoch for elliptical orbits in degrees in the
1233  range 0 to 360. Set m0 = 0 for hyperbolic orbits.
1234  m0 will be set to -1 if perihelion distance is to be returned
1235  instead of a.
1236  a : semi-major axis for elliptical (positive) or hyperbolic orbits
1237  (negative). If m0 < 0, a signifies perihelion distance q instead.
1238  If gm is negative, the perihelion distance q will be returned
1239  ecc : eccentricity
1240  ran : Right Ascension of Ascending Node (in degrees)
1241  aper : Argument of Perihelion (in degrees)
1242  inc : Inclination (in degrees)
1243 
1244  The units must be consistent with each other.
1245  */
1246  const double rddg = 180.0/M_PI;
1247  const double p2 = 2.0*M_PI;
1248 
1249  Vec3 c;
1250  double cabs, u, cu, su, p, r;
1251  int pflg; // 1, if perihelion distance to be returned
1252 
1253  pflg = 0;
1254  if (gm < 0.0)
1255  {
1256  gm = -gm;
1257  pflg = 1;
1258  };
1259 
1260  if (gm < 1e-60) gm = 1e-60;
1261  c = r1 * v1;
1262  cabs = abs(c);
1263  if (fabs(cabs) < 1e-40) cabs = 1e-40;
1264  ran = atan20 (c[0], -c[1]);
1265  inc = c[2]/cabs;
1266  if (fabs(inc) <= 1.0) inc = acos (inc);
1267  else inc = 0;
1268 
1269  r = abs(r1);
1270  if (fabs(r) < 1e-40) r = 1e-40;
1271  su = sin(inc);
1272  if (su != 0.0) su = r1[2]/su;
1273  cu = r1[0]*cos(ran)+r1[1]*sin(ran);
1274  u = atan20 (su, cu); // argument of latitude
1275 
1276  a = abs(v1);
1277  a = 2.0/r - a*a/gm;
1278  if (fabs(a) < 1.0E-30) ecc = 1.0; // parabolic
1279  else
1280  {
1281  a = 1.0/a; // semimajor axis
1282  ecc = 0;
1283  };
1284 
1285  p = cabs*cabs/gm; // semilatum rectum
1286 
1287  if (ecc == 1.0)
1288  {
1289  p = p / 2.0; // perihelion distance
1290  a = 2*p;
1291  }
1292  else
1293  {
1294  ecc = 1.0 - p/a;
1295  if (ecc >= 0) ecc = sqrt(ecc);
1296  else ecc = 0;
1297  p = p / (1.0 + ecc); // perihelion distance
1298  }
1299 
1300  if (fabs(a) > 1e-60) cu = (1.0 - r/a);
1301  else cu = 0; // just in case
1302  su = dot(r1,v1) / sqrt(fabs(a)*gm);
1303  if (ecc < 1.0)
1304  {
1305  m0 = atan20(su,cu); // eccentric anomaly
1306  su = sin(m0);
1307  cu = cos(m0);
1308  aper = 1.0-ecc*ecc;
1309  if (aper >= 0) aper = atan20(sqrt(aper)*su,(cu-ecc)); // true anomaly
1310  m0 = m0 - ecc*su; // mean anomaly
1311  }
1312  else if (ecc > 1.0)
1313  {
1314  su = su / ecc;
1315  m0 = su + sqrt(su*su + 1.0);
1316  if (m0 >= 0) m0 = log(m0); // = asinh (su); hyperbolic anomaly
1317  aper = (ecc+1.0)/(ecc-1.0);
1318  if (aper >= 0) aper = 2.0 * atan(sqrt(aper)*tanh(m0/2.0));
1319  m0 = ecc*su-m0;
1320  }
1321 
1322  if (ecc != 1.0)
1323  {
1324  aper = u - aper; // argument of perihelion
1325  u = fabs(a);
1326  t0 = u/gm;
1327  if (t0 >= 0) t0 = t - u*sqrt(t0)*m0; // time of perihelion transit
1328  else t0 = t;
1329  }
1330  else // parabolic
1331  {
1332  pflg = 1;
1333 
1334  aper = 2.0 * atan(su); // true anomaly
1335  aper = u - aper; // argument of perihelion
1336  t0 = 2.0*p*p*p/gm;
1337  if (t0 >= 0) t0 = t - sqrt(t0) * (su*su*su/3.0 + su);
1338  else t0 = t;
1339  }
1340 
1341  if (m0 < 0.0) m0 = m0 + p2;
1342  if (ran < 0.0) ran = ran + p2;
1343  if (aper < 0.0) aper = aper + p2;
1344  m0 = rddg * m0;
1345  ran = rddg * ran;
1346  aper = rddg * aper;
1347  inc = rddg * inc;
1348 
1349  if (ecc > 1.0) m0 = 0.0;
1350  if (pflg)
1351  {
1352  a = p;
1353  m0 = -1.0;
1354  }
1355  }
1356 
1357 /*-------------------- QuickSun --------------------------------------*/
1358 
1359 Vec3 QuickSun (double t) // low precision position of the Sun at time t
1360  {
1361  /* Low precision position of the Sun at time t given in
1362  Julian centuries since J2000.
1363  Valid only between 1950 and 2050.
1364 
1365  Returns the position vector (in A.U.) in ecliptic coordinates
1366 
1367  */
1368  double n, g, l;
1369  Vec3 rs;
1370 
1371  n = 36525.0 * t;
1372  l = 280.460 + 0.9856474*n; // mean longitude
1373  g = 357.528 + 0.9856003*n; // mean anomaly
1374  l = 2.0*M_PI * frac(l/360.0);
1375  g = 2.0*M_PI * frac(g/360.0);
1376  l = l + (1.915*sin(g) + 0.020*sin(2.0*g)) * 1.74532925199e-2; // ecl.long.
1377  g = 1.00014 - 0.01671*cos(g) - 0.00014*cos(2.0*g); // radius
1378  rs[0] = g * cos(l);
1379  rs[1] = g * sin(l);
1380  rs[2] = 0;
1381 
1382  return rs;
1383  }
1384 
1385 /*-------------------- Class Sun200 --------------------------------------*/
1386  /*
1387  Ecliptic coordinates (in A.U.) and velocity (in A.U./day)
1388  of the sun for Equinox of Date given in Julian centuries since J2000.
1389  ======================================================================
1390  */
1391 Sun200::Sun200 ()
1392  { }
1393 
1394 Vec3 Sun200::position (double t) // position of the Sun at time t
1395  {
1396  Vec3 rs, vs;
1397 
1398  state (t, rs, vs);
1399 
1400  return rs;
1401  }
1402 
1403 void Sun200::state (double t, Vec3& rs, Vec3& vs)
1404  {
1405  /* State vector rs (position) and vs (velocity) of the Sun in
1406  ecliptic of date coordinates at time t (in Julian Centruries
1407  since J2000).
1408  */
1409  const double p2 = 2.0 * M_PI;
1410 
1411  double l, b, r;
1412  int i;
1413 
1414  tt = t;
1415 
1416  dl = 0.0; dr = 0.0; db = 0.0;
1417  m2 = p2 * frac(0.1387306 + 162.5485917*t);
1418  m3 = p2 * frac(0.9931266 + 99.9973604*t);
1419  m4 = p2 * frac(0.0543250 + 53.1666028*t);
1420  m5 = p2 * frac(0.0551750 + 8.4293972*t);
1421  m6 = p2 * frac(0.8816500 + 3.3938722*t);
1422  d = p2 * frac(0.8274 + 1236.8531*t);
1423  a= p2 * frac(0.3749 + 1325.5524*t);
1424  uu = p2 * frac(0.2591 + 1342.2278*t);
1425 
1426  c3[1] = 1.0; s3[1] = 0.0;
1427  c3[2] = cos(m3); s3[2] = sin(m3);
1428  c3[0] = c3[2]; s3[0] = -s3[2];
1429 
1430  for (i=3; i<9; i++)
1431  addthe(c3[i-1],s3[i-1],c3[2],s3[2],c3[i],s3[i]);
1432  pertven(); pertmar(); pertjup(); pertsat(); pertmoo();
1433 
1434  dl = dl + 6.4 * sin(p2*(0.6983 + 0.0561*t))
1435  + 1.87 * sin(p2*(0.5764 + 0.4174*t))
1436  + 0.27 * sin(p2*(0.4189 + 0.3306*t))
1437  + 0.20 * sin(p2*(0.3581 + 2.4814*t));
1438  l = p2 * frac(0.7859453 + m3/p2 +((6191.2+1.1*t)*t+dl)/1296.0E3);
1439  r = 1.0001398 - 0.0000007*t + dr*1E-6;
1440  b = db * 4.8481368111E-6;
1441 
1442  cl= cos(l); sl=sin(l); cb=cos(b); sb=sin(b);
1443  rs[0]=r*cl*cb; rs[1]=r*sl*cb; rs[2]=r*sb;
1444 
1445  /* velocity calculation
1446  gms=2.9591202986e-4 AU^3/d^2
1447  e=0.0167086
1448  sqrt(gms/a)=1.7202085e-2 AU/d
1449  sqrt(gms/a)*sqrt(1-e^2)=1.71996836e-2 AU/d
1450  nu=M + 2e*sin(M) = M + 0.0334172 * sin(M) */
1451 
1452  uu = m3 + 0.0334172*sin(m3); // eccentric Anomaly E
1453  d = cos(uu);
1454  uu = sin(uu);
1455  a = 1.0 - 0.0167086*d;
1456  vs[0] = -1.7202085e-2*uu/a; // velocity in orbit plane
1457  vs[1] = 1.71996836e-2*d/a;
1458  uu = atan2 (0.9998604*uu, (d-0.0167086)); // true anomaly
1459  d = cos(uu);
1460  uu = sin(uu);
1461  dr = d*vs[0]+uu*vs[1];
1462  dl = (d*vs[1]-uu*vs[0]) / r;
1463 
1464  vs[0] = dr*cl*cb - dl*r*sl*cb;
1465  vs[1] = dr*sl*cb + dl*r*cl*cb;
1466  vs[2] = dr*sb;
1467  }
1468 
1469 void Sun200::addthe (double c1, double s1, double c2, double s2,
1470  double& cc, double& ss)
1471  {
1472  cc=c1*c2-s1*s2;
1473  ss=s1*c2+c1*s2;
1474  }
1475 
1476 void Sun200::term (int i1, int i, int it, double dlc, double dls, double drc,
1477  double drs, double dbc, double dbs)
1478  {
1479  if (it == 0) addthe (c3[i1+1],s3[i1+1],c[i+8],s[i+8],u,v);
1480  else
1481  {
1482  u=u*tt;
1483  v=v*tt;
1484  }
1485  dl = dl + dlc*u + dls*v;
1486  dr = dr + drc*u + drs*v;
1487  db = db + dbc*u + dbs*v;
1488  }
1489 
1490 void Sun200::pertven() // Kepler terms and perturbations by Venus
1491  {
1492  int i;
1493 
1494  c[8]=1.0; s[8]=0.0; c[7]=cos(m2); s[7]=-sin(m2);
1495  for (i=7; i>2; i--)
1496  addthe(c[i],s[i],c[7],s[7],c[i-1],s[i-1]);
1497 
1498  term (1, 0, 0, -0.22, 6892.76, -16707.37, -0.54, 0.0, 0.0);
1499  term (1, 0, 1, -0.06, -17.35, 42.04, -0.15, 0.0, 0.0);
1500  term (1, 0, 2, -0.01, -0.05, 0.13, -0.02, 0.0, 0.0);
1501  term (2, 0, 0, 0.0, 71.98, -139.57, 0.0, 0.0, 0.0);
1502  term (2, 0, 1, 0.0, -0.36, 0.7, 0.0, 0.0, 0.0);
1503  term (3, 0, 0, 0.0, 1.04, -1.75, 0.0, 0.0, 0.0);
1504  term (0, -1, 0, 0.03, -0.07, -0.16, -0.07, 0.02, -0.02);
1505  term (1, -1, 0, 2.35, -4.23, -4.75, -2.64, 0.0, 0.0);
1506  term (1, -2, 0, -0.1, 0.06, 0.12, 0.2, 0.02, 0.0);
1507  term (2, -1, 0, -0.06, -0.03, 0.2, -0.01, 0.01, -0.09);
1508  term (2, -2, 0, -4.7, 2.9, 8.28, 13.42, 0.01, -0.01);
1509  term (3, -2, 0, 1.8, -1.74, -1.44, -1.57, 0.04, -0.06);
1510  term (3, -3, 0, -0.67, 0.03, 0.11, 2.43, 0.01, 0.0);
1511  term (4, -2, 0, 0.03, -0.03, 0.1, 0.09, 0.01, -0.01);
1512  term (4, -3, 0, 1.51, -0.4, -0.88, -3.36, 0.18, -0.1);
1513  term (4, -4, 0, -0.19, -0.09, -0.38, 0.77, 0.0, 0.0);
1514  term (5, -3, 0, 0.76, -0.68, 0.3, 0.37, 0.01, 0.0);
1515  term (5, -4, 0, -0.14, -0.04, -0.11, 0.43, -0.03, 0.0);
1516  term (5, -5, 0, -0.05, -0.07, -0.31, 0.21, 0.0, 0.0);
1517  term (6, -4, 0, 0.15, -0.04, -0.06, -0.21, 0.01, 0.0);
1518  term (6, -5, 0, -0.03, -0.03, -0.09, 0.09, -0.01, 0.0);
1519  term (6, -6, 0, 0.0, -0.04, -0.18, 0.02, 0.0, 0.0);
1520  term (7, -5, 0, -0.12, -0.03, -0.08, 0.31, -0.02, -0.01);
1521  }
1522 
1523 void Sun200::pertmar() // Kepler terms and perturbations by Mars
1524  {
1525  int i;
1526 
1527  c[7] = cos(m4); s[7] = -sin(m4);
1528  for (i=7; i>0; i--)
1529  addthe(c[i],s[i],c[7],s[7],c[i-1],s[i-1]);
1530  term (1, -1, 0, -0.22, 0.17, -0.21, -0.27, 0.0, 0.0);
1531  term (1, -2, 0, -1.66, 0.62, 0.16, 0.28, 0.0, 0.0);
1532  term (2, -2, 0, 1.96, 0.57, -1.32, 4.55, 0.0, 0.01);
1533  term (2, -3, 0, 0.4, 0.15, -0.17, 0.46, 0.0, 0.0);
1534  term (2, -4, 0, 0.53, 0.26, 0.09, -0.22, 0.0, 0.0);
1535  term (3, -3, 0, 0.05, 0.12, -0.35, 0.15, 0.0, 0.0);
1536  term (3, -4, 0, -0.13, -0.48, 1.06, -0.29, 0.01, 0.0);
1537  term (3, -5, 0, -0.04, -0.2, 0.2, -0.04, 0.0, 0.0);
1538  term (4, -4, 0, 0.0, -0.03, 0.1, 0.04, 0.0, 0.0);
1539  term (4, -5, 0, 0.05, -0.07, 0.2, 0.14, 0.0, 00);
1540  term (4, -6, 0, -0.1, 0.11, -0.23, -0.22, 0.0, 0.0);
1541  term (5, -7, 0, -0.05, 0.0, 0.01, -0.14, 0.0, 0.0);
1542  term (5, -8, 0, 0.05, 0.01, -0.02, 0.1, 0.0, 0.0);
1543  }
1544 
1545 void Sun200::pertjup() // Kepler terms and perturbations by Jupiter
1546  {
1547  int i;
1548 
1549  c[7] = cos(m5); s[7] = -sin(m5);
1550  for (i=7; i>4; i--)
1551  addthe(c[i],s[i],c[7],s[7],c[i-1],s[i-1]);
1552  term (1, -1, 0, 0.01, 0.07, 0.18, -0.02, 0.0, -0.02);
1553  term (0, -1, 0, -0.31, 2.58, 0.52, 0.34, 0.02, 0.0);
1554  term (1, -1, 0, -7.21, -0.06, 0.13, -16.27, 0.0, -0.02);
1555  term (1, -2, 0, -0.54, -1.52, 3.09, -1.12, 0.01, -0.17);
1556  term (1, -3, 0, -0.03, -0.21, 0.38, -0.06, 0.0, -0.02);
1557  term (2, -1, 0, -0.16, 0.05, -0.18, -0.31, 0.01, 0.0);
1558  term (2, -2, 0, 0.14, -2.73, 9.23, 0.48, 0.0, 0.0);
1559  term (2, -3, 0, 0.07, -0.55, 1.83, 0.25, 0.01, 0.0);
1560  term (2, -4, 0, 0.02, -0.08, 0.25, 0.06, 0.0, 0.0);
1561  term (3, -2, 0, 0.01, -0.07, 0.16, 0.04, 0.0, 0.0);
1562  term (3, -3, 0, -0.16, -0.03, 0.08, -0.64, 0.0, 0.0);
1563  term (3, -4, 0, -0.04, -0.01, 0.03, -0.17, 0.0, 0.0);
1564  }
1565 
1566 void Sun200::pertsat() // Kepler terms and perturbations by Saturn
1567  {
1568  c[7] = cos(m6); s[7] = -sin(m6);
1569  addthe(c[7],s[7],c[7],s[7],c[6],s[6]);
1570  term (0, -1, 0, 0.0, 0.32, 0.01, 0.0, 0.0, 0.0);
1571  term (1, -1, 0, -0.08, -0.41, 0.97, -0.18, 0.0, -0.01);
1572  term (1, -2, 0, 0.04, 0.1, -0.23, 0.1, 0.0, 0.0);
1573  term (2, -2, 0, 0.04, 0.1, -0.35, 0.13, 0.0, 0.0);
1574  }
1575 
1576 void Sun200::pertmoo() // corrections for Earth-Moon center of gravity
1577  {
1578  dl = dl + 6.45*sin(d) - 0.42*sin(d-a) + 0.18*sin(d+a) + 0.17*sin(d-m3) - 0.06*sin(d+m3);
1579  dr = dr + 30.76*cos(d) - 3.06*cos(d-a) + 0.85*cos(d+a) - 0.58*cos(d+m3) + 0.57*cos(d-m3);
1580  db = db + 0.576*sin(uu);
1581  }
1582 
1583 /*--------------------- Class moon200 ----------------------------------*/
1584 
1585  /*
1586  Position vector (in Earth radii) of the Moon referred to Ecliptic
1587  for Equinox of Date.
1588  t is the time in Julian centuries since J2000.
1589  */
1590 
1591 Moon200::Moon200 ()
1592  { }
1593 
1594 Vec3 Moon200::position (double t) // position of the Moon at time t
1595  {
1596  Vec3 rm;
1597 
1598  const double arc = 206264.81; // 3600*180/pi = ''/r
1599  const double pi2 = M_PI * 2.0;
1600 
1601  double lambda, beta, r, fac;
1602 
1603  minit(t);
1604  solar1(); solar2(); solar3(); solarn(n); planetary(t);
1605 
1606  lambda = pi2 * frac ((l0+dlam/arc) / pi2);
1607  if (lambda < 0) lambda = lambda + pi2;
1608  s = f + ds / arc;
1609 
1610  fac = 1.000002708 + 139.978 * dgam;
1611  beta = (fac*(18518.511+1.189+gam1c)*sin(s)-6.24*sin(3*s)+n);
1612  beta = beta * 4.8481368111e-6;
1613  sinpi = sinpi * 0.999953253;
1614  r = arc / sinpi;
1615 
1616  rm.assign (r, lambda, beta);
1617  rm = polcar(rm);
1618 
1619  return rm;
1620  }
1621 
1622 
1623 void Moon200::addthe (double c1, double s1, double c2, double s2,
1624  double& c, double& s)
1625  {
1626  c=c1*c2-s1*s2;
1627  s=s1*c2+c1*s2;
1628  }
1629 
1630 double Moon200::sinus (double phi)
1631  {
1632  /* sin(phi) in units of 1r = 360ø */
1633  return sin (2.0*M_PI * frac(phi));
1634  }
1635 
1636 void Moon200::long_periodic (double t)
1637  {
1638  /* long periodic changes of mean elements */
1639 
1640  double s1, s2, s3, s4, s5, s6, s7;
1641 
1642  s1 = sinus (0.19833 + 0.05611*t);
1643  s2 = sinus (0.27869 + 0.04508*t);
1644  s3 = sinus (0.16827 - 0.36903*t);
1645  s4 = sinus (0.34734 - 5.37261*t);
1646  s5 = sinus (0.10498 - 5.37899*t);
1647  s6 = sinus (0.42681 - 0.41855*t);
1648  s7 = sinus (0.14943 - 5.37511*t);
1649  dl0 = 0.84*s1 + 0.31*s2 + 14.27*s3 + 7.26*s4 + 0.28*s5 + 0.24*s6;
1650  dl = 2.94*s1 + 0.31*s2 + 14.27*s3 + 9.34*s4 + 1.12*s5 + 0.83*s6;
1651  dls = -6.4*s1 - 1.89*s6;
1652  df = 0.21*s1+0.31*s2+14.27*s3-88.7*s4-15.3*s5+0.24*s6-1.86*s7;
1653  dd = dl0 - dls;
1654  dgam = -3332E-9 * sinus (0.59734 - 5.37261*t)
1655  -539E-9 * sinus (0.35498 - 5.37899*t)
1656  -64E-9 * sinus (0.39943 - 5.37511*t);
1657  }
1658 
1659 void Moon200::minit(double t)
1660  {
1661  /* calculate mean elements l (moon), F (node distance)
1662  l' (sun) and D (moon's elongation) */
1663 
1664  const double arc = 206264.81; // 3600*180/pi = ''/r
1665  const double pi2 = M_PI * 2.0;
1666 
1667  int i, j, max;
1668  double t2, arg, fac;
1669 
1670  max = 0; // just to keep the compiler happy
1671  arg = 0;
1672  fac = 0;
1673 
1674  t2 = t * t;
1675  dlam = 0; ds = 0; gam1c = 0; sinpi = 3422.7;
1676  long_periodic (t);
1677  l0 = pi2*frac(0.60643382+1336.85522467*t-0.00000313*t2) + dl0/arc;
1678  l = pi2*frac(0.37489701+1325.55240982*t+0.00002565*t2) + dl/arc;
1679  ls = pi2*frac(0.99312619+99.99735956*t-0.00000044*t2) + dls/arc;
1680  f = pi2*frac(0.25909118+1342.22782980*t-0.00000892*t2) + df/arc;
1681  d = pi2*frac(0.82736186+1236.85308708*t-0.00000397*t2) + dd/arc;
1682  for (i=0; i<4; i++)
1683  {
1684  switch (i)
1685  {
1686  case 0: arg=l; max=4; fac=1.000002208; break;
1687  case 1: arg=ls; max=3; fac=0.997504612-0.002495388*t; break;
1688  case 2: arg=f; max=4; fac=1.000002708+139.978*dgam; break;
1689  case 3: arg=d; max=6; fac=1.0; break;
1690  }
1691  co[6][i] = 1.0; co[7][i] = cos (arg) * fac;
1692  si[6][i] = 0.0; si[7][i] = sin (arg) * fac;
1693  for (j = 2; j <= max; j++)
1694  addthe(co[j+5][i],si[j+5][i],co[7][i],si[7][i],co[j+6][i],si[j+6][i]);
1695  for (j = 1; j <= max; j++)
1696  {
1697  co[6-j][i]=co[j+6][i];
1698  si[6-j][i]=-si[j+6][i];
1699  }
1700  }
1701  }
1702 
1703 void Moon200::term (int p, int q, int r, int s, double& x, double& y) const
1704  {
1705  // calculate x=cos(p*arg1+q*arg2...); y=sin(p*arg1+q*arg2...)
1706  int i[4];
1707  int k;
1708 
1709  i[0]=p; i[1]=q; i[2]=r; i[3]=s; x=1.0; y=0.0;
1710  for (k=0; k<4; k++)
1711  if (i[k]!=0) addthe(x,y,co[i[k]+6][k],si[i[k]+6][k],x,y);
1712  }
1713 
1714 void Moon200::addsol(double coeffl, double coeffs, double coeffg,
1715  double coeffp, int p, int q, int r, int s)
1716  {
1717  double x, y;
1718  term (p,q,r,s,x,y);
1719  dlam = dlam + coeffl*y; ds = ds + coeffs*y;
1720  gam1c = gam1c + coeffg*x; sinpi = sinpi + coeffp*x;
1721  }
1722 
1723 void Moon200::solar1()
1724  {
1725  addsol ( 13.902, 14.06, -0.001, 0.2607, 0, 0, 0, 4);
1726  addsol ( 0.403, -4.01, 0.394, 0.0023, 0, 0, 0, 3);
1727  addsol ( 2369.912, 2373.36, 0.601, 28.2333, 0, 0, 0, 2);
1728  addsol ( -125.154, -112.79, -0.725, -0.9781, 0, 0, 0, 1);
1729  addsol ( 1.979, 6.98, -0.445, 0.0433, 1, 0, 0, 4);
1730  addsol (191.953, 192.72, 0.029, 3.0861, 1, 0, 0, 2);
1731  addsol (-8.466, -13.51, 0.455, -0.1093, 1, 0, 0, 1);
1732  addsol (22639.5, 22609.07, 0.079, 186.5398, 1, 0, 0, 0);
1733  addsol (18.609, 3.59, -0.094, 0.0118, 1, 0, 0, -1);
1734  addsol (-4586.465, -4578.13, -0.077, 34.3117, 1, 0, 0, -2);
1735  addsol (3.215, 5.44, 0.192, -0.0386, 1, 0, 0, -3);
1736  addsol (-38.428, -38.64, 0.001, 0.6008, 1, 0, 0, -4);
1737  addsol (-0.393, -1.43, -0.092, 0.0086, 1, 0, 0, -6);
1738  addsol (-0.289, -1.59, 0.123, -0.0053, 0, 1, 0, 4);
1739  addsol (-24.420, -25.1, 0.04, -0.3, 0, 1, 0, 2);
1740  addsol (18.023, 17.93, 0.007, 0.1494, 0, 1, 0, 1);
1741  addsol (-668.146, -126.98, -1.302, -0.3997, 0, 1, 0, 0);
1742  addsol (0.56, 0.32, -0.001, -0.0037, 0, 1, 0, -1);
1743  addsol (-165.145, -165.06, 0.054, 1.9178, 0, 1, 0, -2);
1744  addsol (-1.877, -6.46, -0.416, 0.0339, 0, 1, 0, -4);
1745  addsol (0.213, 1.02, -0.074, 0.0054, 2, 0, 0, 4);
1746  addsol (14.387, 14.78, -0.017, 0.2833, 2, 0, 0, 2);
1747  addsol (-0.586, -1.2, 0.054, -0.01, 2, 0, 0, 1);
1748  addsol (769.016, 767.96, 0.107, 10.1657, 2, 0, 0, 0);
1749  addsol (1.75, 2.01, -0.018, 0.0155, 2, 0, 0, -1);
1750  addsol (-211.656, -152.53, 5.679, -0.3039, 2, 0, 0, -2);
1751  addsol (1.225, 0.91, -0.03, -0.0088, 2, 0, 0, -3);
1752  addsol (-30.773, -34.07, -0.308, 0.3722, 2, 0, 0, -4);
1753  addsol (-0.57, -1.4, -0.074, 0.0109, 2, 0, 0, -6);
1754  addsol (-2.921, -11.75, 0.787, -0.0484, 1, 1, 0, 2);
1755  addsol (1.267, 1.52, -0.022, 0.0164, 1, 1, 0, 1);
1756  addsol (-109.673, -115.18, 0.461, -0.949, 1, 1, 0, 0);
1757  addsol (-205.962, -182.36, 2.056, 1.4437, 1, 1, 0, -2);
1758  addsol (0.233, 0.36, 0.012, -0.0025, 1, 1, 0, -3);
1759  addsol (-4.391, -9.66, -0.471, 0.0673, 1, 1, 0, -4);
1760  }
1761 
1762 void Moon200::solar2()
1763  {
1764  addsol (0.283, 1.53, -0.111, 0.006, 1, -1, 0, 4);
1765  addsol (14.577, 31.7, -1.54, 0.2302, 1, -1, 0, 2);
1766  addsol (147.687, 138.76, 0.679, 1.1528, 1, -1, 0, 0);
1767  addsol (-1.089, 0.55, 0.021, 0.0, 1, -1, 0, -1);
1768  addsol (28.475, 23.59, -0.443, -0.2257, 1, -1, 0, -2);
1769  addsol (-0.276, -0.38, -0.006, -0.0036, 1, -1, 0, -3);
1770  addsol (0.636, 2.27, 0.146, -0.0102, 1, -1, 0, -4);
1771  addsol (-0.189, -1.68, 0.131, -0.0028, 0, 2, 0, 2);
1772  addsol (-7.486, -0.66, -0.037, -0.0086, 0, 2, 0, 0);
1773  addsol (-8.096, -16.35, -0.74, 0.0918, 0, 2, 0, -2);
1774  addsol (-5.741, -0.04, 0.0, -0.0009, 0, 0, 2, 2);
1775  addsol (0.255, 0.0, 0.0, 0.0, 0, 0, 2, 1);
1776  addsol (-411.608, -0.2, 0.0, -0.0124, 0, 0, 2, 0);
1777  addsol (0.584, 0.84, 0.0, 0.0071, 0, 0, 2, -1);
1778  addsol (-55.173, -52.14, 0.0, -0.1052, 0, 0, 2, -2);
1779  addsol (0.254, 0.25, 0.0, -0.0017, 0, 0, 2, -3);
1780  addsol (0.025, -1.67, 0.0, 0.0031, 0, 0, 2, -4);
1781  addsol (1.06, 2.96, -0.166, 0.0243, 3, 0, 0, 2);
1782  addsol (36.124, 50.64, -1.3, 0.6215, 3, 0, 0, 0);
1783  addsol (-13.193, -16.4, 0.258, -0.1187, 3, 0, 0, -2);
1784  addsol (-1.187, -0.74, 0.042, 0.0074, 3, 0, 0, -4);
1785  addsol (-0.293, -0.31, -0.002, 0.0046, 3, 0, 0, -6);
1786  addsol (-0.29, -1.45, 0.116, -0.0051, 2, 1, 0, 2);
1787  addsol (-7.649, -10.56, 0.259, -0.1038, 2, 1, 0, 0);
1788  addsol (-8.627, -7.59, 0.078, -0.0192, 2, 1, 0, -2);
1789  addsol (-2.74, -2.54, 0.022, 0.0324, 2, 1, 0, -4);
1790  addsol (1.181, 3.32, -0.212, 0.0213, 2, -1, 0, 2);
1791  addsol (9.703, 11.67, -0.151, 0.1268, 2, -1, 0, 0);
1792  addsol (-0.352, -0.37, 0.001, -0.0028, 2, -1, 0, -1);
1793  addsol (-2.494, -1.17, -0.003, -0.0017, 2, -1, 0, -2);
1794  addsol (0.36, 0.2, -0.012, -0.0043, 2, -1, 0, -4);
1795  addsol (-1.167, -1.25, 0.008, -0.0106, 1, 2, 0, 0);
1796  addsol (-7.412, -6.12, 0.117, 0.0484, 1, 2, 0, -2);
1797  addsol (-0.311, -0.65, -0.032, 0.0044, 1, 2, 0, -4);
1798  addsol (0.757, 1.82, -0.105, 0.0112, 1, -2, 0, 2);
1799  addsol (2.58, 2.32, 0.027, 0.0196, 1, -2, 0, 0);
1800  addsol (2.533, 2.4, -0.014, -0.0212, 1, -2, 0, -2);
1801  addsol (-0.344, -0.57, -0.025, 0.0036, 0, 3, 0, -2);
1802  addsol (-0.992, -0.02, 0.0, 0.0, 1, 0, 2, 2);
1803  addsol (-45.099, -0.02, 0.0, -0.0010, 1, 0, 2, 0);
1804  addsol (-0.179, -9.52, 0.0, -0.0833, 1, 0, 2, -2);
1805  addsol (-0.301, -0.33, 0.0, 0.0014, 1, 0, 2, -4);
1806  addsol (-6.382, -3.37, 0.0, -0.0481, 1, 0, -2, 2);
1807  addsol (39.528, 85.13, 0.0, -0.7136, 1, 0, -2, 0);
1808  addsol (9.366, 0.71, 0.0, -0.0112, 1, 0, -2, -2);
1809  addsol (0.202, 0.02, 0.0, 0.0, 1, 0, -2, -4);
1810  }
1811 
1812 void Moon200::solar3()
1813  {
1814  addsol (0.415, 0.1, 0.0, 0.0013, 0, 1, 2, 0);
1815  addsol (-2.152, -2.26, 0.0, -0.0066, 0, 1, 2, -2);
1816  addsol (-1.44, -1.3, 0.0, 0.0014, 0, 1, -2, 2);
1817  addsol (0.384, -0.04, 0.0, 0.0, 0, 1, -2, -2);
1818  addsol (1.938, 3.6, -0.145, 0.0401, 4, 0, 0, 0);
1819  addsol (-0.952, -1.58, 0.052, -0.0130, 4, 0, 0, -2);
1820  addsol (-0.551, -0.94, 0.032, -0.0097, 3, 1, 0, 0);
1821  addsol (-0.482, -0.57, 0.005, -0.0045, 3, 1, 0, -2);
1822  addsol (0.681, 0.96, -0.026, 0.0115, 3, -1, 0, 0);
1823  addsol (-0.297, -0.27, 0.002, -0.0009, 2, 2, 0, -2);
1824  addsol (0.254, 0.21, -0.003, 0.0, 2, -2, 0, -2);
1825  addsol (-0.25, -0.22, 0.004, 0.0014, 1, 3, 0, -2);
1826  addsol (-3.996, 0.0, 0.0, 0.0004, 2, 0, 2, 0);
1827  addsol (0.557, -0.75, 0.0, -0.009, 2, 0, 2, -2);
1828  addsol (-0.459, -0.38, 0.0, -0.0053, 2, 0, -2, 2);
1829  addsol (-1.298, 0.74, 0.0, 0.0004, 2, 0, -2, 0);
1830  addsol (0.538, 1.14, 0.0, -0.0141, 2, 0, -2, -2);
1831  addsol (0.263, 0.02, 0.0, 0.0, 1, 1, 2, 0);
1832  addsol (0.426, 0.07, 0.0, -0.0006, 1, 1, -2, -2);
1833  addsol (-0.304, 0.03, 0.0, 0.0003, 1, -1, 2, 0);
1834  addsol (-0.372, -0.19, 0.0, -0.0027, 1, -1, -2, 2);
1835  addsol (0.418, 0.0, 0.0, 0.0, 0, 0, 4, 0);
1836  addsol (-0.330, -0.04, 0.0, 0.0, 3, 0, 2, 0);
1837  }
1838 
1839 void Moon200::addn (double coeffn, int p, int q, int r, int s,
1840  double& n, double&x, double& y) const
1841  {
1842  term (p,q,r,s,x,y);
1843  n=n+coeffn*y;
1844  }
1845 
1846 void Moon200::solarn (double& n) const
1847  {
1848  // perturbation N of ecliptic latitude
1849  double x, y;
1850 
1851  n = 0.0;
1852  addn (-526.069, 0, 0, 1, -2, n, x, y);
1853  addn (-3.352, 0, 0, 1, -4, n, x, y);
1854  addn (44.297, 1, 0, 1, -2, n, x, y);
1855  addn (-6.0, 1, 0, 1, -4, n, x, y);
1856  addn (20.599, -1, 0, 1, 0, n, x, y);
1857  addn (-30.598, -1, 0, 1, -2, n, x, y);
1858  addn (-24.649, -2, 0, 1, 0, n, x, y);
1859  addn (-2.0, -2, 0, 1, -2, n, x, y);
1860  addn (-22.571, 0, 1, 1, -2, n, x, y);
1861  addn (10.985, 0, -1, 1, -2, n, x, y);
1862  }
1863 
1864 void Moon200::planetary (double t)
1865  {
1866  // perturbations of the ecliptic longitude by Venus and Jupiter
1867 
1868  dlam = dlam
1869  + 0.82*sinus(0.7736 -62.5512*t)+0.31*sinus(0.0466-125.1025*t)
1870  + 0.35*sinus(0.5785-25.1042*t)+0.66*sinus(0.4591+1335.8075*t)
1871  + 0.64*sinus(0.313-91.568*t)+1.14*sinus(0.148+1331.2898*t)
1872  + 0.21*sinus(0.5918+1056.5859*t)+0.44*sinus(0.5784+1322.8595*t)
1873  + 0.24*sinus(0.2275-5.7374*t)+0.28*sinus(0.2965+2.6929*t)
1874  + 0.33*sinus(0.3132+6.3368*t);
1875  }
1876 
1877 /*-------------------- Class Eclipse --------------------------------------*/
1878 /*
1879  Calculalations for Solar and Lunar Eclipses
1880  */
1881 
1882 Eclipse::Eclipse()
1883  {
1884  // some assignments just in case
1885  rs.assign(1,0,0);
1886  rm.assign(1,0,0);
1887  eshadow.assign (1,0,0);
1888  rint.assign (1,0,0);
1889  d_umbra = 0;
1890  ep2 = 0;
1891  }
1892 
1893 int Eclipse::solar (double jd, double tdut, double& phi, double& lamda)
1894  {
1895  /* Calculates various items about a solar eclipse.
1896  INPUT:
1897  jd = Modified Julian Date (UT)
1898  tdut = TDT - UT in sec
1899 
1900  OUTPUT:
1901  phi, lamda: Geographic latitude and longitude (in radians)
1902  of center of shadow if central eclipse
1903 
1904  RETURN:
1905  0 : No eclipse
1906  1 : Partial eclipse
1907  2 : Non-central annular eclipse
1908  3 : Non-central total eclipse
1909  4 : Annular eclipse
1910  5 : Total eclipse
1911  */
1912 
1913  const double flat = 0.996633; // flatting of the Earth
1914  const double ds = 218.245445; // diameter of Sun in Earth radii
1915  const double dm = 0.544986; // diameter of Moon in Earth radii
1916  double s0, s, dlt, r2, r0;
1917  int phase;
1918  Vec3 ve;
1919 
1920  // get the apparent equatorial coordinates of the sun and the moon
1921  equ_sun_moon(jd, tdut);
1922 
1923  rs[2]/=flat; // adjust for flatting of the Earth
1924  rm[2]/=flat;
1925  rint.assign ();
1926  lamda = 0;
1927  phi = 0;
1928 
1929  // intersect shadow axis with Earth
1930  eshadow = rm - rs;
1931  eshadow = vnorm(eshadow); // direction vector of shadow
1932 
1933  s0 = - dot(rm, eshadow); // distance Moon - fundamental plane
1934  r2 = dot (rm,rm);
1935  dlt = s0*s0 + 1.0 - r2;
1936  r0 = 1.0 - dlt;
1937  if (r0 > 0) r0 = sqrt (r0);
1938  else r0 = 0; // distance center of Earth - shadow axis
1939 
1940  r2 = abs(rs - rm);
1941  d_umbra = (ds - dm) * s0 / r2 - dm;// diameter of umbra at fundamental plane
1942  d_penumbra = (ds + dm) * s0 / r2 + dm;
1943 
1944  // get phase of eclipse
1945  if (r0 < 1.0)
1946  {
1947  if (dlt > 0) dlt = sqrt(dlt);
1948  else dlt = 0;
1949  s = s0 - dlt; // distance Moon - fundamental plane
1950  d_umbra = (ds - dm) * s / r2 - dm; // diameter of umbra at surface
1951  rint = rm + s * eshadow;
1952  rint[2] *= flat; // vector to intersection
1953  ve = carpol(rint);
1954  lamda = ve[1] - lsidtim(jd,0,ep2)*0.261799387799; // geographic coordinates
1955  if (lamda > M_PI) lamda -= 2.0*M_PI;
1956  if (lamda < (-M_PI)) lamda += 2.0*M_PI;
1957  phi = sqrt(rint[0]*rint[0] + rint[1]*rint[1])*0.993305615;
1958  phi = atan2(rint[2],phi);
1959 
1960  if (d_umbra > 0) phase = 4; // central annular eclipse
1961  else phase = 5; // central total eclipse
1962  }
1963  else
1964  {
1965  if (r0 < (1.0 + 0.5 * fabs(d_umbra)))
1966  {
1967  if (d_umbra > 0) phase = 2; // non-central annular eclipse
1968  else phase = 3; // non-central total eclipse
1969  }
1970  else
1971  {
1972  if (r0 < (1.0 + 0.5*d_penumbra)) phase = 1; // partial eclipse
1973  else phase = 0; // no eclipse
1974  }
1975  }
1976 
1977  rs[2]*=flat; // restore from flatting of the Earth
1978  rm[2]*=flat;
1979 
1980  return phase;
1981  }
1982 
1983 void Eclipse::maxpos (double jd, double tdut, double& phi, double& lamda)
1984  {
1985  /* Calculates the geographic position of the place of maximum eclipse
1986  at the time jd for a non-central eclipse. (NOTE that in case of
1987  a central eclipse the maximum position will be calculated by
1988  function solar. Do not use this function in that case as the
1989  result would be incorrect! No check is being done in this routine
1990  whether an eclipse is visible at all. Use maxpos only in case of a
1991  confirmed partial or non-central eclipse.
1992 
1993  INPUT:
1994  jd = Modified Julian Date (UT)
1995  tdut = TDT - UT in sec
1996 
1997  OUTPUT:
1998  phi, lamda: Geographic latitude and longitude (in radians)
1999  of maximum eclipse at the time
2000  */
2001 
2002  const double flat = 0.996633; // flatting of the Earth
2003  double s0;
2004  Vec3 ve;
2005 
2006  // get the apparent equatorial coordinates of the sun and the moon
2007  equ_sun_moon(jd, tdut);
2008 
2009  rs[2]/=flat; // adjust for flatting of the Earth
2010  rm[2]/=flat;
2011  rint.assign ();
2012  lamda = 0;
2013  phi = 0;
2014 
2015  // intersect shadow axis with Earth
2016  eshadow = rm - rs;
2017  eshadow = vnorm(eshadow); // direction vector of shadow
2018 
2019  s0 = - dot(rm, eshadow); // distance Moon - fundamental plane
2020  rint = rm + s0 * eshadow;
2021  rint = vnorm(rint); // normalize to 1 Earth radius
2022  rint[2] *= flat; // vector to position of maximum eclipse
2023  ve = carpol(rint);
2024 
2025  lamda = ve[1] - lsidtim(jd,0,ep2)*0.261799387799; // geographic coordinates
2026  if (lamda > M_PI) lamda -= 2.0*M_PI;
2027  if (lamda < (-M_PI)) lamda += 2.0*M_PI;
2028  phi = sqrt(rint[0]*rint[0] + rint[1]*rint[1])*0.993305615;
2029  phi = atan2(rint[2],phi);
2030 
2031  rs[2]*=flat; // restore from flatting of the Earth
2032  rm[2]*=flat;
2033  }
2034 
2035 void Eclipse::penumd (double jd, double tdut, Vec3& vrm, Vec3& ves,
2036  double& dpn, double& pang)
2037  {
2038  /* Calculates various items needed for finding out the northern and
2039  southern border of the penumbra during a solar eclipse.
2040 
2041  INPUT:
2042  jd = Modified Julian Date (UT)
2043  tdut = TDT - UT in sec
2044 
2045  OUTPUT:
2046  vrm = position vector of Moon adjusted for flattening
2047  ves = unit vector pointing into the direction of the center of the shadow
2048  dpn = diameter of the penumbra at the fundamental plane
2049  pang = angle of penumbral half-cone in radians
2050  */
2051 
2052  const double flat = 0.996633; // flatting of the Earth
2053  const double ds = 218.245445; // diameter of Sun in Earth radii
2054  const double dm = 0.544986; // diameter of Moon in Earth radii
2055  double s0, r2;
2056 
2057  // get the apparent equatorial coordinates of the sun and the moon
2058  equ_sun_moon(jd, tdut);
2059  rs[2]/=flat; // adjust for flatting of the Earth
2060  rm[2]/=flat;
2061 
2062  // intersect shadow axis with Earth
2063  eshadow = rm - rs;
2064  pang = abs(eshadow);
2065  eshadow = vnorm(eshadow); // direction vector of shadow
2066  ves = eshadow;
2067  vrm = rm;
2068 
2069  s0 = - dot(rm, eshadow); // distance Moon - fundamental plane
2070 
2071  r2 = abs(rs - rm);
2072  dpn = (ds + dm) * s0 / r2 + dm;
2073 
2074  // penumbral angle
2075  pang = asin((dm + ds) / (2.0 * pang));
2076 
2077  rs[2]*=flat; // restore from flatting of the Earth
2078  rm[2]*=flat;
2079  }
2080 
2081 void Eclipse::umbra (double jd, double tdut, Vec3& vrm, Vec3& ves,
2082  double& dpn, double& pang)
2083  {
2084  /* Calculates various items needed for finding out the northern and
2085  southern border of the umbra during a solar eclipse.
2086 
2087  INPUT:
2088  jd = Modified Julian Date (UT)
2089  tdut = TDT - UT in sec
2090 
2091  OUTPUT:
2092  vrm = position vector of Moon adjusted for flattening
2093  ves = unit vector pointing into the direction of the center of the shadow
2094  dpn = diameter of the umbra at the fundamental plane
2095  pang = angle of umbral half-cone in radians
2096  */
2097 
2098  const double flat = 0.996633; // flatting of the Earth
2099  const double ds = 218.245445; // diameter of Sun in Earth radii
2100  const double dm = 0.544986; // diameter of Moon in Earth radii
2101  double s0, r2;
2102 
2103  // get the apparent equatorial coordinates of the sun and the moon
2104  equ_sun_moon(jd, tdut);
2105  rs[2]/=flat; // adjust for flatting of the Earth
2106  rm[2]/=flat;
2107 
2108  // intersect shadow axis with Earth
2109  eshadow = rm - rs;
2110  pang = abs(eshadow);
2111  eshadow = vnorm(eshadow); // direction vector of shadow
2112  ves = eshadow;
2113  vrm = rm;
2114 
2115  s0 = - dot(rm, eshadow); // distance Moon - fundamental plane
2116 
2117  r2 = abs(rs - rm);
2118  dpn = (ds - dm) * s0 / r2 - dm;
2119 
2120  // umbral angle
2121  pang = asin((ds - dm) / (2.0 * pang));
2122 
2123  rs[2]*=flat; // restore from flatting of the Earth
2124  rm[2]*=flat;
2125  }
2126 
2127 void Eclipse::equ_sun_moon(double jd, double tdut)
2128  {
2129  /* Get the equatorial coordinates of the Sun and the Moon and
2130  store them in rs and rm.
2131  Also store the time t in Julian Centuries and the correction
2132  ep2 for the Apparent Sidereal Time.
2133  jd = Modified Julian Date (UT)
2134  tdut = TDT - UT in sec
2135  */
2136  const double ae = 23454.77992; // 149597870.0/6378.14 = 1AE -> Earth Radii
2137  Mat3 mx;
2138 
2139  t = julcent (jd) + tdut / 3.15576e9; // =(86400.0 * 36525.0);
2140  rs = sun.position(t);
2141  rm = moon.position(t);
2142  rs = eclequ(t,rs);
2143  rm = eclequ(t,rm);
2144 
2145  // correct Moon coordinates for center of figure
2146  mx = zrot(-2.4240684e-6); // +0.5" in longitude
2147  rm = mxvct(mx,rm);
2148  mx = yrot(-1.2120342e-6); // -0.25" in latitude
2149  rm = mxvct(mx,rm);
2150  mx = nutmat(t,ep2); // nutation
2151  rs = mxvct(mx,rs); // apparent coordinates
2152  rs = aberrat(t,rs);
2153  rs *= ae;
2154  rm = mxvct(mx,rm);
2155  }
2156 
2157 double Eclipse::duration (double jd, double tdut, double& width)
2158  {
2159  /* Get the duration of a central eclipse at the center point
2160  for MJD jd and TDT-UT tdut in seconds.
2161  Also return the width of the umbra in km.
2162  A call to solar with the respective jd must have been done
2163  prior to calling this function !!!
2164  */
2165  const double omega = 4.3755e-3; // radial velocity of Earth in rad/min.
2166 
2167  double dur, lm, pa, umbold;
2168  Vec3 rold, eold, rsold, rmold;
2169  Mat3 mx;
2170 
2171  // save old values for jd
2172  rold = rint;
2173  eold = eshadow;
2174  umbold = d_umbra;
2175  rsold = rs;
2176  rmold = rm;
2177 
2178  dur = 0.1; // 0.1 min
2179  if (solar(jd+dur/1440.0,tdut, lm, pa) > 3)
2180  {
2181  mx = zrot(dur*omega);
2182  rint = mxvct(mx,rint);
2183  rint -= rold;
2184  pa = dot (rint, eold);
2185  lm = dot (rint, rint) - pa*pa;
2186  if (lm > 0) lm = sqrt(lm);
2187  else lm = 0;
2188  if (lm > 0) dur = fabs(umbold) / lm * dur * 60.0;
2189  else dur = 0;
2190  }
2191 
2192  else dur = -1;
2193 
2194  // restore old values for jd
2195  d_umbra = umbold;
2196  eshadow = eold;
2197  eold = rold*rint; // direction perpendicular of apparent shadow movement
2198  rint = rold;
2199  rs = rsold;
2200  rm = rmold;
2201 
2202  // get width of umbra at center location
2203  rold = vnorm (eold);
2204  pa = dot(rold,eshadow);
2205  if (pa > 1.0) pa = 1.0;
2206  if (pa < -1.0) pa = -1.0;
2207  pa = fabs(sin(acos(pa)));
2208  if (pa < 0.00001) pa = 0.00001;
2209  width = d_umbra / pa * 6378.14; // allow for projection
2210  width = fabs(width);
2211 
2212  return dur;
2213  }
2214 
2215 Vec3 Eclipse::GetRSun () const // get Earth - Sun vector in Earth radii
2216  {
2217  return rs;
2218  }
2219 
2220 Vec3 Eclipse::GetRMoon () const // get Earth - Moon vector in Earth radii
2221  {
2222  return rm;
2223  }
2224 
2225 double Eclipse::GetEp2 () const // get the ep2 value
2226  {
2227  return ep2;
2228  }
2229 
2230 int Eclipse::lunar (double jd, double tdut)
2231  {
2232  /* check whether lunar eclipse is in progress at
2233  Modified Julian Date jd (UT).
2234  tdut = TDT - UT in sec
2235 
2236  RETURN:
2237  0 : No eclipse
2238  1 : Partial Penumbral Eclipse
2239  2 : Total Penumbral Eclipse
2240  3 : Partial Umbral Eclipse
2241  4 : Total Umbral Eclipse
2242  */
2243 
2244  const double dm = 0.544986; // diameter of Moon in Earth radii
2245  const double ds = 218.245445; // diameter of Sun in Earth radii
2246 
2247  double umbra, penumbra;
2248  double r2, s0, sep;
2249  int phase;
2250 
2251  // get position of Sun and Moon
2252  equ_sun_moon(jd, tdut);
2253 
2254  // get radius of umbra and penumbra
2255  r2 = abs(rs);
2256  s0 = abs (rm);
2257  umbra = 1.02*fabs((ds - 2.0) * s0 / r2 - 2.0)*0.5; // radius of umbra
2258  penumbra = 1.02*fabs((ds + 2.0) * s0 / r2 + 2.0)*0.5;//radius of penumbra
2259  /* (the factor 1.02 allows for enlargment of shadow due to
2260  Earth's atmosphere) */
2261 
2262  // get angular seperation of center of shadow and Moon
2263  r2 = abs(rm);
2264  sep = dot(rs,rm)/(abs(rs)*r2);
2265  if (fabs(sep) > 1.0) sep = 1.0;
2266  sep = acos(sep); // in radians
2267  sep = fabs(tan(sep)*r2); // distance of Moon and shadow in Earth radii
2268 
2269  // Now check the kind of eclipse
2270  if (sep < (umbra - dm/2.0)) phase = 4;
2271  else if (sep < (umbra + dm/2.0)) phase = 3;
2272  else if (sep < (penumbra - dm/2.0)) phase = 2;
2273  else if (sep < (penumbra + dm/2.0)) phase = 1;
2274  else phase = 0;
2275 
2276  return phase;
2277  }
2278 
2279 
stumpff
void stumpff(double e2, double &c1, double &c2, double &c3)
Definition: astrolib.cpp:1044
Sun200::state
void state(double t, Vec3 &rs, Vec3 &vs)
Definition: astrolib.cpp:1403
Refract
double Refract(double h, double p, double t)
Definition: astrolib.cpp:893
Mat3
Definition: attlib.h:63
GeoPos
Vec3 GeoPos(double jd, double ep2, double lat, double lng, double ht)
Definition: astrolib.cpp:718
Eclipse::duration
double duration(double jd, double tdut, double &width)
Definition: astrolib.cpp:2157
parab
void parab(double gm, double t0, double t, double q, double ecc, Vec3 &r1, Vec3 &v1)
Definition: astrolib.cpp:1064
Eclipse::Eclipse
Eclipse()
Definition: astrolib.cpp:1882
equecl
Vec3 equecl(double t, Vec3 &r1)
Definition: astrolib.cpp:358
Eclipse::GetRSun
Vec3 GetRSun() const
Definition: astrolib.cpp:2215
eclequ
Vec3 eclequ(double t, Vec3 &r1)
Definition: astrolib.cpp:341
Vec3
Definition: attlib.h:27
Moon200::position
Vec3 position(double t)
Definition: astrolib.cpp:1594
Sun200::Sun200
Sun200()
Definition: astrolib.cpp:1391
Eclipse::solar
int solar(double jd, double tdut, double &phi, double &lamda)
Definition: astrolib.cpp:1893
yrot
Mat3 yrot(double a)
Definition: attlib.cpp:509
atan20
double atan20(double y, double x)
Definition: attlib.cpp:25
ddd
double ddd(int d, int m, double s)
Definition: astrolib.cpp:35
astrolib.h
lsidtim
double lsidtim(double jd, double lambda, double ep2)
Definition: astrolib.cpp:302
HorEqu
Vec3 HorEqu(double jd, double ep2, double lat, double lng, Vec3 r)
Definition: astrolib.cpp:813
Eclipse::GetEp2
double GetEp2() const
Definition: astrolib.cpp:2225
eps
double eps(double t)
Definition: astrolib.cpp:325
Eclipse::lunar
int lunar(double jd, double tdut)
Definition: astrolib.cpp:2230
DefTdUt
double DefTdUt(int yi)
Definition: astrolib.cpp:223
PoleMx
Mat3 PoleMx(double xp, double yp)
Definition: astrolib.cpp:675
Eclipse::GetRMoon
Vec3 GetRMoon() const
Definition: astrolib.cpp:2220
ellip
void ellip(double gm, double t0, double t, double a, double ecc, double m0, Vec3 &r1, Vec3 &v1)
Definition: astrolib.cpp:982
carpol
Vec3 carpol(const Vec3 &c)
Definition: attlib.cpp:184
vnorm
Vec3 vnorm(const Vec3 &c)
Definition: attlib.cpp:170
attlib.h
Eclipse::maxpos
void maxpos(double jd, double tdut, double &phi, double &lamda)
Definition: astrolib.cpp:1983
zrot
Mat3 zrot(double a)
Definition: attlib.cpp:530
pmatequ
Mat3 pmatequ(double t1, double t2)
Definition: astrolib.cpp:408
oscelm
void oscelm(double gm, double t, Vec3 &r1, Vec3 &v1, double &t0, double &m0, double &a, double &ecc, double &ran, double &aper, double &inc)
Definition: astrolib.cpp:1220
QuickSun
Vec3 QuickSun(double t)
Definition: astrolib.cpp:1359
frac
double frac(double f)
Definition: astrolib.cpp:30
Mat3::assign
void assign(double x11, double x12, double x13, double x21, double x22, double x23, double x31, double x32, double x33)
Definition: attlib.cpp:249
caldat
void caldat(double mjd, int &day, int &month, int &year, double &hour)
Definition: astrolib.cpp:145
nutecl
Mat3 nutecl(double t, double &ep2)
Definition: astrolib.cpp:637
pmatecl
Mat3 pmatecl(double t1, double t2)
Definition: astrolib.cpp:375
abs
double abs(const Vec3 &c)
Definition: attlib.cpp:100
nutmat
Mat3 nutmat(double t, double &ep2, bool hpr)
Definition: astrolib.cpp:437
mxtrn
Mat3 mxtrn(const Mat3 &m1)
Definition: attlib.cpp:379
kepler
void kepler(double gm, double t0, double t, double m0, double a, double ecc, double ran, double aper, double inc, Vec3 &r1, Vec3 &v1)
Definition: astrolib.cpp:1134
AppPos
void AppPos(double jd, double ep2, double lat, double lng, double ht, int solsys, Vec3 r, double &azim, double &elev, double &dist)
Definition: astrolib.cpp:835
hyperb
void hyperb(double gm, double t0, double t, double a, double ecc, Vec3 &r1, Vec3 &v1)
Definition: astrolib.cpp:1013
Sun200::position
Vec3 position(double t)
Definition: astrolib.cpp:1394
dms
void dms(double dd, int &d, int &m, double &s)
Definition: astrolib.cpp:59
eccanom
double eccanom(double man, double ecc)
Definition: astrolib.cpp:915
mjd
double mjd(int day, int month, int year, double hour)
Definition: astrolib.cpp:94
Vec3::assign
void assign(double x=0, double y=0, double z=0)
Definition: attlib.cpp:46
hypanom
double hypanom(double mh, double ecc)
Definition: astrolib.cpp:951
Eclipse::penumd
void penumd(double jd, double tdut, Vec3 &vrm, Vec3 &ves, double &dpn, double &pang)
Definition: astrolib.cpp:2035
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
xrot
Mat3 xrot(double a)
Definition: attlib.cpp:488
julcent
double julcent(double mjuld)
Definition: astrolib.cpp:135
aberrat
Vec3 aberrat(double t, Vec3 &ve)
Definition: astrolib.cpp:695
EquHor
Vec3 EquHor(double jd, double ep2, double lat, double lng, Vec3 r)
Definition: astrolib.cpp:790
dot
double dot(const Vec3 &c1, const Vec3 &c2)
Definition: attlib.cpp:108
AppRADec
void AppRADec(double jd, double ep2, double lat, double lng, double azim, double elev, double &ra, double &dec)
Definition: astrolib.cpp:867
Moon200::Moon200
Moon200()
Definition: astrolib.cpp:1591
Eclipse::umbra
void umbra(double jd, double tdut, Vec3 &vrm, Vec3 &ves, double &dpn, double &pang)
Definition: astrolib.cpp:2081
polcar
Vec3 polcar(const Vec3 &c)
Definition: attlib.cpp:207
mxvct
Vec3 mxvct(const Mat3 &m1, Vec3 &v1)
Definition: attlib.cpp:473
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:38 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
  • 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