Sun position
Sun position algorithm
planet.c
1 /*==============================================================================
2  * planet.c - Astronomical routines to get the positions of planets
3  *
4  * Author: David Hoadley
5  *
6  * Description: (see planet.h)
7  *
8  * Copyright (c) 2020, David Hoadley <vcrumble@westnet.com.au>, except for
9  * routine planet_getHeliocentric(), which is covered by the SOFA Software
10  * License (see the code of that function for the license text).
11  *
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are met:
16  *
17  * * Redistributions of source code must retain the above copyright notice, this
18  * list of conditions and the following disclaimer.
19  * * Redistributions in binary form must reproduce the above copyright notice,
20  * this list of conditions and the following disclaimer in the documentation
21  * and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  *==============================================================================
36  */
37 
38 /* ANSI includes etc. */
39 #include "instead-of-math.h"
40 
41 /* Local and project includes */
42 #include "planet.h"
43 
44 #include "astron.h"
45 #include "general.h"
46 #include "sky.h"
47 #include "sky1.h"
48 #include "vectors3d.h"
49 
50 /*
51  * Local #defines and typedefs
52  */
53 
54 /*
55  * Prototypes for local functions (not called from other modules)
56  */
57 LOCAL int planetGetEarth(double t_cy,
58  V3D_Vector *j2kV_au,
59  V3D_Vector *velV_aupd);
60 
61 /*
62  * Global variables accessible by other modules
63  */
64 
65 
66 /*
67  * Local variables (not accessed by other modules)
68  */
69 /* Constants found in the 2007 Astronomical Almanac, pages K6 & K7 */
70 LOCAL const double lightTime_s = 499.0047863852; // time to travel 1 AU(seconds)
71 
72 /* Derived constants */
73 LOCAL const double invC_dpau = lightTime_s / 86400.0;// 1/c (light speed) (d/AU)
74 
75 
76 LOCAL int currentPlanet = 0;
77 
78 /*
79  *==============================================================================
80  *
81  * Implementation
82  *
83  *==============================================================================
84  *
85  * Global functions callable by other modules
86  *
87  *------------------------------------------------------------------------------
88  */
90 /*! Stores the selected planet number \a np in internal storage for later use
91  by planet_getApparent() or planet_getTopocentric()
92  \param[in] np Desired planet.\n
93  1=Mercury, 2=Venus, 3=Earth-Moon Barycentre, 4=Mars,\n
94  5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune\n
95  Numbers outside this range will cause an assertion failure
96 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
97 {
98  REQUIRE((np > 0) && (np <= 8));
99 
100  currentPlanet = np;
101 }
102 
103 
104 
105 GLOBAL void planet_getApp2(double t_cy,
106  int np,
107  const Sky1_Nut1980 *nut,
108  V3D_Vector *appV,
109  double *dist_au)
110 /*! This function calculates the specified planet's position in apparent
111  coordinates, using the planet_getGeocentric() and planet_getHeliocentric()
112  functions
113  \param[in] t_cy Julian centuries since J2000.0, TT timescale
114  \param[in] np Desired planet.\n
115  1=Mercury, 2=Venus, 3=Earth-Moon Barycentre, 4=Mars,\n
116  5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune\n
117  Numbers outside this range will cause an assertion failure
118  \param[in] nut Nutation terms and obliquity of the ecliptic, as returned
119  by functions sky1_nutationIAU1980() and sky1_epsilon1980()
120 
121  \param[out] appV Position vector of planet in apparent coordinates (unit
122  vector i.e. direction cosines)
123  \param[out] dist_au Geocentric distance of the planet (Astronomical Units)
124 
125  \par When to call this function
126  In most cases, you will want to call planet_getApparent() or
127  planet_getTopocentric() instead, and those functions call this function for
128  you.
129 */
130 {
131  Sky1_Prec1976 prec; /* Precession angles */
132  V3D_Matrix nM, pM; /* Nutation matrix, precession matrix */
133  V3D_Matrix npM; /* Precession/nutation combined matrix */
134  V3D_Vector j2kV; /* Position vector, referred to J2000.0 */
135 
136  REQUIRE_NOT_NULL(appV);
137  REQUIRE_NOT_NULL(dist_au);
138 
139  planet_getGeocentric(t_cy, np, &j2kV, dist_au);
140 
141  /* Create combined precession and nutation matrix */
142  sky1_createNut1980Matrix(nut, &nM);
143  sky1_precessionIAU1976(0.0, t_cy, &prec);
144  sky1_createPrec1976Matrix(&prec, &pM);
145  v3d_multMxM(&npM, &nM, &pM);
146 
147  /* Convert to geocentric apparent coordinates by multiplying
148  by matrices for precession and nutation */
149  v3d_multMxV(appV, &npM, &j2kV);
150 }
151 
152 
153 
154 GLOBAL void planet_getApparent(double j2kTT_cy, Sky_TrueEquatorial *pos)
155 /*! Calculate the position of the currently selected planet as a unit vector and
156  a distance, in apparent coordinates. It calls planet_getApp2() to obtain the
157  planet's position, after having called sky1_nutationIAU1980() to obtain the
158  necessary nutation terms.
159  This function is designed to be callable by the skyfast_init() and
160  skyfast_backgroundUpdate() functions in a tracking application.
161  \param[in] j2kTT_cy Julian centuries since J2000.0, TT timescale
162  \param[out] pos Timestamped structure containing position data and the
163  equation of the equinoxes
164 
165  The planet whose coordinates are obtained with this function is the planet
166  most recently specified with planet_setCurrent()
167 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
168 {
169  Sky1_Nut1980 nut;
170 
171  REQUIRE_NOT_NULL(pos);
172  REQUIRE(currentPlanet > 0); /* Was planet_setCurrent() never called? */
173 
174  /* Calculate nutation */
175  sky1_nutationIAU1980(j2kTT_cy, 0, &nut);
176 
177  /* Calculate the mean obliquity of the ecliptic and the equation
178  of the equinoxes */
179  sky1_epsilon1980(j2kTT_cy, &nut);
180  pos->eqEq_rad = nut.eqEq_rad;
181 
182  /* Calculate the planet's apparent position */
183  planet_getApp2(j2kTT_cy,
184  currentPlanet,
185  &nut,
186  &pos->appCirsV,
187  &pos->distance_au);
188 
189  /* Now set the timestamp*/
190  pos->timestamp_cy = j2kTT_cy;
191 }
192 
193 
194 
195 GLOBAL void planet_getTopocentric(double j2kUtc_d,
196  const Sky_DeltaTs *deltas,
197  const Sky_SiteProp *site,
198  Sky_SiteHorizon *topo)
199 /*! Calls planet_getApparent() to calculate the planet's position in apparent
200  coordinates, and then converts this to topocentric horizon coordinates at
201  the specified site.
202  \param[in] j2kUtc_d UTC time in "J2KD" form - i.e days since J2000.0
203  (= JD - 2 451 545.0)
204  \param[in] deltas Delta T values, as set by the sky_initTime() (or
205  sky_initTimeSimple() or sky_initTimeDetailed()) routines
206  \param[in] site Properties of the observing site, particularly its
207  geometric location on the surface of the Earth, as set by
208  the sky_setSiteLocation() function (or sky_setSiteLoc2())
209  \param[out] topo Topocentric position, in both rectangular (unit vector)
210  form, and as Azimuth and Elevation (altitude) angles
211 
212  You will need to call planet_setCurrent() before calling this function to
213  select the planet whose coordinates you want.
214 
215  \par When to call this function
216  Use this function if you are calculating the planet topocentric position
217  once, for a single site. But if you are going to be calculating it
218  repeatedly, or for multiple sites, use of this function will cause you to
219  perform a great many needless recalculations. Use skyfast_getApprox(),
220  followed by sky1_appToTirs() and sky_siteTirsToTopo() instead.
221 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
222 {
223  Sky_Times atime; // time, in various timescales
224  Sky_TrueEquatorial pos; // geocentric position of the Sun and distance
225  V3D_Vector terInterV; // unit vector in Terrestrial Intermed Ref Sys
226 
227  REQUIRE_NOT_NULL(deltas);
228  REQUIRE_NOT_NULL(site);
229  REQUIRE_NOT_NULL(topo);
230 
231  sky_updateTimes(j2kUtc_d, deltas, &atime);
232 
233  planet_getApparent(atime.j2kTT_cy, &pos);
234 
235  /* Convert apparent position to topocentric Azimuth/Elevation coords */
236  sky1_appToTirs(&pos.appCirsV, atime.j2kUT1_d, pos.eqEq_rad, &terInterV);
237  sky_siteTirsToTopo(&terInterV, pos.distance_au, site, topo);
238 }
239 
240 
241 
242 GLOBAL void planet_getGeocentric(double t_cy,
243  int np,
244  V3D_Vector *p2V,
245  double *dist_au)
246 /*! Calculates an approximate position of the selected planet as seen from the
247  centre of the earth. This function calls planet_getHeliocentric() for the
248  desired planet. It then (as an approximation) calls this routine again for
249  the position of the Earth and uses this to obtain the geocentric position
250  of the planet.
251  \param[in] t_cy Julian centuries since J2000.0, TT timescale
252  \param[in] np Desired planet.\n
253  1=Mercury, 2=Venus, 3=Earth-Moon Barycentre, 4=Mars,\n
254  5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune\n
255  Numbers outside this range will cause an assertion failure
256 
257  \param[out] p2V Position vector of planet in J2000.0 coordinates (unit
258  vector i.e. direction cosines)
259  \param[out] dist_au Geocentric distance of the planet (Astronomical Units)
260 
261  \note
262  Calling planet_getHeliocentric() for the position of the Earth actually
263  returns the position of the Earth-Moon barycenter, rather than the position
264  of the Earth. But the error that is introduced by doing this seems to be
265  relatively small, somewhere in the 10's of arcseconds. So long as a
266  planetary position that is within an arcminute is all you need, this routine
267  should be perfectly OK.
268  \note
269  planet_getHeliocentric() uses an iterative approach to calculating planetary
270  positions. If for some reason that does not converge, this function will set
271  \a p2V and \a dist_au to zero.
272 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
273 {
274  V3D_Vector helioV_au; /* Heliocentric position estimates of planet */
275  V3D_Vector earthV_au; /* Heliocentric position of the Earth */
276  V3D_Vector earthVelV_aupd; /* Earth velocity vector */
277  V3D_Vector geoV_au; /* Geocentric direction of planet */
278  V3D_Vector p1V; /* Geocentric direction of planet, unit vector*/
279  V3D_Vector aberrV; /* Aberration correction vector */
280  double lightTime_d; /* Light time from planet to Earth */
281  int ret;
282 
283  REQUIRE_NOT_NULL(p2V);
284  REQUIRE_NOT_NULL(dist_au);
285 
286  /* Zero out return values, in case planet_GetHeliocentric() fails. */
287  p2V->a[0] = p2V->a[1] = p2V->a[2] = 0.0;
288  *dist_au = 0.0;
289 
290  /* Initial estimate */
291  ret = planet_getHeliocentric(t_cy, np, &helioV_au, NULL);
292  if (ret == 2) {
293  return;
294  }
295  ret = planetGetEarth(t_cy, &earthV_au, &earthVelV_aupd);
296  if (ret == 2) {
297  return;
298  }
299 
300  v3d_subtractV(&geoV_au, &helioV_au, &earthV_au);
301  *dist_au = v3d_magV(&geoV_au);
302 
303  /* How long did light take to arrive from the planet to the Earth?
304  There is a full relativistic correction for this, but for our purposes
305  it can be ignored. Just divide the distance by the speed of light */
306  lightTime_d = *dist_au * invC_dpau;
307 
308  /* First iteration */
309  ret = planet_getHeliocentric(t_cy - lightTime_d / JUL_CENT,
310  np, &helioV_au, NULL);
311  if (ret == 2) {
312  return;
313  }
314  v3d_subtractV(&geoV_au, &helioV_au, &earthV_au);
315  *dist_au = v3d_magV(&geoV_au);
316  lightTime_d = *dist_au * invC_dpau;
317 
318  /* Second iteration */
319  ret = planet_getHeliocentric(t_cy - lightTime_d / JUL_CENT,
320  np, &helioV_au, NULL);
321  if (ret == 2) {
322  return;
323  }
324  v3d_subtractV(&geoV_au, &helioV_au, &earthV_au);
325  *dist_au = v3d_magV(&geoV_au);
326  lightTime_d = *dist_au * invC_dpau;
327 
328  /* Consider that good enough. Convert geocentric vector to a unit vector */
329  p1V.a[0] = geoV_au.a[0] / *dist_au;
330  p1V.a[1] = geoV_au.a[1] / *dist_au;
331  p1V.a[2] = geoV_au.a[2] / *dist_au;
332 
333  aberrV.a[0] = earthVelV_aupd.a[0] * invC_dpau;
334  aberrV.a[1] = earthVelV_aupd.a[1] * invC_dpau;
335  aberrV.a[2] = earthVelV_aupd.a[2] * invC_dpau;
336 
337  *p2V = p1V; // copy vector
338  v3d_addToUVfast(p2V, &aberrV);
339  return;
340 }
341 
342 
343 
345  int np,
346  V3D_Vector *j2kV_au,
347  V3D_Vector *velV_aupd)
348 /*! Calculates an approximate heliocentric position of the selected planet.
349  \returns Error code:\n
350  0 = OK,
351  1 = warning, reduced precision: year outside 1000--3000,
352  2 = error, failed to converge.
353  \param[in] t_cy Julian centuries since J2000.0, TDB (or TT) timescale
354  \param[in] np Desired planet.\n
355  1=Mercury, 2=Venus, 3=Earth-Moon Barycentre, 4=Mars,\n
356  5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune\n
357  Numbers outside this range will cause an assertion
358  failure
359  \param[out] j2kV_au Heliocentric position of planet referred to J2000.0 mean
360  equator and equinox.
361  \param[out] velV_aupd (Optional) Velocity vector of the planet (AU/day), also
362  referred to J2000.0 equator and equinox. If you are not
363  interested in this value, you can pass NULL to this
364  argument.
365 
366  \note
367  This function is a modified implementation of the \c iauPlan94() function
368  from the International Astronomical Union's (IAU) Standards of Fundamental
369  Astronomy (SOFA) collection. See the SOFA Software License at the end of
370  this function's C source code. According to the requirements of that
371  license, here are the required declarations.
372  \note
373  Condition 3(a). This software is derived by David Hoadley from licensed
374  SOFA code (i.e. routine \c iauPlan94()). It does not itself constitute
375  software provided by and/or endorsed by SOFA.
376  \note
377  Condition 3(b). This function differs from the original SOFA routine in that
378  1. The input and output arguments have been altered to match the
379  conventions used elsewhere in this software.\n
380  time:
381  - here: time is input as Julian centuries since J2000.0, TT
382  - SOFA: time is input as a Julian date in two parts, TDB\n
383  .
384  outputs:
385  - here: a position vector scaled in AU, and an optional velocity
386  vector in AU/d
387  - SOFA: a 2x3 element array giving both position and velocity in
388  AU and AU/d respectively.
389  2. A requested planet outside the range 1--8 does not return an error code.
390  Such a request is a programming error, so instead it generates a
391  precondition failure (an assertion failure). Also, the output vectors
392  are not zero'd if this precondition failure occurs.
393  3. The names of some constants have been changed to use the names
394  we already have in use, and in the process "de-FORTRAN-ised",
395  making them more comprehensible.\n
396  D2PI -> TWOPI\n
397  DAS2R -> ARCSEC2RAD
398  4. An assertion test added to check for a NULL pointer being passed for
399  \a j2kV
400  5. Calls our own normalize() function instead of the SOFA routine
401  \c iauAnp()
402  .
403  Condition 3(e). If you make any modification to this software, or copy any
404  part of it for incorporation elsewhere, you must include the SOFA Software
405  License exactly as it appears at the end of this function.
406 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
407 /* What follows is the original header comment block for iauPlan94(). It does
408  not reflect the changes described above. */
409 /*
410 ** - - - - - - - - - -
411 ** i a u P l a n 9 4
412 ** - - - - - - - - - -
413 **
414 ** This function is part of the International Astronomical Union's
415 ** SOFA (Standards Of Fundamental Astronomy) software collection.
416 **
417 ** Status: support function.
418 **
419 ** Approximate heliocentric position and velocity of a nominated major
420 ** planet: Mercury, Venus, EMB, Mars, Jupiter, Saturn, Uranus or
421 ** Neptune (but not the Earth itself).
422 **
423 ** Given:
424 ** date1 double TDB date part A (Note 1)
425 ** date2 double TDB date part B (Note 1)
426 ** np int planet (1=Mercury, 2=Venus, 3=EMB, 4=Mars,
427 ** 5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune)
428 **
429 ** Returned (argument):
430 ** pv double[2][3] planet p,v (heliocentric, J2000.0, au,au/d)
431 **
432 ** Returned (function value):
433 ** int status: -1 = illegal NP (outside 1-8)
434 ** 0 = OK
435 ** +1 = warning: year outside 1000-3000
436 ** +2 = warning: failed to converge
437 **
438 ** Notes:
439 **
440 ** 1) The date date1+date2 is in the TDB time scale (in practice TT can
441 ** be used) and is a Julian Date, apportioned in any convenient way
442 ** between the two arguments. For example, JD(TDB)=2450123.7 could
443 ** be expressed in any of these ways, among others:
444 **
445 ** date1 date2
446 **
447 ** 2450123.7 0.0 (JD method)
448 ** 2451545.0 -1421.3 (J2000 method)
449 ** 2400000.5 50123.2 (MJD method)
450 ** 2450123.5 0.2 (date & time method)
451 **
452 ** The JD method is the most natural and convenient to use in cases
453 ** where the loss of several decimal digits of resolution is
454 ** acceptable. The J2000 method is best matched to the way the
455 ** argument is handled internally and will deliver the optimum
456 ** resolution. The MJD method and the date & time methods are both
457 ** good compromises between resolution and convenience. The limited
458 ** accuracy of the present algorithm is such that any of the methods
459 ** is satisfactory.
460 **
461 ** 2) If an np value outside the range 1-8 is supplied, an error status
462 ** (function value -1) is returned and the pv vector set to zeroes.
463 **
464 ** 3) For np=3 the result is for the Earth-Moon Barycenter. To obtain
465 ** the heliocentric position and velocity of the Earth, use instead
466 ** the SOFA function iauEpv00.
467 **
468 ** 4) On successful return, the array pv contains the following:
469 **
470 ** pv[0][0] x }
471 ** pv[0][1] y } heliocentric position, au
472 ** pv[0][2] z }
473 **
474 ** pv[1][0] xdot }
475 ** pv[1][1] ydot } heliocentric velocity, au/d
476 ** pv[1][2] zdot }
477 **
478 ** The reference frame is equatorial and is with respect to the
479 ** mean equator and equinox of epoch J2000.0.
480 **
481 ** 5) The algorithm is due to J.L. Simon, P. Bretagnon, J. Chapront,
482 ** M. Chapront-Touze, G. Francou and J. Laskar (Bureau des
483 ** Longitudes, Paris, France). From comparisons with JPL
484 ** ephemeris DE102, they quote the following maximum errors
485 ** over the interval 1800-2050:
486 **
487 ** L (arcsec) B (arcsec) R (km)
488 **
489 ** Mercury 4 1 300
490 ** Venus 5 1 800
491 ** EMB 6 1 1000
492 ** Mars 17 1 7700
493 ** Jupiter 71 5 76000
494 ** Saturn 81 13 267000
495 ** Uranus 86 7 712000
496 ** Neptune 11 1 253000
497 **
498 ** Over the interval 1000-3000, they report that the accuracy is no
499 ** worse than 1.5 times that over 1800-2050. Outside 1000-3000 the
500 ** accuracy declines.
501 **
502 ** Comparisons of the present function with the JPL DE200 ephemeris
503 ** give the following RMS errors over the interval 1960-2025:
504 **
505 ** position (km) velocity (m/s)
506 **
507 ** Mercury 334 0.437
508 ** Venus 1060 0.855
509 ** EMB 2010 0.815
510 ** Mars 7690 1.98
511 ** Jupiter 71700 7.70
512 ** Saturn 199000 19.4
513 ** Uranus 564000 16.4
514 ** Neptune 158000 14.4
515 **
516 ** Comparisons against DE200 over the interval 1800-2100 gave the
517 ** following maximum absolute differences. (The results using
518 ** DE406 were essentially the same.)
519 **
520 ** L (arcsec) B (arcsec) R (km) Rdot (m/s)
521 **
522 ** Mercury 7 1 500 0.7
523 ** Venus 7 1 1100 0.9
524 ** EMB 9 1 1300 1.0
525 ** Mars 26 1 9000 2.5
526 ** Jupiter 78 6 82000 8.2
527 ** Saturn 87 14 263000 24.6
528 ** Uranus 86 7 661000 27.4
529 ** Neptune 11 2 248000 21.4
530 **
531 ** 6) The present SOFA re-implementation of the original Simon et al.
532 ** Fortran code differs from the original in the following respects:
533 **
534 ** * C instead of Fortran.
535 **
536 ** * The date is supplied in two parts.
537 **
538 ** * The result is returned only in equatorial Cartesian form;
539 ** the ecliptic longitude, latitude and radius vector are not
540 ** returned.
541 **
542 ** * The result is in the J2000.0 equatorial frame, not ecliptic.
543 **
544 ** * More is done in-line: there are fewer calls to subroutines.
545 **
546 ** * Different error/warning status values are used.
547 **
548 ** * A different Kepler's-equation-solver is used (avoiding
549 ** use of double precision complex).
550 **
551 ** * Polynomials in t are nested to minimize rounding errors.
552 **
553 ** * Explicit double constants are used to avoid mixed-mode
554 ** expressions.
555 **
556 ** None of the above changes affects the result significantly.
557 **
558 ** 7) The returned status indicates the most serious condition
559 ** encountered during execution of the function. Illegal np is
560 ** considered the most serious, overriding failure to converge,
561 ** which in turn takes precedence over the remote date warning.
562 **
563 ** Called:
564 ** iauAnp normalize angle into range 0 to 2pi
565 **
566 ** Reference: Simon, J.L, Bretagnon, P., Chapront, J.,
567 ** Chapront-Touze, M., Francou, G., and Laskar, J.,
568 ** Astron. Astrophys. 282, 663 (1994).
569 **
570 ** This revision: 2017 March 16
571 **
572 ** SOFA release 2017-04-20
573 **
574 ** Copyright (C) 2017 IAU SOFA Board. See notes at end.
575 */
576 {
577  /* Gaussian constant */
578  static const double GK = 0.017202098950;
579 
580 /* Sin and cos of J2000.0 mean obliquity (IAU 1976) */
581  static const double SINEPS = 0.3977771559319137;
582  static const double COSEPS = 0.9174820620691818;
583 
584 /* Maximum number of iterations allowed to solve Kepler's equation */
585  static const int KMAX = 10;
586 
587  int jstat, k;
588  double t, da, dl, de, dp, di, dom, dmu, arga, argl, am,
589  ae, dae, ae2, at, r, v, si2, xq, xp, tl, xsw,
590  xcw, xm2, xf, ci2, xms, xmc, xpxq2, x, y, z;
591 
592 /* Planetary inverse masses */
593  static const double amas[] = { 6023600.0, /* Mercury */
594  408523.5, /* Venus */
595  328900.5, /* EMB */
596  3098710.0, /* Mars */
597  1047.355, /* Jupiter */
598  3498.5, /* Saturn */
599  22869.0, /* Uranus */
600  19314.0 }; /* Neptune */
601 
602 /*
603 ** Tables giving the mean Keplerian elements, limited to t^2 terms:
604 **
605 ** a semi-major axis (au)
606 ** dlm mean longitude (degree and arcsecond)
607 ** e eccentricity
608 ** pi longitude of the perihelion (degree and arcsecond)
609 ** dinc inclination (degree and arcsecond)
610 ** omega longitude of the ascending node (degree and arcsecond)
611 */
612 
613  static const double a[][3] = {
614  { 0.3870983098, 0.0, 0.0 }, /* Mercury */
615  { 0.7233298200, 0.0, 0.0 }, /* Venus */
616  { 1.0000010178, 0.0, 0.0 }, /* EMB */
617  { 1.5236793419, 3e-10, 0.0 }, /* Mars */
618  { 5.2026032092, 19132e-10, -39e-10 }, /* Jupiter */
619  { 9.5549091915, -0.0000213896, 444e-10 }, /* Saturn */
620  { 19.2184460618, -3716e-10, 979e-10 }, /* Uranus */
621  { 30.1103868694, -16635e-10, 686e-10 } /* Neptune */
622  };
623 
624  static const double dlm[][3] = {
625  { 252.25090552, 5381016286.88982, -1.92789 },
626  { 181.97980085, 2106641364.33548, 0.59381 },
627  { 100.46645683, 1295977422.83429, -2.04411 },
628  { 355.43299958, 689050774.93988, 0.94264 },
629  { 34.35151874, 109256603.77991, -30.60378 },
630  { 50.07744430, 43996098.55732, 75.61614 },
631  { 314.05500511, 15424811.93933, -1.75083 },
632  { 304.34866548, 7865503.20744, 0.21103 }
633  };
634 
635  static const double e[][3] = {
636  { 0.2056317526, 0.0002040653, -28349e-10 },
637  { 0.0067719164, -0.0004776521, 98127e-10 },
638  { 0.0167086342, -0.0004203654, -0.0000126734 },
639  { 0.0934006477, 0.0009048438, -80641e-10 },
640  { 0.0484979255, 0.0016322542, -0.0000471366 },
641  { 0.0555481426, -0.0034664062, -0.0000643639 },
642  { 0.0463812221, -0.0002729293, 0.0000078913 },
643  { 0.0094557470, 0.0000603263, 0.0 }
644  };
645 
646  static const double pi[][3] = {
647  { 77.45611904, 5719.11590, -4.83016 },
648  { 131.56370300, 175.48640, -498.48184 },
649  { 102.93734808, 11612.35290, 53.27577 },
650  { 336.06023395, 15980.45908, -62.32800 },
651  { 14.33120687, 7758.75163, 259.95938 },
652  { 93.05723748, 20395.49439, 190.25952 },
653  { 173.00529106, 3215.56238, -34.09288 },
654  { 48.12027554, 1050.71912, 27.39717 }
655  };
656 
657  static const double dinc[][3] = {
658  { 7.00498625, -214.25629, 0.28977 },
659  { 3.39466189, -30.84437, -11.67836 },
660  { 0.0, 469.97289, -3.35053 },
661  { 1.84972648, -293.31722, -8.11830 },
662  { 1.30326698, -71.55890, 11.95297 },
663  { 2.48887878, 91.85195, -17.66225 },
664  { 0.77319689, -60.72723, 1.25759 },
665  { 1.76995259, 8.12333, 0.08135 }
666  };
667 
668  static const double omega[][3] = {
669  { 48.33089304, -4515.21727, -31.79892 },
670  { 76.67992019, -10008.48154, -51.32614 },
671  { 174.87317577, -8679.27034, 15.34191 },
672  { 49.55809321, -10620.90088, -230.57416 },
673  { 100.46440702, 6362.03561, 326.52178 },
674  { 113.66550252, -9240.19942, -66.23743 },
675  { 74.00595701, 2669.15033, 145.93964 },
676  { 131.78405702, -221.94322, -0.78728 }
677  };
678 
679 /* Tables for trigonometric terms to be added to the mean elements of */
680 /* the semi-major axes */
681 
682  static const double kp[][9] = {
683  { 69613, 75645, 88306, 59899, 15746, 71087, 142173, 3086, 0 },
684  { 21863, 32794, 26934, 10931, 26250, 43725, 53867, 28939, 0 },
685  { 16002, 21863, 32004, 10931, 14529, 16368, 15318, 32794, 0 },
686  { 6345, 7818, 15636, 7077, 8184, 14163, 1107, 4872, 0 },
687  { 1760, 1454, 1167, 880, 287, 2640, 19, 2047, 1454 },
688  { 574, 0, 880, 287, 19, 1760, 1167, 306, 574 },
689  { 204, 0, 177, 1265, 4, 385, 200, 208, 204 },
690  { 0, 102, 106, 4, 98, 1367, 487, 204, 0 }
691  };
692 
693  static const double ca[][9] = {
694  { 4, -13, 11, -9, -9, -3, -1, 4, 0 },
695  { -156, 59, -42, 6, 19, -20, -10, -12, 0 },
696  { 64, -152, 62, -8, 32, -41, 19, -11, 0 },
697  { 124, 621, -145, 208, 54, -57, 30, 15, 0 },
698  { -23437, -2634, 6601, 6259, -1507,-1821, 2620, -2115, -1489 },
699  { 62911,-119919, 79336,17814,-24241,12068, 8306, -4893, 8902 },
700  { 389061,-262125,-44088, 8387,-22976,-2093, -615, -9720, 6633 },
701  { -412235,-157046,-31430,37817, -9740, -13, -7449, 9644, 0 }
702  };
703 
704  static const double sa[][9] = {
705  { -29, -1, 9, 6, -6, 5, 4, 0, 0 },
706  { -48, -125, -26, -37, 18, -13, -20, -2, 0 },
707  { -150, -46, 68, 54, 14, 24, -28, 22, 0 },
708  { -621, 532, -694, -20, 192, -94, 71, -73, 0 },
709  { -14614,-19828, -5869, 1881, -4372, -2255, 782, 930, 913 },
710  { 139737, 0, 24667, 51123, -5102, 7429, -4095, -1976, -9566 },
711  { -138081, 0, 37205,-49039,-41901,-33872,-27037,-12474, 18797 },
712  { 0, 28492,133236, 69654, 52322,-49577,-26430, -3593, 0 }
713  };
714 
715 /* Tables giving the trigonometric terms to be added to the mean */
716 /* elements of the mean longitudes */
717 
718  static const double kq[][10] = {
719  { 3086,15746,69613,59899,75645,88306, 12661, 2658, 0, 0 },
720  { 21863,32794,10931, 73, 4387,26934, 1473, 2157, 0, 0 },
721  { 10,16002,21863,10931, 1473,32004, 4387, 73, 0, 0 },
722  { 10, 6345, 7818, 1107,15636, 7077, 8184, 532, 10, 0 },
723  { 19, 1760, 1454, 287, 1167, 880, 574, 2640, 19, 1454 },
724  { 19, 574, 287, 306, 1760, 12, 31, 38, 19, 574 },
725  { 4, 204, 177, 8, 31, 200, 1265, 102, 4, 204 },
726  { 4, 102, 106, 8, 98, 1367, 487, 204, 4, 102 }
727  };
728 
729  static const double cl[][10] = {
730  { 21, -95, -157, 41, -5, 42, 23, 30, 0, 0 },
731  { -160, -313, -235, 60, -74, -76, -27, 34, 0, 0 },
732  { -325, -322, -79, 232, -52, 97, 55, -41, 0, 0 },
733  { 2268, -979, 802, 602, -668, -33, 345, 201, -55, 0 },
734  { 7610, -4997,-7689,-5841,-2617, 1115,-748,-607, 6074, 354 },
735  { -18549, 30125,20012, -730, 824, 23,1289,-352, -14767, -2062 },
736  { -135245,-14594, 4197,-4030,-5630,-2898,2540,-306, 2939, 1986 },
737  { 89948, 2103, 8963, 2695, 3682, 1648, 866,-154, -1963, -283 }
738  };
739 
740  static const double sl[][10] = {
741  { -342, 136, -23, 62, 66, -52, -33, 17, 0, 0 },
742  { 524, -149, -35, 117, 151, 122, -71, -62, 0, 0 },
743  { -105, -137, 258, 35, -116, -88,-112, -80, 0, 0 },
744  { 854, -205, -936, -240, 140, -341, -97, -232, 536, 0 },
745  { -56980, 8016, 1012, 1448,-3024,-3710, 318, 503, 3767, 577 },
746  { 138606,-13478,-4964, 1441,-1319,-1482, 427, 1236, -9167, -1918 },
747  { 71234,-41116, 5334,-4935,-1848, 66, 434, -1748, 3780, -701 },
748  { -47645, 11647, 2166, 3194, 679, 0,-244, -419, -2531, 48 }
749  };
750 
751 /*--------------------------------------------------------------------*/
752 
753  REQUIRE_NOT_NULL(j2kV_au);
754  REQUIRE((np > 0) && (np <= 8));
755 
756 #if 0
757 /* Validate the planet number. */
758  if ((np < 1) || (np > 8)) {
759  jstat = -1;
760 
761  /* Reset the result in case of failure. */
762  for (k = 0; k < 2; k++) {
763  for (i = 0; i < 3; i++) {
764  pv[k][i] = 0.0;
765  }
766  }
767 
768  } else {
769 #else
770  {
771 #endif
772  /* Decrement the planet number to start at zero. */
773  np--;
774 
775  /* Time: Julian millennia since J2000.0. */
776  t = t_cy / 10.0;
777 
778  /* OK status unless remote date. */
779  jstat = fabs(t) <= 1.0 ? 0 : 1;
780 
781  /* Compute the mean elements. */
782  da = a[np][0] +
783  (a[np][1] +
784  a[np][2] * t) * t;
785  dl = (3600.0 * dlm[np][0] +
786  (dlm[np][1] +
787  dlm[np][2] * t) * t) * ARCSEC2RAD;
788  de = e[np][0] +
789  ( e[np][1] +
790  e[np][2] * t) * t;
791  dp = normalize((3600.0 * pi[np][0] +
792  (pi[np][1] +
793  pi[np][2] * t) * t) * ARCSEC2RAD,
794  TWOPI);
795  di = (3600.0 * dinc[np][0] +
796  (dinc[np][1] +
797  dinc[np][2] * t) * t) * ARCSEC2RAD;
798  dom = normalize((3600.0 * omega[np][0] +
799  (omega[np][1] +
800  omega[np][2] * t) * t) * ARCSEC2RAD,
801  TWOPI);
802 
803  /* Apply the trigonometric terms. */
804  dmu = 0.35953620 * t;
805  for (k = 0; k < 8; k++) {
806  arga = kp[np][k] * dmu;
807  argl = kq[np][k] * dmu;
808  da += (ca[np][k] * cos(arga) +
809  sa[np][k] * sin(arga)) * 1e-7;
810  dl += (cl[np][k] * cos(argl) +
811  sl[np][k] * sin(argl)) * 1e-7;
812  }
813  arga = kp[np][8] * dmu;
814  da += t * (ca[np][8] * cos(arga) +
815  sa[np][8] * sin(arga)) * 1e-7;
816  for (k = 8; k < 10; k++) {
817  argl = kq[np][k] * dmu;
818  dl += t * (cl[np][k] * cos(argl) +
819  sl[np][k] * sin(argl)) * 1e-7;
820  }
821  dl = fmod(dl, TWOPI);
822 
823  /* Iterative soln. of Kepler's equation to get eccentric anomaly. */
824  am = dl - dp;
825  ae = am + de * sin(am);
826  k = 0;
827  dae = 1.0;
828  while (k < KMAX && fabs(dae) > 1e-12) {
829  dae = (am - ae + de * sin(ae)) / (1.0 - de * cos(ae));
830  ae += dae;
831  k++;
832  if (k == KMAX-1) jstat = 2;
833  }
834 
835  /* True anomaly. */
836  ae2 = ae / 2.0;
837  at = 2.0 * atan2(sqrt((1.0 + de) / (1.0 - de)) * sin(ae2),
838  cos(ae2));
839 
840  /* Distance (au) and speed (radians per day). */
841  r = da * (1.0 - de * cos(ae));
842  v = GK * sqrt((1.0 + 1.0 / amas[np]) / (da * da * da));
843 
844  si2 = sin(di / 2.0);
845  xq = si2 * cos(dom);
846  xp = si2 * sin(dom);
847  tl = at + dp;
848  xsw = sin(tl);
849  xcw = cos(tl);
850  xm2 = 2.0 * (xp * xcw - xq * xsw);
851  ci2 = cos(di / 2.0);
852  xf = da / sqrt(1 - de * de);
853  xms = (de * sin(dp) + xsw) * xf;
854  xmc = (de * cos(dp) + xcw) * xf;
855  xpxq2 = 2 * xp * xq;
856 
857  /* Position (J2000.0 ecliptic x,y,z in au). */
858  x = r * (xcw - xm2 * xp);
859  y = r * (xsw + xm2 * xq);
860  z = r * (-xm2 * ci2);
861 
862  /* Rotate to equatorial. */
863  j2kV_au->a[0] = x;
864  j2kV_au->a[1] = y * COSEPS - z * SINEPS;
865  j2kV_au->a[2] = y * SINEPS + z * COSEPS;
866 
867  /* Velocity (J2000.0 ecliptic xdot,ydot,zdot in au/d). */
868  if (velV_aupd != NULL) {
869  x = v * (( -1.0 + 2.0 * xp * xp) * xms + xpxq2 * xmc);
870  y = v * (( 1.0 - 2.0 * xq * xq) * xmc - xpxq2 * xms);
871  z = v * (2.0 * ci2 * (xp * xms + xq * xmc));
872 
873  /* Rotate to equatorial. */
874  velV_aupd->a[0] = x;
875  velV_aupd->a[1] = y * COSEPS - z * SINEPS;
876  velV_aupd->a[2] = y * SINEPS + z * COSEPS;
877  }
878  }
879 
880 /* Return the status. */
881  return jstat;
882 
883 /*----------------------------------------------------------------------
884 **
885 ** Copyright (C) 2017
886 ** Standards Of Fundamental Astronomy Board
887 ** of the International Astronomical Union.
888 **
889 ** =====================
890 ** SOFA Software License
891 ** =====================
892 **
893 ** NOTICE TO USER:
894 **
895 ** BY USING THIS SOFTWARE YOU ACCEPT THE FOLLOWING SIX TERMS AND
896 ** CONDITIONS WHICH APPLY TO ITS USE.
897 **
898 ** 1. The Software is owned by the IAU SOFA Board ("SOFA").
899 **
900 ** 2. Permission is granted to anyone to use the SOFA software for any
901 ** purpose, including commercial applications, free of charge and
902 ** without payment of royalties, subject to the conditions and
903 ** restrictions listed below.
904 **
905 ** 3. You (the user) may copy and distribute SOFA source code to others,
906 ** and use and adapt its code and algorithms in your own software,
907 ** on a world-wide, royalty-free basis. That portion of your
908 ** distribution that does not consist of intact and unchanged copies
909 ** of SOFA source code files is a "derived work" that must comply
910 ** with the following requirements:
911 **
912 ** a) Your work shall be marked or carry a statement that it
913 ** (i) uses routines and computations derived by you from
914 ** software provided by SOFA under license to you; and
915 ** (ii) does not itself constitute software provided by and/or
916 ** endorsed by SOFA.
917 **
918 ** b) The source code of your derived work must contain descriptions
919 ** of how the derived work is based upon, contains and/or differs
920 ** from the original SOFA software.
921 **
922 ** c) The names of all routines in your derived work shall not
923 ** include the prefix "iau" or "sofa" or trivial modifications
924 ** thereof such as changes of case.
925 **
926 ** d) The origin of the SOFA components of your derived work must
927 ** not be misrepresented; you must not claim that you wrote the
928 ** original software, nor file a patent application for SOFA
929 ** software or algorithms embedded in the SOFA software.
930 **
931 ** e) These requirements must be reproduced intact in any source
932 ** distribution and shall apply to anyone to whom you have
933 ** granted a further right to modify the source code of your
934 ** derived work.
935 **
936 ** Note that, as originally distributed, the SOFA software is
937 ** intended to be a definitive implementation of the IAU standards,
938 ** and consequently third-party modifications are discouraged. All
939 ** variations, no matter how minor, must be explicitly marked as
940 ** such, as explained above.
941 **
942 ** 4. You shall not cause the SOFA software to be brought into
943 ** disrepute, either by misuse, or use for inappropriate tasks, or
944 ** by inappropriate modification.
945 **
946 ** 5. The SOFA software is provided "as is" and SOFA makes no warranty
947 ** as to its use or performance. SOFA does not and cannot warrant
948 ** the performance or results which the user may obtain by using the
949 ** SOFA software. SOFA makes no warranties, express or implied, as
950 ** to non-infringement of third party rights, merchantability, or
951 ** fitness for any particular purpose. In no event will SOFA be
952 ** liable to the user for any consequential, incidental, or special
953 ** damages, including any lost profits or lost savings, even if a
954 ** SOFA representative has been advised of such damages, or for any
955 ** claim by any third party.
956 **
957 ** 6. The provision of any version of the SOFA software under the terms
958 ** and conditions specified herein does not imply that future
959 ** versions will also be made available under the same terms and
960 ** conditions.
961 *
962 ** In any published work or commercial product which uses the SOFA
963 ** software directly, acknowledgement (see www.iausofa.org) is
964 ** appreciated.
965 **
966 ** Correspondence concerning SOFA software should be addressed as
967 ** follows:
968 **
969 ** By email: sofa@ukho.gov.uk
970 ** By post: IAU SOFA Center
971 ** HM Nautical Almanac Office
972 ** UK Hydrographic Office
973 ** Admiralty Way, Taunton
974 ** Somerset, TA1 2DN
975 ** United Kingdom
976 **
977 **--------------------------------------------------------------------*/
978 }
979 
980 
981 /*
982  *------------------------------------------------------------------------------
983  *
984  * Local functions (not called from other modules)
985  *
986  *------------------------------------------------------------------------------
987  */
988 
989 LOCAL int planetGetEarth(double t_cy,
990  V3D_Vector *j2kV_au,
991  V3D_Vector *velV_aupd)
992 /* Get a heliocentric position vector for the Earth in J2000 coordinates, and
993  a velocity vector for the Earth also.
994 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
995 {
996  /* For the moment, cheat. Use the same planet function that we are using for
997  * all the other planets to get the position of the Earth. That is, treat
998  * the Earth-Moon Barycenter as if it is the position of the Earth. */
999  return planet_getHeliocentric(t_cy, 3, j2kV_au, velV_aupd);
1000 }
1001 
1002 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
sky1.h
sky1.h - astronomical coordinate conversion routines, IAU 1980
planet_getApparent
void planet_getApparent(double j2kTT_cy, Sky_TrueEquatorial *pos)
Calculate the position of the currently selected planet as a unit vector and a distance,...
Definition: planet.c:154
v3d_multMxM
V3D_Matrix * v3d_multMxM(V3D_Matrix *destM, const V3D_Matrix *srcM1, const V3D_Matrix *srcM2)
Multiply 3x3 matrix by 3x3 matrix to give a new 3x3 matrix, as per [destM] = [srcM1]*[srcM2].
Definition: vectors3d.c:517
general.h
general.h - definitions of general use to (standard) C programs
Sky_TrueEquatorial::appCirsV
V3D_Vector appCirsV
Direction of object in apparent or CIRS coordinates (effectively a unit vector).
Definition: sky.h:110
Sky_DeltaTs
This structure contains relatively constant data, and is set up by one of the three functions sky_ini...
Definition: sky.h:166
planet.h
planet.h - Astronomical routines to get the positions of planets
REQUIRE
#define REQUIRE(test_)
Check preconditions.
Definition: general.h:273
sky_siteTirsToTopo
void sky_siteTirsToTopo(const V3D_Vector *terInterV, double dist_au, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
Transform a coordinate vector from the Terrestrial Intermediate Reference System to topocentric Az/El...
Definition: sky-site.c:378
planet_getApp2
void planet_getApp2(double t_cy, int np, const Sky1_Nut1980 *nut, V3D_Vector *appV, double *dist_au)
This function calculates the specified planet's position in apparent coordinates, using the planet_ge...
Definition: planet.c:105
Sky1_Nut1980
Nutation angles and obliquity.
Definition: sky1.h:75
v3d_magV
double v3d_magV(const V3D_Vector *srcV)
Return the magnitude of the specified vector.
Definition: vectors3d.c:271
astron.h
astron.h - assorted definitions useful for astronomy
sky_updateTimes
void sky_updateTimes(double j2kUtc_d, const Sky_DeltaTs *d, Sky_Times *t)
Convert the given "J2KD" in the UTC timescale to the other timescales, and pre-calculate some other q...
Definition: sky-time.c:206
planet_getTopocentric
void planet_getTopocentric(double j2kUtc_d, const Sky_DeltaTs *deltas, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
Calls planet_getApparent() to calculate the planet's position in apparent coordinates,...
Definition: planet.c:195
sky1_epsilon1980
void sky1_epsilon1980(double t_cy, Sky1_Nut1980 *nut)
Calculate the obliquity of the ecliptic and the equation of the equinoxes.
Definition: sky1.c:631
Sky_TrueEquatorial
Struct used for holding an object's coordinates in equatorial apparent or Intermediate coordinates.
Definition: sky.h:106
planet_getHeliocentric
int planet_getHeliocentric(double t_cy, int np, V3D_Vector *j2kV_au, V3D_Vector *velV_aupd)
Calculates an approximate heliocentric position of the selected planet.
Definition: planet.c:344
LOCAL
#define LOCAL
C has some very silly default behaviours.
Definition: general.h:133
GLOBAL
#define GLOBAL
See above.
Definition: general.h:134
Sky_Times::j2kTT_cy
double j2kTT_cy
Julian centuries since J2000.0, TT timescale [T].
Definition: sky.h:188
REQUIRE_NOT_NULL
#define REQUIRE_NOT_NULL(pointer_)
,
Definition: general.h:308
Sky_Times
This structure contains the continuously varying time (and earth rotation) data, in various forms tha...
Definition: sky.h:184
ARCSEC2RAD
#define ARCSEC2RAD
arcseconds to radians
Definition: astron.h:29
Sky_TrueEquatorial::eqEq_rad
double eqEq_rad
Equation of the Equinoxes (radian).
Definition: sky.h:115
Sky_SiteProp
Site properties.
Definition: sky.h:315
TWOPI
#define TWOPI
,
Definition: general.h:160
sky1_createNut1980Matrix
void sky1_createNut1980Matrix(const Sky1_Nut1980 *nut, V3D_Matrix *nutM)
This routine calculates the Nutation matrix, using the nutation in longitude, the nutation in obliqui...
Definition: sky1.c:676
Sky_TrueEquatorial::timestamp_cy
double timestamp_cy
Time applying to the other figures in this struct (centuries since J2000.0, TT timescale)
Definition: sky.h:107
sky1_appToTirs
void sky1_appToTirs(const V3D_Vector *appV, double j2kUT1_d, double eqEq_rad, V3D_Vector *terInterV)
Convert a position in geocentric apparent coordinates to geocentric coordinates in the Terrestrial In...
Definition: sky1.c:810
planet_getGeocentric
void planet_getGeocentric(double t_cy, int np, V3D_Vector *p2V, double *dist_au)
Calculates an approximate position of the selected planet as seen from the centre of the earth.
Definition: planet.c:242
V3D_Matrix
3x3 matrix.
Definition: vectors3d.h:51
planet_setCurrent
void planet_setCurrent(int np)
Stores the selected planet number np in internal storage for later use by planet_getApparent() or pla...
Definition: planet.c:89
Sky_TrueEquatorial::distance_au
double distance_au
Distance to object (Astronomical Units) or 0.0 for far distant objects (that is, those with negligibl...
Definition: sky.h:112
instead-of-math.h
instead-of-math.h - header to be included instead of math.h
v3d_subtractV
V3D_Vector * v3d_subtractV(V3D_Vector *destV, const V3D_Vector *srcV1, const V3D_Vector *srcV2)
Vector subtraction: [destV] = [srcV1] - [srcV2].
Definition: vectors3d.c:106
V3D_Vector
3x1 vector.
Definition: vectors3d.h:57
sky1_precessionIAU1976
void sky1_precessionIAU1976(double t0, double t1, Sky1_Prec1976 *terms)
This procedure calculates the equatorial precession parameters ζ, z, and θ which represent the rotati...
Definition: sky1.c:375
sky.h
sky.h - structures and routines for astronomical observing & tracking
JUL_CENT
#define JUL_CENT
Length of Julian Century in days.
Definition: astron.h:27
vectors3d.h
vectors3d.h - Three dimensional geometry, vectors and matrices
sky1_createPrec1976Matrix
void sky1_createPrec1976Matrix(const Sky1_Prec1976 *terms, V3D_Matrix *precM)
This routine calculates the precession matrix, based on angles ζ, z, and θ.
Definition: sky1.c:437
Sky_Times::j2kUT1_d
double j2kUT1_d
days since J2000.0, UT1 timescale [Du]
Definition: sky.h:186
Sky1_Nut1980::eqEq_rad
double eqEq_rad
Equation of the Equinoxes (radian)
Definition: sky1.h:79
sky1_nutationIAU1980
void sky1_nutationIAU1980(double t_cy, int precision, Sky1_Nut1980 *nut)
Calculates the nutation in longitude and obliquity, according to the IAU 1980 Nutation Theory.
Definition: sky1.c:481
v3d_addToUVfast
V3D_Vector * v3d_addToUVfast(V3D_Vector *modV1, const V3D_Vector *srcV2)
Modify a unit length rectangular position vector modV1 by adding a small correction vector srcV2 to i...
Definition: vectors3d.c:223
Sky1_Prec1976
Precession angles.
Definition: sky1.h:68
v3d_multMxV
V3D_Vector * v3d_multMxV(V3D_Vector *destV, const V3D_Matrix *srcM, const V3D_Vector *srcV)
Multiply 3x3 matrix by 3x1 vector to give a new 3x1 vector, as per equation [destV] = [srcM] * [srcV]...
Definition: vectors3d.c:439
normalize
static double normalize(double x, double range)
Normalizes a cyclic double precision floating point variable x to the interval [0,...
Definition: instead-of-math.h:144
Sky_SiteHorizon
Coordinates of a celestial object in the horizon frame, in both rectangular and polar forms.
Definition: sky.h:129