double nutation_in_obliquity(date d) { double t; // time measured in Julian centuries between given date and the beggingig of the epoch J2000 double da[TOTAL_DELAUNAY_ARGUMENTS]; // array holding Delaunay arguments double lan; // longitude of lunar ascending node (☊) referred to the mean equinox of date int i; // loop index variable double a; // argument of each term of the serie double n; // result nutation in obliquity value // computing time since the beginning of the epoch J2000 to the given measured in Julian centuries t = (julian_date(d) - J2000) / DAYS_IN_JULIAN_CENTURY; // computing Delaunay arguments as given by semi-analytic lunar theory ELP compute_delaunay_arguments(t, FULL_SERIES_TOTAL_TERMS, da); // computing longitude of the lunar ascending node (☊) // Source: P.K. Seidelman. 1980 IAU Theory of Nutation: The Final Report of the IAU Working Group on Nutation, // Celestial Mechanics, vol. 27, May 1982, p. 20. lan = 450160.28 - 6962890.539 * t + 7.455 * t * t + 0.008 * t * t * t; // computing nutation serie (see top comment for more information) for (i = 0, n = 0.0; i < TOTAL_NUTATION_TERMS; i++) { // computing argument of the term of the serie a = nutation_multipliers[i][0] * da[L]; a += nutation_multipliers[i][1] * da[LP]; a += nutation_multipliers[i][2] * da[F]; a += nutation_multipliers[i][3] * da[D]; a += nutation_multipliers[i][4] * lan; // converting argument from arcseconds to radians (π = 648000") a *= M_PI / 648000.0; // accumulation nutation values n += (nutation_coefficients[i][3] + nutation_coefficients[i][4] * t) * cos(a); } // coefficients are given in 10⁻⁵", converting to degrees (1° = 36000000×10⁻⁵") n /= 36000000.0; // converting nutation values from arcseconds to radians (π = 180°) n *= M_PI / 180.0; return n; }
spherical_point geocentric_moon_position(double t) { double delaunay_arguments[TOTAL_DELAUNAY_ARGUMENTS]; // Delaunay arguments double elp2000_arguments[TOTAL_ELP2000_ARGUMENTS]; // ELP2000 arguments double planetary_arguments[TOTAL_PLANETARY_ARGUMENTS]; // planetary arguments double zeta; // argument of the precession precession (ζ) spherical_point sp; // result position of the Moon // each coordinate (longitude, latitude and radial distance) is computed by adding together results of each serie: // Main Porblem and all perturbations; then, Moon's mean mean longitude (W₁) must be added to the value of the // longitude to find the actual position // computing Delaunay arguments (non reduced) compute_delaunay_arguments(t, FULL_SERIES_TOTAL_TERMS, delaunay_arguments); // computing Main Problem sp.longitude = compute_serie_a_sin(delaunay_arguments, main_problem_longitude_multipliers, main_problem_longitude_coefficients, TOTAL_MAIN_PROBLEM_LONGITUDE_TERMS); sp.latitude = compute_serie_a_sin(delaunay_arguments, main_problem_latitude_multipliers, main_problem_latitude_coefficients, TOTAL_MAIN_PROBLEM_LATITUDE_TERMS); sp.distance = compute_serie_a_cos(delaunay_arguments, main_problem_distance_multipliers, main_problem_distance_coefficients, TOTAL_MAIN_PROBLEM_DISTANCE_TERMS); // recomputing reduced Delaunay arguments compute_delaunay_arguments(t, LINEAR_SERIES_TOTAL_TERMS, delaunay_arguments); // computing ELP2000 arguments compute_elp2000_arguments(t, LINEAR_SERIES_TOTAL_TERMS, elp2000_arguments); // computing precession argument zeta = compute_precession_argument(t); // computing Earth figure perturbations (constant) sp.longitude += compute_serie_b(zeta, delaunay_arguments, earth_figure_longitude_0_multipliers, earth_figure_longitude_0_coefficients, TOTAL_EARTH_FIGURE_LONGITUDE_0_TERMS); sp.latitude += compute_serie_b(zeta, delaunay_arguments, earth_figure_latitude_0_multipliers, earth_figure_latitude_0_coefficients, TOTAL_EARTH_FIGURE_LATITUDE_0_TERMS); sp.distance += compute_serie_b(zeta, delaunay_arguments, earth_figure_distance_0_multipliers, earth_figure_distance_0_coefficients, TOTAL_EARTH_FIGURE_DISTANCE_0_TERMS); // computing Earth figure perturbations (linear) sp.longitude += compute_serie_b(zeta, delaunay_arguments, earth_figure_longitude_0_multipliers, earth_figure_longitude_0_coefficients, TOTAL_EARTH_FIGURE_LONGITUDE_0_TERMS) * t; sp.latitude += compute_serie_b(zeta, delaunay_arguments, earth_figure_latitude_0_multipliers, earth_figure_latitude_0_coefficients, TOTAL_EARTH_FIGURE_LATITUDE_0_TERMS) * t; sp.distance += compute_serie_b(zeta, delaunay_arguments, earth_figure_distance_0_multipliers, earth_figure_distance_0_coefficients,TOTAL_EARTH_FIGURE_DISTANCE_0_TERMS) * t; // computing planetary arguments compute_planetary_arguments(t, planetary_arguments); // computing planetary 1 perturbations (constant) sp.longitude += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_longitude_0_multipliers, planetary1_longitude_0_coefficients, TOTAL_PLANETARY1_LONGITUDE_0_TERMS); sp.latitude += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_latitude_0_multipliers, planetary1_latitude_0_coefficients, TOTAL_PLANETARY1_LATITUDE_0_TERMS); sp.distance += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_distance_0_multipliers, planetary1_distance_0_coefficients, TOTAL_PLANETARY1_DISTANCE_0_TERMS); // computing planetary 1 perturbations (linear) sp.longitude += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_longitude_1_multipliers, planetary1_longitude_1_coefficients, TOTAL_PLANETARY1_LONGITUDE_1_TERMS) * t; sp.latitude += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_latitude_1_multipliers, planetary1_latitude_1_coefficients, TOTAL_PLANETARY1_LATITUDE_1_TERMS) * t; sp.distance += compute_serie_c(planetary_arguments, delaunay_arguments, planetary1_distance_1_multipliers, planetary1_distance_1_coefficients, TOTAL_PLANETARY1_DISTANCE_1_TERMS) * t; // computing planetary 2 perturbations (constant) sp.longitude += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_longitude_0_multipliers, planetary2_longitude_0_coefficients, TOTAL_PLANETARY2_LONGITUDE_0_TERMS); sp.latitude += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_latitude_0_multipliers, planetary2_latitude_0_coefficients, TOTAL_PLANETARY2_LATITUDE_0_TERMS); sp.distance += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_distance_0_multipliers, planetary2_distance_0_coefficients, TOTAL_PLANETARY2_DISTANCE_0_TERMS); // computing planetary 2 perturbations (linear) sp.longitude += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_longitude_1_multipliers, planetary2_longitude_1_coefficients, TOTAL_PLANETARY2_LONGITUDE_1_TERMS) * t; sp.latitude += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_latitude_1_multipliers, planetary2_latitude_1_coefficients, TOTAL_PLANETARY2_LATITUDE_1_TERMS) * t; sp.distance += compute_serie_d(planetary_arguments, delaunay_arguments, planetary2_distance_1_multipliers, planetary2_distance_1_coefficients, TOTAL_PLANETARY2_DISTANCE_1_TERMS) * t; // computing tidal effects (constant) sp.longitude += compute_serie_b(zeta, delaunay_arguments, tidal_longitude_0_multipliers, tidal_longitude_0_coefficients, TOTAL_TIDAL_LONGITUDE_0_TERMS); sp.latitude += compute_serie_b(zeta, delaunay_arguments, tidal_latitude_0_multipliers, tidal_latitude_0_coefficients, TOTAL_TIDAL_LATITUDE_0_TERMS); sp.distance += compute_serie_b(zeta, delaunay_arguments, tidal_distance_0_multipliers, tidal_distance_0_coefficients, TOTAL_TIDAL_DISTANCE_0_TERMS); // computing tidal effects (linear) sp.longitude += compute_serie_b(zeta, delaunay_arguments, tidal_longitude_1_multipliers, tidal_longitude_1_coefficients, TOTAL_TIDAL_LONGITUDE_1_TERMS) * t; sp.latitude += compute_serie_b(zeta, delaunay_arguments, tidal_latitude_1_multipliers, tidal_latitude_1_coefficients, TOTAL_TIDAL_LATITUDE_1_TERMS) * t; sp.distance += compute_serie_b(zeta, delaunay_arguments, tidal_distance_1_multipliers, tidal_distance_1_coefficients, TOTAL_TIDAL_DISTANCE_1_TERMS) * t; // computing Moon figure perturbations sp.longitude += compute_serie_b(zeta, delaunay_arguments, moon_figure_longitude_multipliers, moon_figure_longitude_coefficients, TOTAL_MOON_FIGURE_LONGITUDE_TERMS); sp.latitude += compute_serie_b(zeta, delaunay_arguments, moon_figure_latitude_multipliers, moon_figure_latitude_coefficients, TOTAL_MOON_FIGURE_LATITUDE_TERMS); sp.distance += compute_serie_b(zeta, delaunay_arguments, moon_figure_distance_multipliers, moon_figure_distance_coefficients, TOTAL_MOON_FIGURE_DISTANCE_TERMS); // computing relativistic perturbations sp.longitude += compute_serie_b(zeta, delaunay_arguments, relativistic_longitude_multipliers, relativistic_longitude_coefficients, TOTAL_RELATIVISTIC_LONGITUDE_TERMS); sp.latitude += compute_serie_b(zeta, delaunay_arguments, relativistic_latitude_multipliers, relativistic_latitude_coefficients, TOTAL_RELATIVISTIC_LATITUDE_TERMS); sp.distance += compute_serie_b(zeta, delaunay_arguments, relativistic_distance_multipliers, relativistic_distance_coefficients, TOTAL_RELATIVISTIC_DISTANCE_TERMS); // computing planetary perturbations (solar eccentricity) (quadratic) sp.longitude += compute_serie_b(zeta, delaunay_arguments, planetary_longitude_2_multipliers, planetary_longitude_2_coefficients, TOTAL_PLANETARY_LONGITUDE_2_TERMS) * t * t; sp.latitude += compute_serie_b(zeta, delaunay_arguments, planetary_latitude_2_multipliers, planetary_latitude_2_coefficients, TOTAL_PLANETARY_LATITUDE_2_TERMS) * t * t; sp.distance += compute_serie_b(zeta, delaunay_arguments, planetary_distance_2_multipliers, planetary_distance_2_coefficients, TOTAL_PLANETARY_DISTANCE_2_TERMS) * t * t; // recomputing full ELP2000 arguments compute_elp2000_arguments(t, FULL_SERIES_TOTAL_TERMS, elp2000_arguments); // adding mean mean longitude of the Moon (W₁) sp.longitude += elp2000_arguments[W1]; return sp; }