void eraNumat(double epsa, double dpsi, double deps, double rmatn[3][3]) /* ** - - - - - - - - - ** e r a N u m a t ** - - - - - - - - - ** ** Form the matrix of nutation. ** ** Given: ** epsa double mean obliquity of date (Note 1) ** dpsi,deps double nutation (Note 2) ** ** Returned: ** rmatn double[3][3] nutation matrix (Note 3) ** ** Notes: ** ** ** 1) The supplied mean obliquity epsa, must be consistent with the ** precession-nutation models from which dpsi and deps were obtained. ** ** 2) The caller is responsible for providing the nutation components; ** they are in longitude and obliquity, in radians and are with ** respect to the equinox and ecliptic of date. ** ** 3) The matrix operates in the sense V(true) = rmatn * V(mean), ** where the p-vector V(true) is with respect to the true ** equatorial triad of date and the p-vector V(mean) is with ** respect to the mean equatorial triad of date. ** ** Called: ** eraIr initialize r-matrix to identity ** eraRx rotate around X-axis ** eraRz rotate around Z-axis ** ** Reference: ** ** Explanatory Supplement to the Astronomical Almanac, ** P. Kenneth Seidelmann (ed), University Science Books (1992), ** Section 3.222-3 (p114). ** ** Copyright (C) 2013-2014, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { /* Build the rotation matrix. */ eraIr(rmatn); eraRx(epsa, rmatn); eraRz(-dpsi, rmatn); eraRx(-(epsa + deps), rmatn); return; }
void palDeuler( const char *order, double phi, double theta, double psi, double rmat[3][3] ) { int i = 0; double rotations[3]; /* Initialise rmat */ eraIr( rmat ); /* copy the rotations into an array */ rotations[0] = phi; rotations[1] = theta; rotations[2] = psi; /* maximum three rotations */ while (i < 3 && order[i] != '\0') { switch (order[i]) { case 'X': case 'x': case '1': eraRx( rotations[i], rmat ); break; case 'Y': case 'y': case '2': eraRy( rotations[i], rmat ); break; case 'Z': case 'z': case '3': eraRz( rotations[i], rmat ); break; default: /* break out the loop if we do not recognize something */ i = 3; } /* Go to the next position */ i++; } return; }
void eraC2teqx(double rbpn[3][3], double gst, double rpom[3][3], double rc2t[3][3]) /* ** - - - - - - - - - - ** e r a C 2 t e q x ** - - - - - - - - - - ** ** Assemble the celestial to terrestrial matrix from equinox-based ** components (the celestial-to-true matrix, the Greenwich Apparent ** Sidereal Time and the polar motion matrix). ** ** Given: ** rbpn double[3][3] celestial-to-true matrix ** gst double Greenwich (apparent) Sidereal Time ** rpom double[3][3] polar-motion matrix ** ** Returned: ** rc2t double[3][3] celestial-to-terrestrial matrix (Note 2) ** ** Notes: ** ** 1) This function constructs the rotation matrix that transforms ** vectors in the celestial system into vectors in the terrestrial ** system. It does so starting from precomputed components, namely ** the matrix which rotates from celestial coordinates to the ** true equator and equinox of date, the Greenwich Apparent Sidereal ** Time and the polar motion matrix. One use of the present function ** is when generating a series of celestial-to-terrestrial matrices ** where only the Sidereal Time changes, avoiding the considerable ** overhead of recomputing the precession-nutation more often than ** necessary to achieve given accuracy objectives. ** ** 2) The relationship between the arguments is as follows: ** ** [TRS] = rpom * R_3(gst) * rbpn * [CRS] ** ** = rc2t * [CRS] ** ** where [CRS] is a vector in the Geocentric Celestial Reference ** System and [TRS] is a vector in the International Terrestrial ** Reference System (see IERS Conventions 2003). ** ** Called: ** eraCr copy r-matrix ** eraRz rotate around Z-axis ** eraRxr product of two r-matrices ** ** Reference: ** ** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), ** IERS Technical Note No. 32, BKG (2004) ** ** Copyright (C) 2013, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { double r[3][3]; /* Construct the matrix. */ eraCr(rbpn, r); eraRz(gst, r); eraRxr(rpom, r, rc2t); return; }
void eraC2ixys(double x, double y, double s, double rc2i[3][3]) /* ** - - - - - - - - - - ** e r a C 2 i x y s ** - - - - - - - - - - ** ** Form the celestial to intermediate-frame-of-date matrix given the CIP ** X,Y and the CIO locator s. ** ** Given: ** x,y double Celestial Intermediate Pole (Note 1) ** s double the CIO locator s (Note 2) ** ** Returned: ** rc2i double[3][3] celestial-to-intermediate matrix (Note 3) ** ** Notes: ** ** 1) The Celestial Intermediate Pole coordinates are the x,y ** components of the unit vector in the Geocentric Celestial ** Reference System. ** ** 2) The CIO locator s (in radians) positions the Celestial ** Intermediate Origin on the equator of the CIP. ** ** 3) The matrix rc2i is the first stage in the transformation from ** celestial to terrestrial coordinates: ** ** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] ** ** = RC2T * [CRS] ** ** where [CRS] is a vector in the Geocentric Celestial Reference ** System and [TRS] is a vector in the International Terrestrial ** Reference System (see IERS Conventions 2003), ERA is the Earth ** Rotation Angle and RPOM is the polar motion matrix. ** ** Called: ** eraIr initialize r-matrix to identity ** eraRz rotate around Z-axis ** eraRy rotate around Y-axis ** ** Reference: ** ** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), ** IERS Technical Note No. 32, BKG (2004) ** ** Copyright (C) 2013-2014, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { double r2, e, d; /* Obtain the spherical angles E and d. */ r2 = x*x + y*y; e = (r2 != 0.0) ? atan2(y, x) : 0.0; d = atan(sqrt(r2 / (1.0 - r2))); /* Form the matrix. */ eraIr(rc2i); eraRz(e, rc2i); eraRy(d, rc2i); eraRz(-(e+s), rc2i); return; }
void eraBp00(double date1, double date2, double rb[3][3], double rp[3][3], double rbp[3][3]) /* ** - - - - - - - - ** e r a B p 0 0 ** - - - - - - - - ** ** Frame bias and precession, IAU 2000. ** ** Given: ** date1,date2 double TT as a 2-part Julian Date (Note 1) ** ** Returned: ** rb double[3][3] frame bias matrix (Note 2) ** rp double[3][3] precession matrix (Note 3) ** rbp double[3][3] bias-precession matrix (Note 4) ** ** Notes: ** ** 1) The TT date date1+date2 is a Julian Date, apportioned in any ** convenient way between the two arguments. For example, ** JD(TT)=2450123.7 could be expressed in any of these ways, ** among others: ** ** date1 date2 ** ** 2450123.7 0.0 (JD method) ** 2451545.0 -1421.3 (J2000 method) ** 2400000.5 50123.2 (MJD method) ** 2450123.5 0.2 (date & time method) ** ** The JD method is the most natural and convenient to use in ** cases where the loss of several decimal digits of resolution ** is acceptable. The J2000 method is best matched to the way ** the argument is handled internally and will deliver the ** optimum resolution. The MJD method and the date & time methods ** are both good compromises between resolution and convenience. ** ** 2) The matrix rb transforms vectors from GCRS to mean J2000.0 by ** applying frame bias. ** ** 3) The matrix rp transforms vectors from J2000.0 mean equator and ** equinox to mean equator and equinox of date by applying ** precession. ** ** 4) The matrix rbp transforms vectors from GCRS to mean equator and ** equinox of date by applying frame bias then precession. It is ** the product rp x rb. ** ** 5) It is permissible to re-use the same array in the returned ** arguments. The arrays are filled in the order given. ** ** Called: ** eraBi00 frame bias components, IAU 2000 ** eraPr00 IAU 2000 precession adjustments ** eraIr initialize r-matrix to identity ** eraRx rotate around X-axis ** eraRy rotate around Y-axis ** eraRz rotate around Z-axis ** eraCr copy r-matrix ** eraRxr product of two r-matrices ** ** Reference: ** "Expressions for the Celestial Intermediate Pole and Celestial ** Ephemeris Origin consistent with the IAU 2000A precession- ** nutation model", Astron.Astrophys. 400, 1145-1154 (2003) ** ** n.b. The celestial ephemeris origin (CEO) was renamed "celestial ** intermediate origin" (CIO) by IAU 2006 Resolution 2. ** ** Copyright (C) 2013-2017, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { /* J2000.0 obliquity (Lieske et al. 1977) */ const double EPS0 = 84381.448 * ERFA_DAS2R; double t, dpsibi, depsbi, dra0, psia77, oma77, chia, dpsipr, depspr, psia, oma, rbw[3][3]; /* Interval between fundamental epoch J2000.0 and current date (JC). */ t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC; /* Frame bias. */ eraBi00(&dpsibi, &depsbi, &dra0); /* Precession angles (Lieske et al. 1977) */ psia77 = (5038.7784 + (-1.07259 + (-0.001147) * t) * t) * t * ERFA_DAS2R; oma77 = EPS0 + ((0.05127 + (-0.007726) * t) * t) * t * ERFA_DAS2R; chia = ( 10.5526 + (-2.38064 + (-0.001125) * t) * t) * t * ERFA_DAS2R; /* Apply IAU 2000 precession corrections. */ eraPr00(date1, date2, &dpsipr, &depspr); psia = psia77 + dpsipr; oma = oma77 + depspr; /* Frame bias matrix: GCRS to J2000.0. */ eraIr(rbw); eraRz(dra0, rbw); eraRy(dpsibi*sin(EPS0), rbw); eraRx(-depsbi, rbw); eraCr(rbw, rb); /* Precession matrix: J2000.0 to mean of date. */ eraIr(rp); eraRx(EPS0, rp); eraRz(-psia, rp); eraRx(-oma, rp); eraRz(chia, rp); /* Bias-precession matrix: GCRS to mean of date. */ eraRxr(rp, rbw, rbp); return; }
void eraC2tcio(double rc2i[3][3], double era, double rpom[3][3], double rc2t[3][3]) /* ** - - - - - - - - - - ** e r a C 2 t c i o ** - - - - - - - - - - ** ** Assemble the celestial to terrestrial matrix from CIO-based ** components (the celestial-to-intermediate matrix, the Earth Rotation ** Angle and the polar motion matrix). ** ** Given: ** rc2i double[3][3] celestial-to-intermediate matrix ** era double Earth rotation angle (radians) ** rpom double[3][3] polar-motion matrix ** ** Returned: ** rc2t double[3][3] celestial-to-terrestrial matrix ** ** Notes: ** ** 1) This function constructs the rotation matrix that transforms ** vectors in the celestial system into vectors in the terrestrial ** system. It does so starting from precomputed components, namely ** the matrix which rotates from celestial coordinates to the ** intermediate frame, the Earth rotation angle and the polar motion ** matrix. One use of the present function is when generating a ** series of celestial-to-terrestrial matrices where only the Earth ** Rotation Angle changes, avoiding the considerable overhead of ** recomputing the precession-nutation more often than necessary to ** achieve given accuracy objectives. ** ** 2) The relationship between the arguments is as follows: ** ** [TRS] = RPOM * R_3(ERA) * rc2i * [CRS] ** ** = rc2t * [CRS] ** ** where [CRS] is a vector in the Geocentric Celestial Reference ** System and [TRS] is a vector in the International Terrestrial ** Reference System (see IERS Conventions 2003). ** ** Called: ** eraCr copy r-matrix ** eraRz rotate around Z-axis ** eraRxr product of two r-matrices ** ** Reference: ** ** McCarthy, D. D., Petit, G. (eds.), 2004, IERS Conventions (2003), ** IERS Technical Note No. 32, BKG ** ** Copyright (C) 2013-2015, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { double r[3][3]; /* Construct the matrix. */ eraCr(rc2i, r); eraRz(era, r); eraRxr(rpom, r, rc2t); return; }
void eraFw2m(double gamb, double phib, double psi, double eps, double r[3][3]) /* ** - - - - - - - - ** e r a F w 2 m ** - - - - - - - - ** ** Form rotation matrix given the Fukushima-Williams angles. ** ** Given: ** gamb double F-W angle gamma_bar (radians) ** phib double F-W angle phi_bar (radians) ** psi double F-W angle psi (radians) ** eps double F-W angle epsilon (radians) ** ** Returned: ** r double[3][3] rotation matrix ** ** Notes: ** ** 1) Naming the following points: ** ** e = J2000.0 ecliptic pole, ** p = GCRS pole, ** E = ecliptic pole of date, ** and P = CIP, ** ** the four Fukushima-Williams angles are as follows: ** ** gamb = gamma = epE ** phib = phi = pE ** psi = psi = pEP ** eps = epsilon = EP ** ** 2) The matrix representing the combined effects of frame bias, ** precession and nutation is: ** ** NxPxB = R_1(-eps).R_3(-psi).R_1(phib).R_3(gamb) ** ** 3) Three different matrices can be constructed, depending on the ** supplied angles: ** ** o To obtain the nutation x precession x frame bias matrix, ** generate the four precession angles, generate the nutation ** components and add them to the psi_bar and epsilon_A angles, ** and call the present function. ** ** o To obtain the precession x frame bias matrix, generate the ** four precession angles and call the present function. ** ** o To obtain the frame bias matrix, generate the four precession ** angles for date J2000.0 and call the present function. ** ** The nutation-only and precession-only matrices can if necessary ** be obtained by combining these three appropriately. ** ** Called: ** eraIr initialize r-matrix to identity ** eraRz rotate around Z-axis ** eraRx rotate around X-axis ** ** Reference: ** ** Hilton, J. et al., 2006, Celest.Mech.Dyn.Astron. 94, 351 ** ** Copyright (C) 2013-2015, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { /* Construct the matrix. */ eraIr(r); eraRz(gamb, r); eraRx(phib, r); eraRz(-psi, r); eraRx(-eps, r); return; }
void eraPb06(double date1, double date2, double *bzeta, double *bz, double *btheta) /* ** - - - - - - - - ** e r a P b 0 6 ** - - - - - - - - ** ** This function forms three Euler angles which implement general ** precession from epoch J2000.0, using the IAU 2006 model. Frame ** bias (the offset between ICRS and mean J2000.0) is included. ** ** Given: ** date1,date2 double TT as a 2-part Julian Date (Note 1) ** ** Returned: ** bzeta double 1st rotation: radians cw around z ** bz double 3rd rotation: radians cw around z ** btheta double 2nd rotation: radians ccw around y ** ** Notes: ** ** 1) The TT date date1+date2 is a Julian Date, apportioned in any ** convenient way between the two arguments. For example, ** JD(TT)=2450123.7 could be expressed in any of these ways, ** among others: ** ** date1 date2 ** ** 2450123.7 0.0 (JD method) ** 2451545.0 -1421.3 (J2000 method) ** 2400000.5 50123.2 (MJD method) ** 2450123.5 0.2 (date & time method) ** ** The JD method is the most natural and convenient to use in ** cases where the loss of several decimal digits of resolution ** is acceptable. The J2000 method is best matched to the way ** the argument is handled internally and will deliver the ** optimum resolution. The MJD method and the date & time methods ** are both good compromises between resolution and convenience. ** ** 2) The traditional accumulated precession angles zeta_A, z_A, ** theta_A cannot be obtained in the usual way, namely through ** polynomial expressions, because of the frame bias. The latter ** means that two of the angles undergo rapid changes near this ** date. They are instead the results of decomposing the ** precession-bias matrix obtained by using the Fukushima-Williams ** method, which does not suffer from the problem. The ** decomposition returns values which can be used in the ** conventional formulation and which include frame bias. ** ** 3) The three angles are returned in the conventional order, which ** is not the same as the order of the corresponding Euler ** rotations. The precession-bias matrix is ** R_3(-z) x R_2(+theta) x R_3(-zeta). ** ** 4) Should zeta_A, z_A, theta_A angles be required that do not ** contain frame bias, they are available by calling the ERFA ** function eraP06e. ** ** Called: ** eraPmat06 PB matrix, IAU 2006 ** eraRz rotate around Z-axis ** ** Copyright (C) 2013-2014, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { double r[3][3], r31, r32; /* Precession matrix via Fukushima-Williams angles. */ eraPmat06(date1, date2, r); /* Solve for z. */ *bz = atan2(r[1][2], r[0][2]); /* Remove it from the matrix. */ eraRz(*bz, r); /* Solve for the remaining two angles. */ *bzeta = atan2 (r[1][0], r[1][1]); r31 = r[2][0]; r32 = r[2][1]; *btheta = atan2(-ERFA_DSIGN(sqrt(r31 * r31 + r32 * r32), r[0][2]), r[2][2]); return; }