• 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
solarsystem.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 * Calculate positions and physical ephemerides of Solar System bodies. * * *
13 * The algorithm for the Modified Julian Date are based on *
14 * O.Montebruck and T.Pfleger, "Astronomy with a PC", *
15 * Springer Verlag, Berlin, Heidelberg, New York, 1989 *
16 *
17 * The calculations of the positions and physical ephemerides of the *
18 * various solar system bodies are based on *
19 * O.Montebruck, "Astronomie mit dem Personal Computer", *
20 * Springer Verlag, Berlin, Heidelberg, 1989; *
21 * O.Montebruck, "Practical Ephemeris Calculations", *
22 * Springer Verlag, Berlin, Heidelberg, New York, 1989 *
23 * and on the *
24 * "Explanatory Supplement to the Astronomical Almanac" *
25 * University Science Books, Mill Valley, CA, 1992 *
26 * *
27 * Open Source Code. License: GNU LGPL Version 2+ *
28 * *
29 * Author: Gerhard HOLTKAMP, 30-SEP-2013 *
30 ***************************************************************************/
31 
32 /*------------ include files and definitions -----------------------------*/
33 #include "solarsystem.h"
34 #include <cstdio>
35 #include <cstdlib>
36 #include <cstring>
37 #include <cmath>
38 #include <ctime>
39 using namespace std;
40 
41 #include "astrolib.h"
42 #include "astr2lib.h"
43 #include "attlib.h"
44 
45 const double degrad = M_PI / 180.0;
46 
47 // ################ Solar Eclipse Class ####################
48 
49 SolarSystem::SolarSystem()
50 {
51  ssinit();
52 }
53 
54 SolarSystem::~SolarSystem()
55 {
56 
57 }
58 
59 double SolarSystem::atan23 (double y, double x)
60  {
61  /* redefine atan2 so that it does'nt crash when both x and y are 0 */
62  double result;
63 
64  if ((x == 0) && (y == 0)) result = 0;
65  else result = atan2 (y, x);
66 
67  return result;
68  }
69 
70 double SolarSystem::DegFDms (double h)
71  {
72  /* convert degrees from d.fff -> d.mmsss where .mm are the minutes
73  and sss are seconds (and fractions of seconds).
74  */
75  int mm, deg;
76  double hh, t, sec;
77 
78  hh = fabs(h);
79  dms (hh,deg,mm,sec);
80  if (sec>=59.5)
81  {
82  mm++;
83  sec = 0;
84  };
85  if (mm>59)
86  {
87  deg++;
88  mm=0;
89  };
90  hh = double(deg);
91  t = double(mm)/100.0;
92  hh += t;
93  t = sec/10000.0;
94  hh += t;
95  if (h < 0) hh = -hh;
96 
97  return hh;
98  }
99 
100 double SolarSystem::DmsDegF (double h)
101  {
102  /* convert degrees from d.mmsss -> d.fff where .mm are the minutes
103  and sss are seconds (and fractions of seconds).
104  Returned is the angle in decimal degrees.
105  */
106  int mm, deg;
107  double hh, t, sec, dlt;
108 
109  hh = fabs(h);
110  dlt = hh*3.33e-16;
111  hh += dlt;
112  deg = int(hh);
113  t = fmod(hh,1.0)*100.0;
114  mm = int(t + 0.1e-12);
115  sec = fmod(hh*100.0,1.0)*100.0;
116  hh = ddd(deg,mm,sec);
117  if (h < 0) hh = -hh;
118 
119  return hh;
120  }
121 
122 void SolarSystem::ssinit()
123 {
124  // initialize solar system data
125  ss_update_called = false;
126  ss_moon_called = false;
127  ss_nutation = false;
128  ss_planmat_called = false;
129  ss_kepler_stored = false;
130  ss_kepler_called = false;
131 
132  ss_day = 1;
133  ss_month = 1;
134  ss_year = 2012;
135  ss_hour = 0;
136  ss_minute = 0;
137  ss_second = 0;
138  ss_tzone = 0;
139  ss_del_auto = 1;
140  ss_del_tdut = DefTdUt(ss_year);
141  ss_RT = true;
142  ss_epoch = 51544.5; // J2000.0
143  ss_central_body = 4;
144  setCurrentMJD();
145  ss_planmat = mxidn();
146  getConstEarth();
147 }
148 
149 void SolarSystem::DefTime () // Get System Time and Date
150  {
151  time_t tt;
152  int hh, mm, ss;
153  double jd, hr;
154 
155  tt = time(NULL);
156  jd = 40587.0 + tt/86400.0; // seconds since 1-JAN-1970
157 
158  caldat(jd, hh, mm, ss, hr);
159  ss_year = ss;
160  ss_month = mm;
161  ss_day = hh;
162 
163  dms(hr, hh, mm, jd);
164  ss_hour = hh;
165  ss_minute = mm;
166  ss_second = int(jd);
167  if (ss_del_auto) ss_del_tdut = DefTdUt(ss_year);
168  };
169 
170 void SolarSystem::setTimezone(double d)
171 {
172  // set the timezone to d (hours difference from UTC) for I/O
173  ss_tzone = d;
174 }
175 
176 void SolarSystem::setDeltaTAI_UTC(double d)
177 {
178  // c is the difference between TAI and UTC according to the IERS
179  // we have to add 32.184 sec to get to the difference TT - UT
180  // which is used in the calculations here
181 
182  ss_del_tdut = d + 32.184;
183  ss_del_auto = 0;
184 }
185 
186 void SolarSystem::setAutoTAI_UTC()
187 {
188  // set the difference between TAI and UTC according to the IERS
189  ss_del_auto = true;
190  ss_del_tdut = DefTdUt(ss_year);
191 }
192 
193 void SolarSystem::setCurrentMJD(int year, int month, int day, int hour, int min, double sec)
194 {
195  // set the (MJD-) time currently used for calculations to year, month, day, hour, min, sec
196  // corrected for timezone
197 
198  double jd;
199 
200  jd = ddd(hour, min, sec) - ss_tzone;
201  jd = mjd(day, month, year, jd);
202 
203  ss_time = jd;
204  ss_update_called = false;
205  ss_moon_called = false;
206  ss_planmat_called = false;
207  ss_kepler_called = false;
208 
209 }
210 
211 void SolarSystem::setCurrentMJD()
212 {
213  // set the (MJD-) time currently used for calculations to Real Time
214 
215  double jd, sec;
216 
217  DefTime();
218  sec = double(ss_second);
219  jd = ddd(ss_hour, ss_minute, sec);
220  jd = mjd(ss_day, ss_month, ss_year, jd);
221 
222  ss_time = jd;
223  ss_update_called = false;
224  ss_moon_called = false;
225  ss_planmat_called = false;
226  ss_kepler_called = false;
227 
228 }
229 
230 double SolarSystem::getMJD(int year, int month, int day, int hour, int min, double sec) const
231 {
232  // return the (MJD-) time corresponding to year, month, day, hour, min, sec
233  // corrected for timezone
234 
235  double jd;
236 
237  jd = ddd(hour, min, sec) - ss_tzone;
238  jd = mjd(day, month, year, jd);
239 
240  return jd;
241 }
242 
243 void SolarSystem::getDatefromMJD(double mjd, int &year, int &month, int &day, int &hour, int &min, double &sec) const
244 {
245  // convert times given in Modified Julian Date (MJD) into conventional date and time
246  // correct for timezone
247 
248  double magn;
249 
250  caldat((mjd + ss_tzone/24.0), day, month, year, magn);
251  dms (magn,hour,min,sec);
252  if (sec>30.0) min++;;
253  if (min>59)
254  {
255  hour++;
256  min=0;
257  };
258 }
259 
260 void SolarSystem::setEpoch (double yr)
261 {
262  int day, month, year;
263  double b;
264 
265  if (yr == 0) ss_epoch = 0; // Mean of Date
266  else
267  {
268  year = int(yr);
269  b = 12.0 * (yr - double(year));
270  month = int(b) + 1;
271  day = 1;
272 
273  b = 0;
274  ss_epoch = mjd(day, month, year, b);
275  }
276  ss_update_called = false;
277  ss_moon_called = false;
278  ss_planmat_called = false;
279  ss_kepler_called = false;
280 
281 }
282 
283 void SolarSystem::setNutation (bool nut)
284 {
285  ss_nutation = nut;
286  ss_update_called = false;
287  ss_moon_called = false;
288  ss_planmat_called = false;
289  ss_kepler_called = false;
290 
291 }
292 
293 void SolarSystem::setCentralBody(const char* pname)
294 {
295  ss_central_body = 4; // default Earth
296  getConstEarth();
297  if (strncmp("Sun", pname, 3) == 0)
298  {
299  ss_central_body = 0;
300  getConstSun();
301  };
302  if (strncmp("Moon", pname, 4) == 0)
303  {
304  ss_central_body = 1;
305  getConstMoon();
306  };
307  if (strncmp("Mercury", pname, 7) == 0)
308  {
309  ss_central_body = 2;
310  getConstMercury();
311  };
312  if (strncmp("Venus", pname, 5) == 0)
313  {
314  ss_central_body = 3;
315  getConstVenus();
316  };
317  if (strncmp("Mars", pname, 4) == 0)
318  {
319  ss_central_body = 5;
320  getConstMars();
321  };
322  if (strncmp("Jupiter", pname, 7) == 0)
323  {
324  ss_central_body = 6;
325  getConstJupiter();
326  };
327  if (strncmp("Saturn", pname, 6) == 0)
328  {
329  ss_central_body = 7;
330  getConstSaturn();
331  };
332  if (strncmp("Uranus", pname, 6) == 0)
333  {
334  ss_central_body = 8;
335  getConstUranus();
336  };
337  if (strncmp("Neptune", pname, 7) == 0)
338  {
339  ss_central_body = 9;
340  getConstNeptune();
341  };
342  ss_update_called = false;
343  ss_moon_called = false;
344  ss_planmat_called = false;
345  ss_kepler_called = false;
346 
347 }
348 
349 void SolarSystem::updateSolar()
350 {
351  // calculate all positions in mean ecliptic of epoch
352 
353  const double ae = 23454.77992; // 149597870.0/6378.14 = 1AE -> Earth Radii
354  double dt, eps2;
355  Sun200 sun;
356  Moon200 moon;
357  Plan200 pln;
358  Vec3 coff;
359  Mat3 pmx;
360 
361  ss_update_called = true;
362 
363  // get positions in ecliptic coordinates of date
364  dt = ss_time + ss_del_tdut/86400.0;
365  dt = julcent (dt);
366  ss_rs = sun.position(dt);
367  ss_rm = moon.position(dt)/ae;
368  ss_pmer = pln.Mercury(dt);
369  ss_pven = pln.Venus(dt);
370  ss_pearth[0] = -ss_rs[0];
371  ss_pearth[1] = -ss_rs[1];
372  ss_pearth[2] = -ss_rs[2];
373  ss_pmars = pln.Mars(dt);
374  ss_pjup = pln.Jupiter(dt);
375  ss_psat = pln.Saturn(dt);
376  ss_pura = pln.Uranus(dt);
377  ss_pnept = pln.Neptune(dt);
378 
379  // refer to selected central body
380  coff[0] = 0;
381  coff[1] = 0;
382  coff[2] = 0;
383 
384  if (ss_central_body == 2) coff -= ss_pmer;
385  if (ss_central_body == 3) coff -= ss_pven;
386  if (ss_central_body == 4) coff -= ss_pearth;
387  if (ss_central_body == 5) coff -= ss_pmars;
388  if (ss_central_body == 6) coff -= ss_pjup;
389  if (ss_central_body == 7) coff -= ss_psat;
390  if (ss_central_body == 8) coff -= ss_pura;
391  if (ss_central_body == 9) coff -= ss_pnept;
392  if (ss_central_body == 1) coff = coff + ss_rs - ss_rm;
393 
394  ss_pmer += coff;
395  ss_pven += coff;
396  ss_pearth += coff;
397  ss_pmars += coff;
398  ss_pjup += coff;
399  ss_psat += coff;
400  ss_pura += coff;
401  ss_pnept += coff;
402 
403  ss_rs[0] = coff[0];
404  ss_rs[1] = coff[1];
405  ss_rs[2] = coff[2];
406 
407  // convert into equatorial
408  ss_rs = eclequ(dt, ss_rs);
409  ss_rm = eclequ(dt, ss_rm);
410  ss_pmer = eclequ(dt, ss_pmer);
411  ss_pven = eclequ(dt, ss_pven);
412  ss_pearth = eclequ(dt, ss_pearth);
413  ss_pmars = eclequ(dt, ss_pmars);
414  ss_pjup = eclequ(dt, ss_pjup);
415  ss_psat = eclequ(dt, ss_psat);
416  ss_pura = eclequ(dt, ss_pura);
417  ss_pnept = eclequ(dt, ss_pnept);
418 
419  // correct for precession
420  if (ss_epoch != 0)
421  {
422  eps2 = julcent(ss_epoch);
423  pmx = pmatequ(dt, eps2);
424  ss_rs = mxvct(pmx,ss_rs);
425  ss_rm = mxvct(pmx,ss_rm);
426  ss_pmer = mxvct(pmx,ss_pmer);
427  ss_pven = mxvct(pmx,ss_pven);
428  ss_pearth = mxvct(pmx,ss_pearth);
429  ss_pmars = mxvct(pmx,ss_pmars);
430  ss_pjup = mxvct(pmx,ss_pjup);
431  ss_psat = mxvct(pmx,ss_psat);
432  ss_pura = mxvct(pmx,ss_pura);
433  ss_pnept = mxvct(pmx,ss_pnept);
434  };
435 
436  // correct for nutation
437  if (ss_nutation)
438  {
439  pmx = nutmat(dt, eps2, false);
440  ss_rs = mxvct(pmx,ss_rs);
441  ss_rm = mxvct(pmx,ss_rm);
442  ss_pmer = mxvct(pmx,ss_pmer);
443  ss_pven = mxvct(pmx,ss_pven);
444  ss_pearth = mxvct(pmx,ss_pearth);
445  ss_pmars = mxvct(pmx,ss_pmars);
446  ss_pjup = mxvct(pmx,ss_pjup);
447  ss_psat = mxvct(pmx,ss_psat);
448  ss_pura = mxvct(pmx,ss_pura);
449  ss_pnept = mxvct(pmx,ss_pnept);
450  };
451 }
452 
453 void SolarSystem::getRaDec(Vec3 r1, double& ra, double& decl)
454 {
455  // convert equatorial vector r1 into RA and DEC (in HH.MMSS and DD.MMSS)
456 
457  double const degrad = M_PI / 180.0;
458  Vec3 r2;
459 
460  r2 = carpol(r1);
461  decl = r2[2] / degrad;
462  ra = r2[1] / degrad;
463  ra /= 15.0;
464  if (ra < 0) ra += 24.0;
465 
466  decl = DegFDms(decl);
467  ra = DegFDms(ra);
468 
469 }
470 
471 void SolarSystem::getSun (double& ra, double& decl) // RA and Dec for the Sun
472 {
473  if (!ss_update_called) updateSolar();
474  if (ss_central_body == 0)
475  {
476  ra = -100.0;
477  decl = 0;
478  }
479  else getRaDec (ss_rs, ra, decl);
480 }
481 
482 void SolarSystem::getMoon (double& ra, double& decl) // RA and Dec for the Moon
483 {
484  if (!ss_update_called) updateSolar();
485  if (ss_central_body != 4)
486  {
487  ra = -100.0;
488  decl = 0;
489  }
490  else getRaDec (ss_rm, ra, decl);
491 }
492 
493 void SolarSystem::getMercury (double& ra, double& decl) // RA and Dec for Mercury
494 {
495  if (!ss_update_called) updateSolar();
496  if (ss_central_body == 2)
497  {
498  ra = -100.0;
499  decl = 0;
500  }
501  else getRaDec (ss_pmer, ra, decl);
502 }
503 
504 void SolarSystem::getVenus (double& ra, double& decl) // RA and Dec for Venus
505 {
506  if (!ss_update_called) updateSolar();
507  if (ss_central_body == 3)
508  {
509  ra = -100.0;
510  decl = 0;
511  }
512  else getRaDec (ss_pven, ra, decl);
513 }
514 
515 void SolarSystem::getEarth (double& ra, double& decl) // RA and Dec for Earth
516 {
517  if (!ss_update_called) updateSolar();
518  if (ss_central_body == 4)
519  {
520  ra = -100.0;
521  decl = 0;
522  }
523  else getRaDec (ss_pearth, ra, decl);
524 }
525 
526 void SolarSystem::getMars (double& ra, double& decl) // RA and Dec for Mars
527 {
528  if (!ss_update_called) updateSolar();
529  if (ss_central_body == 5)
530  {
531  ra = -100.0;
532  decl = 0;
533  }
534  else getRaDec (ss_pmars, ra, decl);
535 }
536 
537 void SolarSystem::getJupiter (double& ra, double& decl) // RA and Dec for Jupiter
538 {
539  if (!ss_update_called) updateSolar();
540  if (ss_central_body == 6)
541  {
542  ra = -100.0;
543  decl = 0;
544  }
545  else getRaDec (ss_pjup, ra, decl);
546 }
547 
548 void SolarSystem::getSaturn (double& ra, double& decl) // RA and Dec for Saturn
549 {
550  if (!ss_update_called) updateSolar();
551  if (ss_central_body == 7)
552  {
553  ra = -100.0;
554  decl = 0;
555  }
556  else getRaDec (ss_psat, ra, decl);
557 }
558 
559 void SolarSystem::getUranus (double& ra, double& decl) // RA and Dec for Uranus
560 {
561  if (!ss_update_called) updateSolar();
562  if (ss_central_body == 8)
563  {
564  ra = -100.0;
565  decl = 0;
566  }
567  else getRaDec (ss_pura, ra, decl);
568 }
569 
570 void SolarSystem::getNeptune (double& ra, double& decl) // RA and Dec for Neptune
571 {
572  if (!ss_update_called) updateSolar();
573  if (ss_central_body == 9)
574  {
575  ra = -100.0;
576  decl = 0;
577  }
578  else getRaDec (ss_pnept, ra, decl);
579 
580 }
581 
582 void SolarSystem::getPhysSun (double &pdiam, double &pmag)
583 {
584  // Apparent diameter for the Sun in radians
585 
586  if (ss_central_body == 0)
587  {
588  pdiam = 0;
589  pmag = 0;
590 
591  return;
592  };
593  if (!ss_update_called) updateSolar();
594 
595  pdiam = 0.00930495 / abs(ss_rs);
596  pmag = -26.7 + 5.0 * log10(abs(ss_rs));
597 }
598 
599 void SolarSystem::getPhysMercury(double &pdiam, double &pmag, double &pphase)
600 {
601  // Physical elements Mercury
602 
603  double ia, cp, cs, ps;
604 
605  if (ss_central_body == 2)
606  {
607  pdiam = 0;
608  pmag = 0;
609  pphase = 0;
610 
611  return;
612  };
613 
614  if (!ss_update_called) updateSolar();
615 
616  cp = abs(ss_pmer);
617  cs = abs(ss_rs);
618  ps = abs(ss_rs - ss_pmer);
619 
620  pdiam = 3.24831e-05 / cp; // apparent diameter in radians
621 
622  ia = 2.0 * cp * ps;
623  if (ia == 0) ia = 1.0; // this should never happen
624 
625  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
626 
627  pphase = 0.5 * (1.0 + ia);
628 
629  ia = acos(ia) / degrad;
630  ia /= 100.0;
631  pmag = -0.36 + 3.80*ia - 2.73*ia*ia + 2.00*ia*ia*ia;
632  pmag = pmag + 5.0 * log10(ps * cp);
633 }
634 
635 void SolarSystem::getPhysVenus(double &pdiam, double &pmag, double &pphase)
636 {
637  // Physical elements Venus
638 
639  double ia, cp, cs, ps;
640 
641  if (ss_central_body == 3)
642  {
643  pdiam = 0;
644  pmag = 0;
645  pphase = 0;
646 
647  return;
648  };
649 
650  if (!ss_update_called) updateSolar();
651 
652  cp = abs(ss_pven);
653  cs = abs(ss_rs);
654  ps = abs(ss_rs - ss_pven);
655 
656  pdiam = 8.09089e-05 / cp; // apparent diameter in radians
657 
658  ia = 2.0 * cp * ps;
659  if (ia == 0) ia = 1.0; // this should never happen
660 
661  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
662 
663  pphase = 0.5 * (1.0 + ia);
664 
665  ia = acos(ia) / degrad;
666  ia /= 100.0;
667  pmag = -4.29 + 0.09*ia + 2.39*ia*ia - 0.65*ia*ia*ia;
668  pmag = pmag + 5.0 * log10(ps * cp);
669 }
670 
671 void SolarSystem::getPhysEarth(double &pdiam, double &pmag, double &pphase)
672 {
673  // Physical elements Earth
674 
675  double ia, cp, cs, ps;
676 
677  if (ss_central_body == 4)
678  {
679  pdiam = 0;
680  pmag = 0;
681  pphase = 0;
682 
683  return;
684  };
685 
686  if (!ss_update_called) updateSolar();
687 
688  cp = abs(ss_pearth);
689  cs = abs(ss_rs);
690  ps = abs(ss_rs - ss_pearth);
691 
692  pdiam = 8.52705e-05 / cp; // apparent diameter in radians
693 
694  ia = 2.0 * cp * ps;
695  if (ia == 0) ia = 1.0; // this should never happen
696 
697  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
698 
699  pphase = 0.5 * (1.0 + ia);
700 
701  ia = acos(ia) / degrad;
702  ia /= 100.0;
703  pmag = -4.0 + 0.09*ia + 2.39*ia*ia - 0.65*ia*ia*ia;
704  pmag = pmag + 5.0 * log10(ps * cp);
705 }
706 
707 void SolarSystem::getPhysMars(double &pdiam, double &pmag, double &pphase)
708 {
709  // Physical elements Mars
710 
711  double ia, cp, cs, ps;
712 
713  if (ss_central_body == 5)
714  {
715  pdiam = 0;
716  pmag = 0;
717  pphase = 0;
718 
719  return;
720  };
721 
722  if (!ss_update_called) updateSolar();
723 
724  cp = abs(ss_pmars);
725  cs = abs(ss_rs);
726  ps = abs(ss_rs - ss_pmars);
727 
728  pdiam = 4.54178e-05 / cp; // apparent diameter in radians
729 
730  ia = 2.0 * cp * ps;
731  if (ia == 0) ia = 1.0; // this should never happen
732 
733  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
734 
735  pphase = 0.5 * (1.0 + ia);
736 
737  ia = acos(ia) / degrad;
738  pmag = -1.52 + 0.016*ia;
739  pmag = pmag + 5.0 * log10(ps * cp);
740 }
741 
742 void SolarSystem::getPhysJupiter(double &pdiam, double &pmag, double &pphase)
743 {
744  // Physical elements Jupiter
745 
746  double ia, cp, cs, ps;
747 
748  if (ss_central_body == 6)
749  {
750  pdiam = 0;
751  pmag = 0;
752  pphase = 0;
753 
754  return;
755  };
756 
757  if (!ss_update_called) updateSolar();
758 
759  cp = abs(ss_pjup);
760  cs = abs(ss_rs);
761  ps = abs(ss_rs - ss_pjup);
762 
763  pdiam = 0.000955789 / cp; // apparent diameter in radians
764 
765  ia = 2.0 * cp * ps;
766  if (ia == 0) ia = 1.0; // this should never happen
767 
768  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
769 
770  pphase = 0.5 * (1.0 + ia);
771 
772  ia = acos(ia) / degrad;
773  pmag = -9.25 + 0.005*ia;
774  pmag = pmag + 5.0 * log10(ps * cp);
775 }
776 
777 void SolarSystem::getPhysSaturn(double &pdiam, double &pmag, double &pphase)
778 {
779  // Physical elements Saturn
780 
781  double ia, cp, cs, ps;
782 
783  if (ss_central_body == 7)
784  {
785  pdiam = 0;
786  pmag = 0;
787  pphase = 0;
788 
789  return;
790  };
791 
792  if (!ss_update_called) updateSolar();
793 
794  cp = abs(ss_psat);
795  cs = abs(ss_rs);
796  ps = abs(ss_rs - ss_psat);
797 
798  pdiam = 0.000805733 / cp; // apparent diameter in radians
799 
800  ia = 2.0 * cp * ps;
801  if (ia == 0) ia = 1.0; // this should never happen
802 
803  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
804 
805  pphase = 0.5 * (1.0 + ia);
806 
807 // ia = acos(ia) / degrad;
808 // pmag = -7.19 + 0.044*ia;
809  pmag = -10.0;
810  pmag = pmag + 5.0 * log10(ps * cp);
811 }
812 
813 void SolarSystem::getPhysUranus(double &pdiam, double &pmag, double &pphase)
814 {
815  // Physical elements Uranus
816 
817  double ia, cp, cs, ps;
818 
819  if (ss_central_body == 8)
820  {
821  pdiam = 0;
822  pmag = 0;
823  pphase = 0;
824 
825  return;
826  };
827 
828  if (!ss_update_called) updateSolar();
829 
830  cp = abs(ss_pura);
831  cs = abs(ss_rs);
832  ps = abs(ss_rs - ss_pura);
833 
834  pdiam = 0.000341703 / cp; // apparent diameter in radians
835 
836  ia = 2.0 * cp * ps;
837  if (ia == 0) ia = 1.0; // this should never happen
838 
839  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
840 
841  pphase = 0.5 * (1.0 + ia);
842 
843  ia = acos(ia) / degrad;
844  pmag = -7.19 + 0.0228*ia;
845  pmag = pmag + 5.0 * log10(ps * cp);
846 }
847 
848 void SolarSystem::getPhysNeptune(double &pdiam, double &pmag, double &pphase)
849 {
850  // Physical elements Neptune
851 
852  double ia, cp, cs, ps;
853 
854  if (ss_central_body == 9)
855  {
856  pdiam = 0;
857  pmag = 0;
858  pphase = 0;
859 
860  return;
861  };
862 
863  if (!ss_update_called) updateSolar();
864 
865  cp = abs(ss_pnept);
866  cs = abs(ss_rs);
867  ps = abs(ss_rs - ss_pnept);
868 
869  pdiam = 0.000331074 / cp; // apparent diameter in radians
870 
871  ia = 2.0 * cp * ps;
872  if (ia == 0) ia = 1.0; // this should never happen
873 
874  ia = (cp*cp + ps*ps - cs*cs) / ia; // cos of phase angle
875 
876  pphase = 0.5 * (1.0 + ia);
877 
878  pmag = -6.87;
879  pmag = pmag + 5.0 * log10(ps * cp);
880 }
881 
882 double SolarSystem::getDiamMoon ()
883 {
884  // Apparent diameter for the Moon
885 
886  if (ss_central_body == 1) return 0;
887  if (!ss_update_called) updateSolar();
888 
889  return 2.32356e-05 / abs(ss_rm);
890 }
891 
892 void SolarSystem::getLunarLibration (double &lblon, double &lblat, double &termt)
893 {
894  // librations of the Moon and terminator position
895  if (!ss_moon_called) MoonDetails();
896 
897  lblon = ss_moon_lblon;
898  lblat = ss_moon_lblat;
899  termt = ss_moon_term;
900 }
901 
902 void SolarSystem::getLunarPhase (double &phase, double &ildisk, double &amag)
903 {
904  // phase and mag of Moon
905  if (!ss_moon_called) MoonDetails();
906 
907  phase = ss_moon_phase;
908  ildisk = ss_moon_ildisk;
909  amag = ss_moon_mag;
910 }
911 
912 Vec3 SolarSystem::SnPos (double &ep2, double &els) const
913  {
914  // return the apparent position of the Sun
915  // and the Nutation ep2 value and the ecliptic longitude of the Sun els
916 
917  Sun200 sun;
918  Mat3 mx;
919  Vec3 rs, s;
920  double t;
921 
922  t = ss_time + ss_del_tdut/86400.0;
923  t = julcent (t);
924 
925  rs = sun.position(t);
926  s = carpol(rs);
927  els = s[1];
928 
929  rs = eclequ(t,rs);
930  mx = nutmat(t,ep2); // nutation
931  rs = mxvct(mx,rs); // apparent coordinates
932  rs = aberrat(t,rs);
933 
934  return rs;
935  }
936 
937 Vec3 SolarSystem::MnPos (double &ep2, double &elm) const
938  {
939  // return the apparent position of the Moon
940  // and the Nutation ep2 value and the ecliptic longitude of the Moon elm
941 
942  Moon200 moon;
943  Mat3 mx;
944  Vec3 rm, s;
945  double t;
946 
947  t = ss_time + ss_del_tdut/86400.0;
948  t = julcent (t);
949 
950  rm = moon.position(t);
951  s = carpol(rm);
952  elm = s[1];
953 
954  rm = eclequ(t,rm);
955  mx = nutmat(t,ep2); // nutation
956  rm = mxvct(mx,rm);
957 
958  return rm;
959  }
960 
961 void SolarSystem::MoonLibr (double jd, Vec3 rm, Vec3 sn,
962  double &lblon, double &lblat, double &termt)
963  {
964  /* Calculate the librations angles lblon (longitude) and
965  lblat (latitude) for the moon at position rs and time jd.
966  Also calculate the selenographic longitude of the terminator.
967  rm is the position of the Moon from Earth, sn the position
968  of the Sun (also with respect to Earth).
969  */
970  double t, gam, gmp, l, omg, mln;
971  double a, b, c, ic, gn, gp, omp;
972  double const degrad = M_PI / 180.0;
973  Vec3 v1;
974  Mat3 m1, m2;
975 
976  t = (jd - 15019.5) / 36525.0;
977  gam = 281.2208333 + ((0.33333333e-5*t + 0.45277778e-3)*t + 1.7191750)*t;
978  gmp = 334.3295556 + ((-0.125e-4*t - 0.10325e-1)*t + 4069.0340333)*t;
979  l = 279.6966778 + (0.3025e-3*t + 36000.768925)*t;
980  omg = 259.1832750 + ((0.22222222e-5*t + 0.20777778e-2)*t - 1934.1420083)*t;
981  b = 23.45229444 + ((0.50277778e-6*t -0.16388889e-5)*t - 0.130125e-1)*t;
982  mln = 270.4341639 + ((0.1888889e-5*t -0.11333e-2)*t + 481267.8831417)*t;
983  ic = 1.535*degrad;
984  gn = (l - gam)*degrad;
985  gp = (mln - gmp)*degrad;
986  omp = (gmp - omg)*degrad;
987  a = -107.0*cos(gp) + 37.0*cos(gp+2.0*omp) -11.0*cos(2.0*(gp+omp));
988  a = a*0.000277778*degrad + ic;
989  c = (-109.0*sin(gp) + 37.0*sin(gp+2.0*omp) - 11.0*sin(2.0*(gp+omp)))/sin(ic);
990  c = (c*0.000277778 + omg)*degrad;
991  gn = -12.0*sin(gp) + 59.0*sin(gn) + 18.0*sin(2.0*omp);
992  gn = gn*0.000277778*degrad; // tau
993 
994  b *= degrad;
995  gam = cos(a)*cos(b) + sin(a)*sin(b)*cos(c);
996  gmp = gam*gam;
997  if(gmp > 1.0) gmp = 0;
998  else gmp = sqrt(1.0 - gmp);
999  gam = atan23(gmp,gam); // theta
1000  t = cos(a)*sin(b) - sin(a)*sin(b)*cos(c);
1001  l = -sin(a)*sin(c);
1002 
1003  gmp = atan23(l,t); // phi
1004  t = sin(a)*cos(b) - cos(a)*sin(b)*cos(c);
1005  l = -sin(b)*sin(c);
1006  a = atan23(l,t); // delta
1007  c = a + mln*degrad + gn - c; // psi
1008 
1009  // libration rotation matrix from Mean equator to true selenographic
1010  m1 = zrot(gmp);
1011  m2 = xrot(gam);
1012  m1 = m2 * m1;
1013  m2 = zrot(c);
1014  m1 = m2 * m1;
1015 
1016  // Earth coordinates
1017  v1[0] = -rm[0];
1018  v1[1] = -rm[1];
1019  v1[2] = -rm[2];
1020 
1021  v1 = mxvct(m1,v1);
1022  v1 = carpol(v1);
1023  lblat = v1[2] / degrad;
1024  lblon = v1[1] / degrad;
1025  if (lblon > 180.0) lblon = lblon - 360.0;
1026 
1027  // terminator
1028  v1 = mxvct(m1,sn);
1029  v1 = carpol(v1);
1030  termt = v1[1] / degrad;
1031  if (termt > 180.0) termt = termt - 360.0;
1032  termt -= 90.0;
1033  a = 90.0 + lblon;
1034  b = lblon - 90;
1035  if (termt > a) termt -= 180.0;
1036  else
1037  {
1038  if (termt < b) termt += 180;
1039  };
1040  }
1041 
1042 void SolarSystem::MoonDetails ()
1043  {
1044  // Calculate specific details about the Moon
1045  // Libration, Terminator position, Phase and Magnitude
1046 
1047  double jd, t, lblon, lblat, termt, mnmag;
1048  double dist, ps;
1049  double els, elm;
1050  double const degrad = M_PI / 180.0;
1051  double const ae = 23454.77992; // 149597870.0/6378.14 = 1AE -> Earth Radii
1052  Vec3 snc, mnc; // position of the Sun and the Moon
1053  Vec3 s, rm, rs, s3;
1054  double ep2; // correction for Apparent Sideral Time
1055 
1056  if (ss_central_body != 4) // calculate only for the Earth as reference
1057  {
1058  ss_moon_ildisk = 0;
1059  ss_moon_phase = 0;
1060  ss_moon_lblon = 0;
1061  ss_moon_lblat = 0;
1062  ss_moon_mag = 0;
1063  ss_moon_term = 0;
1064 
1065  return;
1066  };
1067 
1068  if (!ss_update_called) updateSolar();
1069  ss_moon_called = true;
1070 
1071  jd = ss_time;
1072 
1073  rs = SnPos (ep2, els);
1074  rs *= ae;
1075  snc = rs;
1076 
1077  rm = MnPos (ep2, elm);
1078  mnc = rm;
1079  s = snc - rm;
1080  MoonLibr(jd, rm, s, lblon, lblat, termt); // librations and terminator
1081 
1082  // calculate apparent magnitude of the Moon
1083  mnmag = abs(rm) / 23454.77992; // distance moon-observer in AU
1084  s = vnorm(s);
1085  s[0] = -s[0];
1086  s[1] = -s[1];
1087  s[2] = -s[2];
1088  s3 = vnorm(rm);
1089 
1090  dist = dot(s, s3); // cos of phase angle Sun-Moon-Observer
1091  if (fabs(dist) <= 1.0) dist = acos(dist) / degrad;
1092  else dist = 180.0;
1093  if (dist <= 61.0) dist = -3.475256769e-2 + 2.75256769e-2*dist;
1094  else
1095  {
1096  if (dist < 115.0) dist = 0.6962632 * exp(1.48709985e-2*dist);
1097  else
1098  {
1099  if (dist < 155.0) dist = 0.6531068 * exp(1.49213e-2*dist);
1100  else dist = 1.00779e-9 * pow (dist, 4.486359);
1101  };
1102  };
1103  if (mnmag <= 0) mnmag = 1e-30; // should never happen.
1104  mnmag = 0.23 + 5.0*log10(mnmag) + dist; // moon's mag
1105 
1106  // illuminated fraction
1107  rs = snc - mnc;
1108  rs = vnorm(rs);
1109  rm = vnorm(mnc);
1110  t = (1.0 - dot(rs,rm)) * 0.5;
1111  ps = elm - els;
1112  if (ps < 0) ps += 2*M_PI;
1113  ps = ps / (2.0*M_PI);
1114 
1115  ss_moon_ildisk = t;
1116  ss_moon_phase = ps;
1117  ss_moon_lblon = lblon;
1118  ss_moon_lblat = lblat;
1119  ss_moon_mag = mnmag;
1120  ss_moon_term = termt;
1121  }
1122 
1123 void SolarSystem::getConstSun() // Sun constants
1124 {
1125  ss_J2 = 0;
1126  ss_R0 = 696000.0;
1127  ss_flat = 0.0;
1128  ss_axl0 = 286.13;
1129  ss_axl1 = 0.0;
1130  ss_axb0 = 63.87;
1131  ss_axb1 = 0.0;
1132  ss_W = 84.10;
1133  ss_Wd = 14.1844000;
1134  ss_GM = 1.32712438e+20;
1135 }
1136 
1137 void SolarSystem::getConstMoon() // Moon planetary constants
1138 {
1139  ss_J2 = 0.2027e-3;
1140  ss_R0 = 1738.0;
1141  ss_flat = 0.0;
1142  ss_axl0 = 0.0;
1143  ss_axl1 = 0.0;
1144  ss_axb0 = 90.0;
1145  ss_axb1 = 0.0;
1146  ss_W = 0.0;
1147  ss_Wd = 13.17635898;
1148  ss_GM = 4.90279412e+12;
1149 }
1150 
1151 void SolarSystem::getConstMercury() // Mercury planetary constants
1152 {
1153  ss_J2 = 0.0;
1154  ss_R0 = 2439.7;
1155  ss_flat = 0.0;
1156  ss_axl0 = 281.01;
1157  ss_axl1 = -0.033;
1158  ss_axb0 = 61.45;
1159  ss_axb1 = -0.005;
1160  ss_W = 329.71;
1161  ss_Wd = 6.1385025;
1162  ss_GM = 2.20320802e+13;
1163 }
1164 
1165 void SolarSystem::getConstVenus() // Venus planetary constants
1166 {
1167  ss_J2 = 0.027e-3;
1168  ss_R0 = 6051.9;
1169  ss_flat = 0.0;
1170  ss_axl0 = 272.72;
1171  ss_axl1 = 0.0;
1172  ss_axb0 = 67.15;
1173  ss_axb1 = 0.0;
1174  ss_W = 160.26;
1175  ss_Wd = -1.4813596;
1176  ss_GM = 3.24858761e+14;
1177 }
1178 
1179 void SolarSystem::getConstEarth() // Earth planetary constants
1180 {
1181  ss_J2 = 1.08263e-3;
1182  ss_R0 = 6378.140;
1183  ss_flat = 0.00335364;
1184  ss_axl0 = 0.0;
1185  ss_axl1 = 0.0;
1186  ss_axb0 = 90.0;
1187  ss_axb1 = 0.0;
1188  ss_W = 0;
1189  ss_Wd = 359.017045833334;
1190  ss_GM = 3.986005e+14;
1191 }
1192 
1193 void SolarSystem::getConstMars() // Mars planetary constants
1194 {
1195  ss_J2 = 1.964e-3;
1196  ss_R0 = 3397.2;
1197  ss_flat = 0.00647630;
1198  ss_axl0 = 317.681;
1199  ss_axl1 = -0.108;
1200  ss_axb0 = 52.886;
1201  ss_axb1 = -0.061;
1202  ss_W = 176.868; // 176.655;
1203  ss_Wd = 350.8919830;
1204  ss_GM = 4.282828596416e+13; // 4.282837405582e+13
1205 }
1206 
1207 void SolarSystem::getConstJupiter() // Jupiter planetary constants
1208 {
1209  ss_J2 = 0.01475;
1210  ss_R0 = 71492.0;
1211  ss_flat = 0.06487;
1212  ss_axl0 = 268.05;
1213  ss_axl1 = -0.009;
1214  ss_axb0 = 64.49;
1215  ss_axb1 = 0.003;
1216  ss_W = 43.3;
1217  ss_Wd = 870.270;
1218  ss_GM = 1.2671199164e+17;
1219 }
1220 
1221 void SolarSystem::getConstSaturn() // Saturn planetary constants
1222 {
1223  ss_J2 = 0.01645;
1224  ss_R0 = 60268.0;
1225  ss_flat = 0.09796;
1226  ss_axl0 = 40.58;
1227  ss_axl1 = -0.036;
1228  ss_axb0 = 83.54;
1229  ss_axb1 = -0.004;
1230  ss_W = 38.90;
1231  ss_Wd = 810.7939024;
1232  ss_GM = 3.7934096899e+16;
1233 }
1234 
1235 void SolarSystem::getConstUranus() // Uranus planetary constants
1236 {
1237  ss_J2 = 0.012;
1238  ss_R0 = 25559.0;
1239  ss_flat = 0.02293;
1240  ss_axl0 = 257.43;
1241  ss_axl1 = 0;
1242  ss_axb0 = -15.10;
1243  ss_axb1 = 0;
1244  ss_W = 261.62;
1245  ss_Wd = -554.913;
1246  ss_GM = 5.8031587739e+15;
1247 }
1248 
1249 void SolarSystem::getConstNeptune() // Neptune planetary constants
1250 {
1251  ss_J2 = 0.004;
1252  ss_R0 = 24764.0;
1253  ss_flat = 0.0171;
1254  ss_axl0 = 295.33;
1255  ss_axl1 = 0;
1256  ss_axb0 = 40.65;
1257  ss_axb1 = 0;
1258  ss_W = 107.21;
1259  ss_Wd = 468.75;
1260  ss_GM = 6.8713077560e+15;
1261 }
1262 
1263 Mat3 SolarSystem::getSelenographic () const
1264 {
1265  // Calculate the Matrix to transform from Mean of J2000 into selenographic
1266  // coordinates at MJD time ss_time.
1267 
1268  double t, gam, gmp, l, omg, mln;
1269  double a, b, c, ic, gn, gp, omp;
1270  double const degrad = M_PI / 180.0;
1271  Mat3 m1, m2;
1272 
1273  t = (ss_time - 15019.5) / 36525.0;
1274  gam = 281.2208333 + ((0.33333333e-5*t + 0.45277778e-3)*t + 1.7191750)*t;
1275  gmp = 334.3295556 + ((-0.125e-4*t - 0.10325e-1)*t + 4069.0340333)*t;
1276  l = 279.6966778 + (0.3025e-3*t + 36000.768925)*t;
1277  omg = 259.1832750 + ((0.22222222e-5*t + 0.20777778e-2)*t - 1934.1420083)*t;
1278  b = 23.45229444 + ((0.50277778e-6*t -0.16388889e-5)*t - 0.130125e-1)*t;
1279  mln = 270.4341639 + ((0.1888889e-5*t -0.11333e-2)*t + 481267.8831417)*t;
1280  ic = 1.535*degrad;
1281  gn = (l - gam)*degrad;
1282  gp = (mln - gmp)*degrad;
1283  omp = (gmp - omg)*degrad;
1284  a = -107.0*cos(gp) + 37.0*cos(gp+2.0*omp) -11.0*cos(2.0*(gp+omp));
1285  a = a*0.000277778*degrad + ic;
1286  c = (-109.0*sin(gp) + 37.0*sin(gp+2.0*omp) - 11.0*sin(2.0*(gp+omp)))/sin(ic);
1287  c = (c*0.000277778 + omg)*degrad;
1288  gn = -12.0*sin(gp) + 59.0*sin(gn) + 18.0*sin(2.0*omp);
1289  gn = gn*0.000277778*degrad; // tau
1290 
1291  b *= degrad;
1292  gam = cos(a)*cos(b) + sin(a)*sin(b)*cos(c);
1293  gmp = gam*gam;
1294  if(gmp > 1.0) gmp = 0;
1295  else gmp = sqrt(1.0 - gmp);
1296  gam = atan23(gmp,gam); // theta
1297  t = cos(a)*sin(b) - sin(a)*sin(b)*cos(c);
1298  l = -sin(a)*sin(c);
1299 
1300  gmp = atan23(l,t); // phi
1301  t = sin(a)*cos(b) - cos(a)*sin(b)*cos(c);
1302  l = -sin(b)*sin(c);
1303  a = atan23(l,t); // delta
1304  c = a + mln*degrad + gn - c; // psi
1305 
1306  // libration rotation matrix from Mean equator to true selenographic
1307  m1 = zrot(gmp);
1308  m2 = xrot(gam);
1309  m1 = m2 * m1;
1310  m2 = zrot(c);
1311  m1 = m2 * m1;
1312 
1313  t = julcent(ss_time + ss_del_tdut/86400.0);
1314  m2 = pmatequ(0,t); // convert from mean of J2000 to mean of epoch
1315  m1 = m1 * m2;
1316 
1317  return m1;
1318 }
1319 
1320 void SolarSystem::getPlanMat()
1321 {
1322  // get Matrix to convert from Equatorial into planetary coordinates
1323 
1324  double ag, dt;
1325  Mat3 mx, m1;
1326 
1327  ss_planmat_called = true;
1328 
1329  dt = ss_time + ss_del_tdut/86400.0;
1330  dt = julcent (dt);
1331  if (ss_central_body == 1) ss_planmat = getSelenographic();
1332  else
1333  {
1334  if (ss_central_body == 4) // Earth
1335  {
1336  mx = pmatequ(0, dt);
1337  m1 = nutmat(dt, ag, false);
1338  mx = m1 * mx;
1339  m1 = zrot(lsidtim(ss_time, 0, ag)*M_PI/12.0);
1340  }
1341  else // other planets
1342  {
1343  ag = (ss_axl0 + ss_axl1 * dt) * M_PI / 180.0;
1344  mx = zrot(ag + M_PI / 2.0);
1345  ag = (ss_axb0 + ss_axb1 * dt) * M_PI / 180.0;
1346  m1 = xrot(M_PI / 2.0 - ag);
1347  mx = m1 * mx;
1348  m1 = zrot((ss_W + ss_Wd*(ss_time+ss_del_tdut/86400.0-51544.5))*(M_PI/180.0));
1349  };
1350  ss_planmat = m1 * mx;
1351  };
1352 
1353  if (ss_epoch != 51544.5) // correct for precession
1354  {
1355  if (ss_epoch == 0) ag = dt;
1356  else ag = julcent(ss_epoch);
1357  mx = pmatequ(ag, 0);
1358  ss_planmat = ss_planmat * mx;
1359  };
1360 
1361 }
1362 
1363 Vec3 SolarSystem::getPlanetocentric (double ra, double decl)
1364 {
1365  // return unity vector which corresponds to planetocentric position of
1366  // sky point at R.A ra (in HH.MMSS) and Declination decl (in DDD.MMSS)
1367 
1368  double dra, ddec;
1369  Vec3 ru;
1370 
1371  if (!ss_update_called) updateSolar();
1372  if (!ss_planmat_called) getPlanMat();
1373 
1374  dra = 15.0*DmsDegF(ra)*degrad;
1375  ddec = DmsDegF(decl)*degrad;
1376 
1377  ru[0] = 1.0;
1378  ru[1] = dra;
1379  ru[2] = ddec;
1380  ru = polcar(ru);
1381 
1382  ru = mxvct (ss_planmat, ru);
1383 
1384  return ru;
1385 }
1386 
1387 void SolarSystem::getPlanetographic (double ra, double decl, double &lng, double &lat)
1388 {
1389  // get planetogrphic longitude long and latitude lat (in decimal degrees) where
1390  // sky point at R.A ra (in HH.MMSS) and Declination decl (in DDD.MMSS) is at zenith.
1391 
1392  int j;
1393  double f, re, b1, b2, b3, c, sh, s, mp2;
1394  Vec3 ru, s2;
1395 
1396  ru = getPlanetocentric (ra, decl);
1397 
1398  mp2 = 2.0 * M_PI;
1399  re = ss_R0;
1400  ru *= re;
1401  f = ss_flat;
1402 
1403  s2 = carpol(ru);
1404  ss_lat = s2[2]; // just preliminary
1405  ss_lng = s2[1]; // measured with the motion of rotation!
1406  if (ss_lng > mp2) ss_lng -= mp2;
1407  if (ss_lng < -M_PI) ss_lng += mp2;
1408  if (ss_lng > M_PI) ss_lng -= mp2;
1409 
1410  // get height above ellipsoid and geodetic latitude
1411  if (abs(ru) > 0.1)
1412  {
1413  if (f == 0)
1414  {
1415  ss_height = abs(ru) - re;
1416  }
1417  else
1418  {
1419  c = f*(2.0 - f);
1420  s = ru[0]*ru[0] + ru[1]*ru[1];
1421  sh = c*ru[2];
1422 
1423  for (j=0; j<4; j++)
1424  {
1425  b1 = ru[2] + sh;
1426  b3 = sqrt(s+b1*b1);
1427  if (b3 < 1e-5) b3 = sin(ss_lat); // just in case
1428  else b3 = b1 / b3;
1429  b2 = re / sqrt(1.0 - c*b3*b3);
1430  sh = b2 * c * b3;
1431  };
1432 
1433  sh = ru[2] + sh;
1434  ss_lat = atan23(sh,sqrt(s));
1435  sh = sqrt(s+sh*sh) - b2;
1436  ss_height = sh;
1437  };
1438  }
1439  else ss_height = 0; // this should never happen
1440 
1441  ss_lat = ss_lat * 180.0 / M_PI;
1442  ss_lng = ss_lng * 180.0 / M_PI;
1443 
1444  lat = ss_lat;
1445  lng = ss_lng;
1446 
1447 }
1448 
1449 void SolarSystem::putOrbitElements (double t0, double pdist, double ecc, double ran, double aper, double inc, double eclep)
1450 {
1451  // store orbit elements for a hyperbolic, parabolic or highly elliptic heliocentric orbit
1452 
1453  ss_kepler_stored = true;
1454  ss_kepler_called = false;
1455 
1456  ss_t0 = t0;
1457  ss_m0 = -1.0;
1458  ss_a = pdist;
1459  ss_ecc = ecc;
1460  ss_ran = ran;
1461  ss_aper = aper;
1462  ss_inc = inc;
1463  ss_eclep = eclep;
1464 }
1465 
1466 void SolarSystem::putEllipticElements (double t0, double a, double m0, double ecc, double ran, double aper, double inc, double eclep)
1467 {
1468  // store orbit elements for an elliptic heliocentric orbit
1469 
1470  ss_kepler_stored = true;
1471  ss_kepler_called = false;
1472 
1473  ss_t0 = t0;
1474  ss_m0 = m0;
1475  ss_a = a;
1476  ss_ecc = ecc;
1477  ss_ran = ran;
1478  ss_aper = aper;
1479  ss_inc = inc;
1480  ss_eclep = eclep;
1481 }
1482 
1483 void SolarSystem::getOrbitPosition (double& ra, double& decl)
1484 {
1485  // get the position of the object for which the Kepler elements had been stored
1486 
1487  const double gs = 2.959122083e-4; // gravitation constant of the Sun in AU and d
1488  double dt;
1489  int day, month, year;
1490  double b, eps2, yr;
1491  Mat3 pmx;
1492 
1493  Vec3 r1, v1;
1494 
1495  if (!ss_kepler_stored)
1496  {
1497  ra = -100.0;
1498  decl = 0;
1499 
1500  return;
1501  };
1502 
1503  if (!ss_update_called) updateSolar();
1504 
1505  ss_kepler_called = true;
1506 
1507  // calculate Kepler orbit
1508 
1509  dt = ss_time + ss_del_tdut/86400.0;
1510 
1511  kepler (gs, ss_t0, dt, ss_m0, ss_a, ss_ecc, ss_ran, ss_aper, ss_inc, r1, v1);
1512 
1513  // correct for precession
1514  if (ss_epoch != 0) eps2 = julcent(ss_epoch);
1515  else eps2 = julcent(dt);
1516 
1517  yr = ss_eclep;
1518  if (yr == 0) b = eps2; // Mean of Date
1519  else
1520  {
1521  year = int(yr);
1522  b = 12.0 * (yr - double(year));
1523  month = int(b) + 1;
1524  day = 1;
1525 
1526  b = mjd(day, month, year, 0);
1527  b = julcent(b);
1528  };
1529 
1530  pmx = pmatecl(b, eps2);
1531  ss_comet = mxvct(pmx,r1);
1532 
1533  // convert into equatorial
1534  ss_comet = eclequ(eps2, ss_comet);
1535 
1536  // correct for nutation
1537  if (ss_nutation)
1538  {
1539  dt = julcent(dt);
1540  pmx = nutmat(dt, eps2, false);
1541  ss_comet = mxvct(pmx,ss_comet);
1542  };
1543 
1544  // refer to selected central body
1545  ss_comet = ss_comet + ss_rs;
1546 
1547  getRaDec (ss_comet, ra, decl);
1548 }
1549 
1550 double SolarSystem::getDistance()
1551 {
1552  // distance in AU of Kepler object
1553 
1554  double ra, decl;
1555 
1556  if (!ss_kepler_stored) return 0;
1557 
1558  if (!ss_kepler_called) getOrbitPosition (ra, decl);
1559 
1560  return abs(ss_comet);
1561 }
1562 
1563 double SolarSystem::getCometMag(double g, double k)
1564 {
1565  // apparent magnitude of comet. g = absolute magnitude, k = comet function
1566 
1567  double ra, decl;
1568 
1569  if (!ss_kepler_stored) return 0;
1570 
1571  if (!ss_kepler_called) getOrbitPosition (ra, decl);
1572 
1573  return g + 5.0 * log10(abs(ss_comet)) + k * log10(abs(ss_comet - ss_rs));
1574 
1575 }
1576 
1577 double SolarSystem::getAsteroidMag(double h, double g)
1578 {
1579  // apparent magnitude of asteroid. h = absolute magnitude, g = slope parameter
1580 
1581  double ra, decl, s, t;
1582 
1583  if (!ss_kepler_stored) return 0;
1584 
1585  if (!ss_kepler_called) getOrbitPosition (ra, decl);
1586 
1587  ra = abs(ss_comet);
1588  decl = abs(ss_comet - ss_rs);
1589  t = 2.0 * ra * decl;
1590  s = abs(ss_rs);
1591 
1592  if (t > 0) t = (ra*ra + decl*decl - s*s) / t;
1593  else t = 0; // just in case
1594 
1595  t = acos(t) / degrad;
1596  t /= 10.0;
1597 
1598  ra = h + 5.0 * log10(ra*decl) + g * t;
1599 
1600  return ra;
1601 
1602 }
Mat3
Definition: attlib.h:63
SolarSystem::getAsteroidMag
double getAsteroidMag(double h, double g)
Definition: solarsystem.cpp:1577
SolarSystem::getUranus
void getUranus(double &ra, double &decl)
Definition: solarsystem.cpp:559
SolarSystem::setCentralBody
void setCentralBody(const char *pname)
Definition: solarsystem.cpp:293
SolarSystem::getDatefromMJD
void getDatefromMJD(double mjd, int &year, int &month, int &day, int &hour, int &min, double &sec) const
Definition: solarsystem.cpp:243
eclequ
Vec3 eclequ(double t, Vec3 &r1)
Definition: astrolib.cpp:341
SolarSystem::getOrbitPosition
void getOrbitPosition(double &ra, double &decl)
Definition: solarsystem.cpp:1483
Vec3
Definition: attlib.h:27
Moon200
Definition: astrolib.h:96
SolarSystem::getPhysSun
void getPhysSun(double &pdiam, double &pmag)
Definition: solarsystem.cpp:582
SolarSystem::getJupiter
void getJupiter(double &ra, double &decl)
Definition: solarsystem.cpp:537
degrad
const double degrad
Definition: solarsystem.cpp:45
SolarSystem::setTimezone
void setTimezone(double d)
Definition: solarsystem.cpp:170
SolarSystem::getCometMag
double getCometMag(double g, double k)
Definition: solarsystem.cpp:1563
Moon200::position
Vec3 position(double t)
Definition: astrolib.cpp:1594
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
SolarSystem::getLunarLibration
void getLunarLibration(double &lblon, double &lblat, double &termt)
Definition: solarsystem.cpp:892
SolarSystem::getNeptune
void getNeptune(double &ra, double &decl)
Definition: solarsystem.cpp:570
SolarSystem::setAutoTAI_UTC
void setAutoTAI_UTC()
Definition: solarsystem.cpp:186
SolarSystem::DmsDegF
static double DmsDegF(double h)
Definition: solarsystem.cpp:100
DefTdUt
double DefTdUt(int yi)
Definition: astrolib.cpp:223
SolarSystem::DegFDms
static double DegFDms(double h)
Definition: solarsystem.cpp:70
Plan200::Uranus
Vec3 Uranus(double t)
Definition: astr2lib.cpp:729
carpol
Vec3 carpol(const Vec3 &c)
Definition: attlib.cpp:184
vnorm
Vec3 vnorm(const Vec3 &c)
Definition: attlib.cpp:170
attlib.h
zrot
Mat3 zrot(double a)
Definition: attlib.cpp:530
Plan200::Mercury
Vec3 Mercury(double t)
Definition: astr2lib.cpp:97
pmatequ
Mat3 pmatequ(double t1, double t2)
Definition: astrolib.cpp:408
Plan200::Neptune
Vec3 Neptune(double t)
Definition: astr2lib.cpp:860
SolarSystem::getLunarPhase
void getLunarPhase(double &phase, double &ildisk, double &amag)
Definition: solarsystem.cpp:902
SolarSystem::getPhysEarth
void getPhysEarth(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:671
Sun200
Definition: astrolib.h:71
caldat
void caldat(double mjd, int &day, int &month, int &year, double &hour)
Definition: astrolib.cpp:145
SolarSystem::putEllipticElements
void putEllipticElements(double t0, double a, double m0, double ecc, double ran, double aper, double inc, double eclep)
Definition: solarsystem.cpp:1466
pmatecl
Mat3 pmatecl(double t1, double t2)
Definition: astrolib.cpp:375
SolarSystem::getDistance
double getDistance()
Definition: solarsystem.cpp:1550
Plan200::Mars
Vec3 Mars(double t)
Definition: astr2lib.cpp:321
abs
double abs(const Vec3 &c)
Definition: attlib.cpp:100
SolarSystem::~SolarSystem
~SolarSystem()
Definition: solarsystem.cpp:54
solarsystem.h
SolarSystem::setEpoch
void setEpoch(double yr)
Definition: solarsystem.cpp:260
nutmat
Mat3 nutmat(double t, double &ep2, bool hpr)
Definition: astrolib.cpp:437
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
SolarSystem::getVenus
void getVenus(double &ra, double &decl)
Definition: solarsystem.cpp:504
SolarSystem::getPhysUranus
void getPhysUranus(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:813
SolarSystem::getSun
void getSun(double &ra, double &decl)
Definition: solarsystem.cpp:471
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
Plan200::Saturn
Vec3 Saturn(double t)
Definition: astr2lib.cpp:596
SolarSystem::getPhysVenus
void getPhysVenus(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:635
mjd
double mjd(int day, int month, int year, double hour)
Definition: astrolib.cpp:94
SolarSystem::getEarth
void getEarth(double &ra, double &decl)
Definition: solarsystem.cpp:515
SolarSystem::getMercury
void getMercury(double &ra, double &decl)
Definition: solarsystem.cpp:493
SolarSystem::getSaturn
void getSaturn(double &ra, double &decl)
Definition: solarsystem.cpp:548
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
SolarSystem::putOrbitElements
void putOrbitElements(double t0, double pdist, double ecc, double ran, double aper, double inc, double eclep)
Definition: solarsystem.cpp:1449
mxidn
Mat3 mxidn()
Definition: attlib.cpp:368
SolarSystem::getMoon
void getMoon(double &ra, double &decl)
Definition: solarsystem.cpp:482
SolarSystem::getPlanetographic
void getPlanetographic(double ra, double decl, double &lng, double &lat)
Definition: solarsystem.cpp:1387
xrot
Mat3 xrot(double a)
Definition: attlib.cpp:488
SolarSystem::getPhysSaturn
void getPhysSaturn(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:777
SolarSystem::getPhysJupiter
void getPhysJupiter(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:742
julcent
double julcent(double mjuld)
Definition: astrolib.cpp:135
aberrat
Vec3 aberrat(double t, Vec3 &ve)
Definition: astrolib.cpp:695
SolarSystem::setDeltaTAI_UTC
void setDeltaTAI_UTC(double d)
Definition: solarsystem.cpp:176
SolarSystem::getPhysMars
void getPhysMars(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:707
SolarSystem::getDiamMoon
double getDiamMoon()
Definition: solarsystem.cpp:882
Plan200
Definition: astr2lib.h:24
SolarSystem::getMJD
double getMJD(int year, int month, int day, int hour, int min, double sec) const
Definition: solarsystem.cpp:230
dot
double dot(const Vec3 &c1, const Vec3 &c2)
Definition: attlib.cpp:108
astr2lib.h
SolarSystem::getPhysNeptune
void getPhysNeptune(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:848
Plan200::Jupiter
Vec3 Jupiter(double t)
Definition: astr2lib.cpp:492
polcar
Vec3 polcar(const Vec3 &c)
Definition: attlib.cpp:207
mxvct
Vec3 mxvct(const Mat3 &m1, Vec3 &v1)
Definition: attlib.cpp:473
SolarSystem::setCurrentMJD
void setCurrentMJD()
Definition: solarsystem.cpp:211
Plan200::Venus
Vec3 Venus(double t)
Definition: astr2lib.cpp:213
SolarSystem::getPlanetocentric
Vec3 getPlanetocentric(double ra, double decl)
Definition: solarsystem.cpp:1363
SolarSystem::setNutation
void setNutation(bool nut)
Definition: solarsystem.cpp:283
SolarSystem::getMars
void getMars(double &ra, double &decl)
Definition: solarsystem.cpp:526
SolarSystem::SolarSystem
SolarSystem()
Definition: solarsystem.cpp:49
SolarSystem::getPhysMercury
void getPhysMercury(double &pdiam, double &pmag, double &pphase)
Definition: solarsystem.cpp:599
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:42 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