Example #1
0
// ICRS to TEME conversion
void icrs_to_teme(double mjd,double a[3][3])
{
  int i,j;
  double dpsi,deps,eps,z,theta,zeta,h;
  double p[3][3],n[3][3],q[3][3],b[3][3];

  // Precession
  precess(51544.5,mjd,&zeta,&z,&theta);
  identity_matrix(p);
  rotate_z(-zeta,p);
  rotate_y(theta,p);
  rotate_z(-z,p);

  // Nutation
  nutation(mjd,&dpsi,&deps,&eps);
  identity_matrix(n);
  rotate_x(eps,n);
  rotate_z(-dpsi,n);
  rotate_x(-eps-deps,n);

  // Equation of equinoxes
  identity_matrix(q);
  rotate_z(dpsi*cos(eps+deps),q);

  // Multiply matrices (left to right)
  matrix_multiply(q,n,b);
  matrix_multiply(b,p,a);

  return;
}
Example #2
0
void testnutation(void)
{
    double jd = 2411545.0;
    char deg[30];
    double d;
    d = nutation(jd) * RAD2DEG;
    fmtdeg(deg, d);
    printf("%s\n", deg);
}
Example #3
0
void vSOPPlanetInfo(char *dataDir, double tJD, int planet,
		    double *rA, double *dec, double *distance)
{
  double L, B, R, L0, B0, R0, x, y, z, lambda, beta, delta, tau,
    T, Lprime, deltaL, deltaB, deltaPhi, deltaEps, eps, tY, tX;

  heliocentricEclipticCoordinates(dataDir, tJD, 2, &L0, &B0, &R0);
  if (planet != SUN)
    heliocentricEclipticCoordinates(dataDir, tJD, planet, &L, &B, &R);
  else
    L = B = R = 0.0;
  x = R*cos(B)*cos(L) - R0*cos(B0)*cos(L0);
  y = R*cos(B)*sin(L) - R0*cos(B0)*sin(L0);
  z = R*sin(B)        - R0*sin(B0);
  delta = sqrt(x*x + y*y + z*z);
  tau = 0.0057755183*delta;
  heliocentricEclipticCoordinates(dataDir, tJD-tau, 2, &L0, &B0, &R0);
  if (planet != SUN)
    heliocentricEclipticCoordinates(dataDir, tJD-tau, planet, &L, &B, &R);
  else
    L = B = R = 0.0;
  x = R*cos(B)*cos(L) - R0*cos(B0)*cos(L0);
  y = R*cos(B)*sin(L) - R0*cos(B0)*sin(L0);
  z = R*sin(B)        - R0*sin(B0);
  lambda = atan2(y, x);
  doubleNormalize0to2pi(&lambda);
  beta   = atan2(z, sqrt(x*x + y*y));

  T = (tJD - 2451545.0) / 36525.0;
  Lprime = lambda - 1.397*DEGREES_TO_RADIANS*T - 0.00031*DEGREES_TO_RADIANS*T*T;
  deltaL = -0.09033*ARCSEC_TO_RADIANS
    + 0.03916*ARCSEC_TO_RADIANS*(cos(Lprime) + sin(Lprime))*tan(beta);
  deltaB = 0.03916*ARCSEC_TO_RADIANS*(cos(Lprime) - sin(Lprime));
  lambda += deltaL;
  beta   += deltaB;

  nutation(T, &deltaPhi, &deltaEps, &eps);
  eps *= DEGREES_TO_RADIANS;
  lambda += deltaPhi*ARCSEC_TO_RADIANS;
  tY = sin(lambda)*cos(eps) - tan(beta)*sin(eps) + 1.0;
  tX = cos(lambda) + 1.0;
  *rA  = atan2(sin(lambda)*cos(eps) - tan(beta)*sin(eps), cos(lambda));
  doubleNormalize0to2pi(rA);
  *dec = asin(sin(beta)*cos(eps) + cos(beta)*sin(eps)*sin(lambda));
  *distance = sqrt(x*x + y*y + z*z);
}
TimeIncrement 
EquationOfTime( double julianDay )
{
    shared_ptr< JPLEphemeris > spEphem
            = JPLEphemeris::GetEphemeris( julianDay );
    if ( ! spEphem )
        return TimeIncrement( 0 );
    Angle meanSolarLong = MeanSolarLongitude( julianDay );
    Point3D earthBarycentric;
    Vector3D earthBarycentricVelocity;
#ifdef DEBUG
    bool earthRslt =
#endif
            GetEarthBarycentric( julianDay, &earthBarycentric,
                                 &earthBarycentricVelocity, spEphem );
    Assert( earthRslt );
    Matrix3D precessionMatrix = Precession( julianDay ).Matrix( );
    Nutation nutation( 0., 0. );
    if ( spEphem->NutationAvailable() )
    {
#ifdef DEBUG
        bool nutRslt =
#endif
                spEphem->GetNutation( julianDay, &nutation );
        Assert( nutRslt );
    }
    Angle meanObliquity = MeanObliquity( julianDay );
    Angle trueObliquity = TrueObliquity( meanObliquity, nutation );
    Matrix3D nutAndPrecMatrix = nutation.Matrix( meanObliquity )
            * precessionMatrix;
    JPLBarycentricEphemeris sunEphem( spEphem, JPLEphemeris::Sun );
    Point3D sunPos = GetSunApparentPlace( julianDay, sunEphem,
                                          earthBarycentric,
                                          earthBarycentricVelocity,
                                          nutAndPrecMatrix );
    Equatorial sunEquatorial( sunPos );
    Angle eotAngle = meanSolarLong  -  Angle( 0.0057183, Angle::Degree )
            -  sunEquatorial.RightAscension()
            +  nutation.NutLongitude() * Cos( trueObliquity );
    return TimeIncrement( eotAngle.Cycles() );
}
Example #5
0
/* given a Now *, find the local apparent sidereal time, in hours.
 */
void
now_lst (Now *np, double *lstp)
{
	static double last_mjd = -23243, last_lng = 121212, last_lst;
	double eps, lst, deps, dpsi;

	if (last_mjd == mjd && last_lng == lng) {
	    *lstp = last_lst;
	    return;
	}

	utc_gst (mjd_day(mjd), mjd_hr(mjd), &lst);
	lst += radhr(lng);

	obliquity(mjd, &eps);
	nutation(mjd, &deps, &dpsi);
	lst += radhr(dpsi*cos(eps+deps));

	range (&lst, 24.0);

	last_mjd = mjd;
	last_lng = lng;
	*lstp = last_lst = lst;
}
Example #6
0
void moonPosition(double jDE, double *rA, double *dec,
		     double *eLong, double *eLat, double *distance, float *Fr)
{
  int i;
  double T, Lprime, D, M, Mprime, F, A1, A2, A3, Sigmal, Sigmar, Sigmab,
    E, alpha, dD, dM, dMprime, dF, lambda, beta, delta, deltaPhi, deltaEps,
    eps, pi;

  T = (jDE - 2451545.0)/36525.0;
  nutation(T, &deltaPhi, &deltaEps, &eps);
  Lprime = 218.3164477
    +   481267.88123421*T
    -        0.00157860*T*T
    +                   T*T*T/538841.0
    -                   T*T*T*T/65194000.0;
  doubleNormalize0to360(&Lprime);
  D =    297.8501921
    + 445267.1114034*T
    -      0.0018819*T*T
    +                T*T*T/545868.0
    -                T*T*T*T/113065000.0;
  doubleNormalize0to360(&D);
  M =   357.5291092
    + 35999.0502909*T
    -     0.0001536*T*T
    +               T*T*T/24490000.0;

  doubleNormalize0to360(&M);
  Mprime = 134.9633964
    +   477198.8675055*T
    +        0.0087414*T*T
    +                  T*T*T/69699.0
    -                  T*T*T*T/14712000.0;
  doubleNormalize0to360(&Mprime);
  F =     93.2720950
    + 483202.0175233*T
    -      0.0036539*T*T
    -                T*T*T/3526000.0
    -                T*T*T*T/863310000.0;
  doubleNormalize0to360(&F);
  A1 = 119.75 +    131.849*T;
  doubleNormalize0to360(&A1);
  A2 =  53.09 + 479264.290*T;
  doubleNormalize0to360(&A2);
  A3 = 313.45 + 481266.484*T;
  doubleNormalize0to360(&A3);
  Sigmal = Sigmar = Sigmab = 0.0;
  E = 1.0 - 0.002516*T - 0.0000074*T*T;
  dD = D*DEGREES_TO_RADIANS;
  dM = M*DEGREES_TO_RADIANS;
  dMprime = Mprime*DEGREES_TO_RADIANS;
  dF = F*DEGREES_TO_RADIANS;
  for (i = 0; i < 60; i++) {
    if ((argMultlr[i][1] == 1) || (argMultlr[i][1] == -1))
      alpha = E;
    else if ((argMultlr[i][1] == 2) || (argMultlr[i][1] == -2))
      alpha = E*E;
    else
      alpha = 1;
    Sigmal += alpha*SigmalCoef[i]*sin(argMultlr[i][0]*dD
				    + argMultlr[i][1]*dM
				    + argMultlr[i][2]*dMprime
				    + argMultlr[i][3]*dF);
    Sigmar += alpha*SigmarCoef[i]*cos(argMultlr[i][0]*dD
				    + argMultlr[i][1]*dM
				    + argMultlr[i][2]*dMprime
				    + argMultlr[i][3]*dF);
    if ((argMultb[i][1] == 1) || (argMultb[i][1] == -1))
      alpha = E;
    else if ((argMultb[i][1] == 2) || (argMultb[i][1] == -2))
      alpha = E*E;
    else
      alpha = 1;
    Sigmab += alpha*SigmabCoef[i]*sin(argMultb[i][0]*dD
				    + argMultb[i][1]*dM
				    + argMultb[i][2]*dMprime
				    + argMultb[i][3]*dF);
  }
  Sigmal += 3958.0*sin(A1*DEGREES_TO_RADIANS)
          + 1962.0*sin((Lprime-F)*DEGREES_TO_RADIANS)
          +  318.0*sin(A2*DEGREES_TO_RADIANS);
  Sigmab += -2235.0*sin(Lprime*DEGREES_TO_RADIANS)
    + 382.0*sin(A3*DEGREES_TO_RADIANS)
    + 175.0*sin((A1-F)*DEGREES_TO_RADIANS)
    + 175.0*sin((A1+F)*DEGREES_TO_RADIANS)
    + 127.0*sin((Lprime-Mprime)*DEGREES_TO_RADIANS)
    - 115.0*sin((Lprime+Mprime)*DEGREES_TO_RADIANS);
  lambda = Lprime + Sigmal*1.0e-6 + deltaPhi/3600.0;
  doubleNormalize0to360(&lambda);
  beta   = Sigmab*1.0e-6;
  doubleNormalize0to360(&beta);
  delta = 385000.56 + Sigmar*1.0e-3;
  pi = asin(6378.14/delta)/DEGREES_TO_RADIANS;
  eps    *= DEGREES_TO_RADIANS;
  lambda *= DEGREES_TO_RADIANS;
  beta   *= DEGREES_TO_RADIANS;
  *eLong = lambda;
  *eLat = beta;
  *rA  = atan2(sin(lambda)*cos(eps) - tan(beta)*sin(eps), cos(lambda));
  doubleNormalize0to2pi(rA);
  *dec = asin(sin(beta)*cos(eps) + cos(beta)*sin(eps)*sin(lambda));
  *distance = delta;
}
Example #7
0
int
lunar_longitude( mpfr_t *result, mpfr_t *moment ) {

    mpfr_t C, mean_moon, elongation, solar_anomaly, lunar_anomaly, moon_node, E, correction, venus, jupiter, flat_earth, N, fullangle;

    mpfr_init(C);
    julian_centuries( &C, moment );

    {
        mpfr_t a, b, c, d, e;

        mpfr_init(mean_moon);
        mpfr_init_set_d(a, 218.316591, GMP_RNDN);
        mpfr_init_set_d(b, 481267.88134236, GMP_RNDN);
        mpfr_init_set_d(c, -0.0013268, GMP_RNDN);
        mpfr_init_set_ui(d, 1, GMP_RNDN);
        mpfr_div_ui(d, d, 538841, GMP_RNDN);
        mpfr_init_set_si(e, -1, GMP_RNDN);
        mpfr_div_ui(e, e, 65194000, GMP_RNDN);

        polynomial( &mean_moon, &C, 5, &a, &b, &c, &d, &e );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(elongation);

        mpfr_init_set_d(a, 297.8502042, GMP_RNDN);
        mpfr_init_set_d(b, 445267.1115168, GMP_RNDN);
        mpfr_init_set_d(c, -0.00163, GMP_RNDN);
        mpfr_init_set_ui(d, 1, GMP_RNDN);
        mpfr_div_ui(d, d, 545868, GMP_RNDN);
        mpfr_init_set_si(e, -1, GMP_RNDN);
        mpfr_div_ui(e, e, 113065000, GMP_RNDN);
        polynomial( &elongation, &C, 5, &a, &b, &c, &d, &e );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c, d;
        mpfr_init(solar_anomaly);
        mpfr_init_set_d(a, 357.5291092, GMP_RNDN);
        mpfr_init_set_d(b, 35999.0502909, GMP_RNDN);
        mpfr_init_set_d(c,  -0.0001536, GMP_RNDN);
        mpfr_init_set_ui(d, 1, GMP_RNDN);
        mpfr_div_ui(d, d, 24490000, GMP_RNDN);
        polynomial( &solar_anomaly, &C, 4, &a, &b, &c, &d );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
    }

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(lunar_anomaly);

        mpfr_init_set_d(a, 134.9634114, GMP_RNDN);
        mpfr_init_set_d(b, 477198.8676313, GMP_RNDN);
        mpfr_init_set_d(c, 0.0008997, GMP_RNDN);
        mpfr_init_set_ui(d, 1, GMP_RNDN);
        mpfr_div_ui(d, d, 69699, GMP_RNDN);
        mpfr_init_set_si(e, -1, GMP_RNDN);
        mpfr_div_ui(e, e,  14712000, GMP_RNDN);
        polynomial( &lunar_anomaly, &C, 5, &a, &b, &c, &d, &e);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(moon_node);
        mpfr_init_set_d(a, 93.2720993, GMP_RNDN);
        mpfr_init_set_d(b, 483202.0175273, GMP_RNDN);
        mpfr_init_set_d(c, -0.0034029, GMP_RNDN);
        mpfr_init_set_si(d, -1, GMP_RNDN);
        mpfr_div_ui(d, d, 3526000, GMP_RNDN);
        mpfr_init_set_ui(e, 1, GMP_RNDN);
        mpfr_div_ui(e, e, 863310000, GMP_RNDN);
        polynomial(&moon_node, &C, 5, &a, &b, &c, &d, &e);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c;
        mpfr_init(E);
        mpfr_init_set_ui(a, 1, GMP_RNDN);
        mpfr_init_set_d(b, -0.002516, GMP_RNDN);
        mpfr_init_set_d(c, -0.0000074, GMP_RNDN);
        polynomial( &E, &C, 3, &a, &b, &c );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
    }

    {
        int i;
        mpfr_t fugly;
        mpfr_init_set_ui(fugly, 0, GMP_RNDN);

        for(i = 0; i < LUNAR_LONGITUDE_ARGS_SIZE; i++) {
            mpfr_t a, b, v, w, x, y, z;
            mpfr_init_set_d( v, LUNAR_LONGITUDE_ARGS[i][0], GMP_RNDN );
            mpfr_init_set_d( w, LUNAR_LONGITUDE_ARGS[i][1], GMP_RNDN );
            mpfr_init_set_d( x, LUNAR_LONGITUDE_ARGS[i][2], GMP_RNDN );
            mpfr_init_set_d( y, LUNAR_LONGITUDE_ARGS[i][3], GMP_RNDN );
            mpfr_init_set_d( z, LUNAR_LONGITUDE_ARGS[i][4], GMP_RNDN );

            mpfr_init(b);
            mpfr_pow(b, E, x, GMP_RNDN);

            mpfr_mul(w, w, elongation, GMP_RNDN);
            mpfr_mul(x, x, solar_anomaly, GMP_RNDN);
            mpfr_mul(y, y, lunar_anomaly, GMP_RNDN);
            mpfr_mul(z, z, moon_node, GMP_RNDN);

            mpfr_init_set(a, w, GMP_RNDN);
            mpfr_add(a, a, x, GMP_RNDN);
            mpfr_add(a, a, y, GMP_RNDN);
            mpfr_add(a, a, z, GMP_RNDN);
            dt_astro_sin(&a, &a);

            mpfr_mul(a, a, v, GMP_RNDN);
            mpfr_mul(a, a, b, GMP_RNDN);
            mpfr_add(fugly, fugly, a, GMP_RNDN);

            mpfr_clear(a);
            mpfr_clear(b);
            mpfr_clear(v);
            mpfr_clear(w);
            mpfr_clear(x);
            mpfr_clear(y);
            mpfr_clear(z);
        }

        mpfr_init_set_d( correction, 0.000001, GMP_RNDN );
        mpfr_mul( correction, correction, fugly, GMP_RNDN);
        mpfr_clear(fugly);
    }

    {
        mpfr_t a, b;
        mpfr_init(venus);
        mpfr_init_set_d(a, 119.75, GMP_RNDN);
        mpfr_init_set(b, C, GMP_RNDN);
        mpfr_mul_d(b, b, 131.849, GMP_RNDN);

        mpfr_add(a, a, b, GMP_RNDN);
        dt_astro_sin(&a, &a);
        mpfr_mul_d(venus, a, 0.003957, GMP_RNDN );
        mpfr_clear(a);
        mpfr_clear(b);
    }

    {
        mpfr_t a, b;
        mpfr_init(jupiter);
        mpfr_init_set_d(a, 53.09, GMP_RNDN);
        mpfr_init_set(b, C, GMP_RNDN);
        mpfr_mul_d(b, b, 479264.29, GMP_RNDN);
    
        mpfr_add(a, a, b, GMP_RNDN);
        dt_astro_sin(&a, &a);
        mpfr_mul_d(jupiter, a, 0.000318, GMP_RNDN );
        mpfr_clear(a);
        mpfr_clear(b);
    }

    {
        mpfr_t a;
        mpfr_init(flat_earth);
        mpfr_init_set(a, mean_moon, GMP_RNDN);
        mpfr_sub(a, a, moon_node, GMP_RNDN);
        dt_astro_sin(&a, &a);
        mpfr_mul_d(flat_earth, a, 0.001962, GMP_RNDN);
        mpfr_clear(a);
    }

    mpfr_set(*result, mean_moon, GMP_RNDN);
    mpfr_add(*result, *result, correction, GMP_RNDN);
    mpfr_add(*result, *result, venus, GMP_RNDN);
    mpfr_add(*result, *result, jupiter, GMP_RNDN);
    mpfr_add(*result, *result, flat_earth, GMP_RNDN);

#ifdef ANNOYING_DEBUG
#if (ANNOYING_DEBUG)
mpfr_fprintf(stderr,
    "mean_moon = %.10RNf\ncorrection = %.10RNf\nvenus = %.10RNf\njupiter = %.10RNf\nflat_earth = %.10RNf\n",
    mean_moon,
    correction,
    venus,
    jupiter,
    flat_earth);
#endif
#endif

    mpfr_init(N);
    nutation(&N, moment);
    mpfr_add(*result, *result, N, GMP_RNDN);

    mpfr_init_set_ui(fullangle, 360, GMP_RNDN);

#ifdef ANNOYING_DEBUG
#if (ANNOYING_DEBUG)
mpfr_fprintf(stderr, "lunar = mod(%.10RNf) = ", *result );
#endif
#endif
    dt_astro_mod(result, result, &fullangle);
#ifdef ANNOYING_DEBUG
#if (ANNOYING_DEBUG)
mpfr_fprintf(stderr, "%.10RNf\n", *result );
#endif
#endif

    mpfr_clear(C);
    mpfr_clear(mean_moon);
    mpfr_clear(elongation);
    mpfr_clear(solar_anomaly);
    mpfr_clear(lunar_anomaly);
    mpfr_clear(moon_node);
    mpfr_clear(E);
    mpfr_clear(correction);
    mpfr_clear(venus);
    mpfr_clear(jupiter);
    mpfr_clear(flat_earth);
    mpfr_clear(N);
    mpfr_clear(fullangle);
    return 1;
}
Example #8
0
/* given the modified JD, mj, correct, IN PLACE, the right ascension *ra
 * and declination *dec (both in radians) for nutation.
 */
void
nut_eq (double mj, double *ra, double *dec)
{
	static double lastmj = -10000;
	static double a[3][3];		/* rotation matrix */
	double xold, yold, zold, x, y, z;

	if (mj != lastmj) {
	    double epsilon, dpsi, deps;
	    double se, ce, sp, cp, sede, cede;

	    obliquity(mj, &epsilon);
	    nutation(mj, &deps, &dpsi);

	    /* the rotation matrix a applies the nutation correction to
	     * a vector of equatoreal coordinates Xeq to Xeq' by 3 subsequent
	     * rotations:  R1 - from equatoreal to ecliptic system by
	     * rotation of angle epsilon about x, R2 - rotate ecliptic
	     * system by -dpsi about its z, R3 - from ecliptic to equatoreal
	     * by rotation of angle -(epsilon + deps)
	     *
	     *	Xeq' = A * Xeq = R3 * R2 * R1 * Xeq
	     * 
	     *		[ 1       0          0    ]
	     * R1 =	[ 0   cos(eps)   sin(eps) ]
	     *		[ 0  - sin(eps)  cos(eps) ]
	     * 
	     *		[ cos(dpsi)  - sin(dpsi)  0 ]
	     * R2 =	[ sin(dpsi)   cos(dpsi)   0 ]
	     *		[      0           0      1 ]
	     * 
	     *		[ 1         0                 0         ]
	     * R3 =	[ 0  cos(eps + deps)  - sin(eps + deps) ]
	     *		[ 0  sin(eps + deps)   cos(eps + deps)  ]
	     * 
	     * for efficiency, here is a explicitely:
	     */
	    
	    se = sin(epsilon);
	    ce = cos(epsilon);
	    sp = sin(dpsi);
	    cp = cos(dpsi);
	    sede = sin(epsilon + deps);
	    cede = cos(epsilon + deps);

	    a[0][0] = cp;
	    a[0][1] = -sp*ce;
	    a[0][2] = -sp*se;

	    a[1][0] = cede*sp;
	    a[1][1] = cede*cp*ce+sede*se;
	    a[1][2] = cede*cp*se-sede*ce;

	    a[2][0] = sede*sp;
	    a[2][1] = sede*cp*ce-cede*se;
	    a[2][2] = sede*cp*se+cede*ce;

	    lastmj = mj;
	}

	sphcart(*ra, *dec, 1.0, &xold, &yold, &zold);
	x = a[0][0] * xold + a[0][1] * yold + a[0][2] * zold;
	y = a[1][0] * xold + a[1][1] * yold + a[1][2] * zold;
	z = a[2][0] * xold + a[2][1] * yold + a[2][2] * zold;
	cartsph(x, y, z, ra, dec, &zold);	/* radius should be 1.0 */
	if (*ra < 0.) *ra += 2.*PI;		/* make positive for display */
}