@ -1,78 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "orbit.hpp" | |||
#include "math/angles.hpp" | |||
#include <cmath> | |||
namespace astro | |||
{ | |||
double solve_kepler(double ec, double ma, double tolerance, std::size_t iterations) | |||
{ | |||
// Approximate eccentric anomaly, E | |||
double e0 = ma + ec * std::sin(ma) * (1.0 + ec * std::cos(ma)); | |||
// Iteratively converge E0 and E1 | |||
for (std::size_t i = 0; i < iterations; ++i) | |||
{ | |||
double e1 = e0 - (e0 - ec * std::sin(e0) - ma) / (1.0 - ec * std::cos(e0)); | |||
double error = std::abs(e1 - e0); | |||
e0 = e1; | |||
if (error < tolerance) | |||
break; | |||
} | |||
return e0; | |||
} | |||
double3 orbital_elements_to_ecliptic(const orbital_elements& elements, double ke_tolerance, std::size_t ke_iterations) | |||
{ | |||
// Calculate semi-minor axis, b | |||
double b = elements.a * std::sqrt(1.0 - elements.ec * elements.ec); | |||
// Solve Kepler's equation for eccentric anomaly, E | |||
double ea = solve_kepler(elements.ec, elements.ma, ke_tolerance, ke_iterations); | |||
// Calculate radial distance, r; and true anomaly, v | |||
double xv = elements.a * (std::cos(ea) - elements.ec); | |||
double yv = b * std::sin(ea); | |||
double r = std::sqrt(xv * xv + yv * yv); | |||
double v = std::atan2(yv, xv); | |||
// Calculate true longitude, l | |||
double l = elements.w + v; | |||
// Transform vector (r, 0, 0) from local coordinates to ecliptic coordinates | |||
// = Rz(-omega) * Rx(-i) * Rz(-l) * r | |||
double cos_om = std::cos(elements.om); | |||
double sin_om = std::sin(elements.om); | |||
double cos_i = std::cos(elements.i); | |||
double cos_l = std::cos(l); | |||
double sin_l = std::sin(l); | |||
return double3 | |||
{ | |||
r * (cos_om * cos_l - sin_om * sin_l * cos_i), | |||
r * (sin_om * cos_l + cos_om * sin_l * cos_i), | |||
r * sin_l * std::sin(elements.i) | |||
}; | |||
} | |||
} // namespace astro |
@ -1,75 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_ASTRO_ORBIT_HPP | |||
#define ANTKEEPER_ASTRO_ORBIT_HPP | |||
#include "utility/fundamental-types.hpp" | |||
namespace astro | |||
{ | |||
/** | |||
* Contains six orbital elements which describe a Keplerian orbit. | |||
*/ | |||
struct orbital_elements | |||
{ | |||
double ec; ///< Eccentricity, e | |||
double a; ///< Semi-major axis, a | |||
double i; ///< Inclination, i (radians) | |||
double om; ///< Longitude of the ascending node, OMEGA (radians) | |||
double w; ///< Argument of periapsis, w (radians) | |||
double ma; ///< Mean anomaly, M (radians) | |||
}; | |||
/** | |||
* Orbital state vectors. | |||
*/ | |||
struct orbital_state | |||
{ | |||
double3 r; ///< Cartesian position, r. | |||
double3 v; ///< Cartesian velocity, v. | |||
}; | |||
/** | |||
* Iteratively solves Kepler's equation for eccentric anomaly, E. | |||
* | |||
* @param ec Eccentricity, e. | |||
* @param ma Mean anomaly, M (radians). | |||
* @param tolerance Tolerance of solution. | |||
* @param iterations Maximum number of iterations. | |||
* @return Eccentric anomaly. | |||
*/ | |||
double solve_kepler(double ec, double ma, double tolerance, std::size_t iterations); | |||
/** | |||
* Calculates the ecliptic rectangular orbital position from Keplerian orbital elements. | |||
* | |||
* @note Only works for elliptical orbits. | |||
* | |||
* @param elements Orbital elements. | |||
* @param ke_tolerance Kepler's equation tolerance. | |||
* @param ke_iterations Kepler's equation iterations. | |||
* @return Orbital state. | |||
*/ | |||
double3 orbital_elements_to_ecliptic(const orbital_elements& elements, double ke_tolerance, std::size_t ke_iterations); | |||
} // namespace astro | |||
#endif // ANTKEEPER_ASTRO_ORBIT_HPP |
@ -1,214 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_COORDINATES_ECLIPTIC_HPP | |||
#define ANTKEEPER_COORDINATES_ECLIPTIC_HPP | |||
#include "coordinates/rectangular.hpp" | |||
#include "coordinates/spherical.hpp" | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace coordinates { | |||
namespace rectangular { | |||
/// Rectangular coordinate system with the plane of the Earth's orbit as the fundamental plane. This is a right-handed coordinate system with the x-axis pointing to the vernal equinox, the y-axis pointing east, and the z-axis is the north orbital pole. | |||
namespace ecliptic { | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from ecliptic space into equatorial space. | |||
* | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::equatorial | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_equatorial(T ecl); | |||
/** | |||
* Rotates rectangular coordinates from ecliptic space into equatorial space. | |||
* | |||
* @param v Rectangular coordinates in ecliptic space. | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Rectangular coordinates in equatorial space. | |||
* | |||
* @see coordinates::rectangular::equatorial | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T ecl); | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from ecliptic space into local horizontal space. | |||
* | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::horizontal | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_horizontal(T ecl, T lat, T lst); | |||
/** | |||
* Rotates rectangular coordinates from ecliptic space into local horizontal space. | |||
* | |||
* @param v Rectangular coordinates in ecliptic space. | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rectangular coordinates in local horizontal space. | |||
* | |||
* @see coordinates::rectangular::horizontal | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T ecl, T lat, T lst); | |||
} // namespace ecliptic | |||
} // namespace rectangular | |||
namespace spherical { | |||
/// Spherical ecliptic coordinate system. | |||
namespace ecliptic { | |||
/** | |||
* Rotates spherical coordinates from ecliptic space into equatorial space. | |||
* | |||
* @param v Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). | |||
* | |||
* @see coordinates::spherical::equatorial | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T ecl); | |||
/** | |||
* Rotates spherical coordinates from ecliptic space into local horizontal space. | |||
* | |||
* @param v Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). | |||
* | |||
* @see coordinates::spherical::horizontal | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T ecl, T lat, T lst); | |||
} // namespace ecliptic | |||
} // namespace spherical | |||
namespace rectangular { | |||
namespace ecliptic { | |||
template <class T> | |||
math::matrix3<T> to_equatorial(T ecl) | |||
{ | |||
const T c_ecl = std::cos(ecl); | |||
const T s_ecl = std::sin(ecl); | |||
return math::matrix3<T> | |||
{ | |||
T(1.0), T(0.0), T(0.0), | |||
T(0.0), c_ecl, s_ecl, | |||
T(0.0), -s_ecl, c_ecl | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T ecl) | |||
{ | |||
return to_equatorial<T>(ecl) * v; | |||
} | |||
template <class T> | |||
math::matrix3<T> to_horizontal(T ecl, T lat, T lst) | |||
{ | |||
const T c_ecl = std::cos(ecl); | |||
const T s_ecl = std::sin(ecl); | |||
const T c_lat = std::cos(lat); | |||
const T s_lat = std::sin(lat); | |||
const T c_lst = std::cos(lst); | |||
const T s_lst = std::sin(lst); | |||
return math::matrix3<T> | |||
{ | |||
s_lat * c_lst, s_lst, c_lat * c_lst, | |||
s_lat * s_lst * c_ecl - c_lat * s_ecl, -c_lst * c_ecl, c_lat * s_lst * c_ecl + s_lat * s_ecl, | |||
s_lat * s_lst * -s_ecl - c_lat * c_ecl, c_lst * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T ecl, T lat, T lst) | |||
{ | |||
return to_horizontal<T>(ecl, lat, lst) * v; | |||
} | |||
} // namespace ecliptic | |||
} // namespace rectangular | |||
namespace spherical { | |||
namespace ecliptic { | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T ecl) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::ecliptic::to_equatorial<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
ecl | |||
) | |||
); | |||
} | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T ecl, T lat, T lst) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::ecliptic::to_horizontal<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
ecl, | |||
lat, | |||
lst | |||
) | |||
); | |||
} | |||
} // namespace ecliptic | |||
} // namespace spherical | |||
} // namespace coordinates | |||
#endif // ANTKEEPER_COORDINATES_ECLIPTIC_HPP |
@ -1,208 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_COORDINATES_EQUATORIAL_HPP | |||
#define ANTKEEPER_COORDINATES_EQUATORIAL_HPP | |||
#include "coordinates/rectangular.hpp" | |||
#include "coordinates/spherical.hpp" | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace coordinates { | |||
namespace rectangular { | |||
/// Rectangular coordinate system with the Earth's equator as the fundamental plane. This is a right-handed coordinate system with the x-axis pointing to the vernal equinox, the y-axis pointing east, and the z-axis is the north celestial pole. | |||
namespace equatorial { | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from equatorial space into ecliptic space. | |||
* | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::ecliptic | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_ecliptic(T ecl); | |||
/** | |||
* Rotates rectangular coordinates from equatorial space into ecliptic space. | |||
* | |||
* @param v Rectangular coordinates in equatorial space. | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Rectangular coordinates in ecliptic space. | |||
* | |||
* @see coordinates::rectangular::ecliptic | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl); | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from equatorial space into local horizontal space. | |||
* | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::horizontal | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_horizontal(T lat, T lst); | |||
/** | |||
* Rotates rectangular coordinates from equatorial space into local horizontal space. | |||
* | |||
* @param v Rectangular coordinates in equatorial space. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rectangular coordinates in local horizontal space. | |||
* | |||
* @see coordinates::rectangular::horizontal | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T lat, T lst); | |||
} // namespace equatorial | |||
} // namespace rectangular | |||
namespace spherical { | |||
/// Spherical equatorial coordinate system. | |||
namespace equatorial { | |||
/** | |||
* Rotates spherical coordinates from equatorial space into ecliptic space. | |||
* | |||
* @param v Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @return Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). | |||
* | |||
* @see coordinates::spherical::ecliptic | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl); | |||
/** | |||
* Rotates spherical coordinates from equatorial space into local horizontal space. | |||
* | |||
* @param v Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). | |||
* | |||
* @see coordinates::spherical::horizontal | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T lat, T lst); | |||
} // namespace equatorial | |||
} // namespace spherical | |||
namespace rectangular { | |||
namespace equatorial { | |||
template <class T> | |||
math::matrix3<T> to_ecliptic(T ecl) | |||
{ | |||
const T c_ecl = std::cos(ecl); | |||
const T s_ecl = std::sin(ecl); | |||
return math::matrix3<T> | |||
{ | |||
T(1.0), T(0.0), T(0.0), | |||
T(0.0), c_ecl, -s_ecl, | |||
T(0.0), s_ecl, c_ecl | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl) | |||
{ | |||
return to_ecliptic(ecl) * v; | |||
} | |||
template <class T> | |||
math::matrix3<T> to_horizontal(T lat, T lst) | |||
{ | |||
const T c_lat = std::cos(lat); | |||
const T s_lat = std::sin(lat); | |||
const T c_lst = std::cos(lst); | |||
const T s_lst = std::sin(lst); | |||
return math::matrix3<T> | |||
{ | |||
s_lat * c_lst, s_lst, c_lat * c_lst, | |||
s_lat * s_lst, -c_lst, c_lat * s_lst, | |||
-c_lat, T(0.0), s_lat | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T lat, T lst) | |||
{ | |||
return to_horizontal(lat, lst) * v; | |||
} | |||
} // namespace equatorial | |||
} // namespace rectangular | |||
namespace spherical { | |||
namespace equatorial { | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::equatorial::to_ecliptic<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
ecl | |||
) | |||
); | |||
} | |||
template <class T> | |||
math::vector3<T> to_horizontal(const math::vector3<T>& v, T lat, T lst) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::equatorial::to_horizontal<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
lat, | |||
lst | |||
) | |||
); | |||
} | |||
} // namepace equatorial | |||
} // namespace spherical | |||
} // namespace coordinates | |||
#endif // ANTKEEPER_COORDINATES_EQUATORIAL_HPP |
@ -1,220 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_COORDINATES_HORIZONTAL_HPP | |||
#define ANTKEEPER_COORDINATES_HORIZONTAL_HPP | |||
#include "coordinates/rectangular.hpp" | |||
#include "coordinates/spherical.hpp" | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace coordinates { | |||
namespace rectangular { | |||
/// Rectangular local horizontal coordinate system in which the x-axis points north, the y-axis points east, and the z-axis points to the vertical. | |||
namespace horizontal { | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from local horizontal space into equatorial space. | |||
* | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::equatorial | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_equatorial(T lat, T lst); | |||
/** | |||
* Rotates rectangular coordinates from local horizontal space into equatorial space. | |||
* | |||
* @param v Rectangular coordinates in local horizontal space. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rectangular coordinates in equatorial space. | |||
* | |||
* @see coordinates::rectangular::equatorial | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst); | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates from local horizontal space into ecliptic space. | |||
* | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rotation matrix. | |||
* | |||
* @see coordinates::rectangular::ecliptic | |||
*/ | |||
template <class T> | |||
math::matrix3<T> to_ecliptic(T ecl, T lat, T lst); | |||
/** | |||
* Rotates rectangular coordinates from local horizontal space into ecliptic space. | |||
* | |||
* @param v Rectangular coordinates in local horizontal space. | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Rectangular coordinates in ecliptic space. | |||
* | |||
* @see coordinates::rectangular::ecliptic | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst); | |||
} // namespace horizontal | |||
} // namespace rectangular | |||
namespace spherical { | |||
/// Spherical local horizontal coordinate system. | |||
namespace horizontal { | |||
/** | |||
* Rotates spherical coordinates from local horizontal space into equatorial space. | |||
* | |||
* @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians). | |||
* | |||
* @see coordinates::spherical::equatorial | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst); | |||
/** | |||
* Rotates spherical coordinates from local horizontal space into ecliptic space. | |||
* | |||
* @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians). | |||
* @param ecl Obliquity of the ecliptic, in radians. | |||
* @param lat Observer's latitude, in radians. | |||
* @param lst Local sidereal time, in radians. | |||
* @return Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians). | |||
* | |||
* @see coordinates::spherical::ecliptic | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst); | |||
} // namespace horizontal | |||
} // namespace spherical | |||
namespace rectangular { | |||
namespace horizontal { | |||
template <class T> | |||
math::matrix3<T> to_equatorial(T lat, T lst) | |||
{ | |||
const T c_lat = std::cos(lat); | |||
const T s_lat = std::sin(lat); | |||
const T c_lst = std::cos(lst); | |||
const T s_lst = std::sin(lst); | |||
return math::matrix3<T> | |||
{ | |||
c_lst * s_lat, s_lst * s_lat, -c_lat, | |||
s_lst, c_lst, T(0.0), | |||
c_lst * c_lat, s_lst * c_lat, s_lat | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst) | |||
{ | |||
return to_equatorial<T>(lat, lst) * v; | |||
} | |||
template <class T> | |||
math::matrix3<T> to_ecliptic(T ecl, T lat, T lst) | |||
{ | |||
const T c_ecl = std::cos(ecl); | |||
const T s_ecl = std::sin(ecl); | |||
const T c_lat = std::cos(lat); | |||
const T s_lat = std::sin(lat); | |||
const T c_lst = std::cos(lst); | |||
const T s_lst = std::sin(lst); | |||
return math::matrix3<T> | |||
{ | |||
s_lat * c_lst, s_lat * s_lst * c_ecl - c_lat * s_ecl, s_lat * s_lst * -s_ecl - c_lat * c_ecl, | |||
s_lst, -c_lst * c_ecl, c_lst * s_ecl, | |||
c_lat * c_lst, c_lat * s_lst * c_ecl + s_lat * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst) | |||
{ | |||
return to_ecliptic<T>(ecl, lat, lst) * v; | |||
} | |||
} // namespace horizontal | |||
} // namespace rectangular | |||
namespace spherical { | |||
namespace horizontal { | |||
template <class T> | |||
math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::horizontal::to_equatorial<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
lat, | |||
lst | |||
) | |||
); | |||
} | |||
template <class T> | |||
math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst) | |||
{ | |||
return coordinates::rectangular::to_spherical<T> | |||
( | |||
coordinates::rectangular::horizontal::to_ecliptic<T> | |||
( | |||
coordinates::spherical::to_rectangular<T>(v), | |||
ecl, | |||
lat, | |||
lst | |||
) | |||
); | |||
} | |||
} // namespace horizontal | |||
} // namespace spherical | |||
} // namespace coordinates | |||
#endif // ANTKEEPER_COORDINATES_HORIZONTAL_HPP |
@ -1,175 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_COORDINATES_RECTANGULAR_HPP | |||
#define ANTKEEPER_COORDINATES_RECTANGULAR_HPP | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace coordinates { | |||
/// Rectangular (Cartesian) coordinate systems. | |||
namespace rectangular { | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates about the x-axis by a given angle. | |||
* | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotation matrix. | |||
*/ | |||
template <class T> | |||
math::matrix3<T> rotate_x(T angle); | |||
/** | |||
* Rotates rectangular coordinates about the x-axis. | |||
* | |||
* @param v Rectangular coordinates to rotate. | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotated rectangular coordinates. | |||
*/ | |||
template <class T> | |||
math::vector3<T> rotate_x(const math::vector3<T>& v, T angle); | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates about the y-axis by a given angle. | |||
* | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotation matrix. | |||
*/ | |||
template <class T> | |||
math::matrix3<T> rotate_y(T angle); | |||
/** | |||
* Rotates rectangular coordinates about the y-axis. | |||
* | |||
* @param v Rectangular coordinates to rotate. | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotated rectangular coordinates. | |||
*/ | |||
template <class T> | |||
math::vector3<T> rotate_y(const math::vector3<T>& v, T angle); | |||
/** | |||
* Produces a matrix which rotates rectangular coordinates about the z-axis by a given angle. | |||
* | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotation matrix. | |||
*/ | |||
template <class T> | |||
math::matrix3<T> rotate_z(T angle); | |||
/** | |||
* Rotates rectangular coordinates about the z-axis. | |||
* | |||
* @param v Rectangular coordinates to rotate. | |||
* @param angle Angle of rotation, in radians. | |||
* @return Rotated rectangular coordinates. | |||
*/ | |||
template <class T> | |||
math::vector3<T> rotate_z(const math::vector3<T>& v, T angle); | |||
/** | |||
* Converts rectangular coordinates to spherical coordinates. | |||
* | |||
* @param v Rectangular coordinates. | |||
* @return Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). | |||
* | |||
* @see coordinates::spherical | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_spherical(const math::vector3<T>& v); | |||
template <class T> | |||
math::vector3<T> to_spherical(const math::vector3<T>& v) | |||
{ | |||
const T xx_yy = v.x * v.x + v.y * v.y; | |||
return math::vector3<T> | |||
{ | |||
std::sqrt(xx_yy + v.z * v.z), | |||
std::atan2(v.z, std::sqrt(xx_yy)), | |||
std::atan2(v.y, v.x) | |||
}; | |||
} | |||
template <class T> | |||
math::matrix3<T> rotate_x(T angle) | |||
{ | |||
const T c = std::cos(angle); | |||
const T s = std::sin(angle); | |||
return math::matrix3<T> | |||
{ | |||
T(1), T(0), T(0), | |||
T(0), c, -s, | |||
T(0), s, c | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> rotate_x(const math::vector3<T>& v, T angle) | |||
{ | |||
return rotate_x(angle) * v; | |||
} | |||
template <class T> | |||
math::matrix3<T> rotate_y(T angle) | |||
{ | |||
const T c = std::cos(angle); | |||
const T s = std::sin(angle); | |||
return math::matrix3<T> | |||
{ | |||
c, T(0), s, | |||
T(0), T(1), T(0), | |||
-s, T(0), c | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> rotate_y(const math::vector3<T>& v, T angle) | |||
{ | |||
return rotate_y(angle) * v; | |||
} | |||
template <class T> | |||
math::matrix3<T> rotate_z(T angle) | |||
{ | |||
const T c = std::cos(angle); | |||
const T s = std::sin(angle); | |||
return math::matrix3<T> | |||
{ | |||
c, -s, T(0), | |||
s, c, T(0), | |||
T(0), T(0), T(1) | |||
}; | |||
} | |||
template <class T> | |||
math::vector3<T> rotate_z(const math::vector3<T>& v, T angle) | |||
{ | |||
return rotate_z(angle) * v; | |||
} | |||
} // namespace rectangular | |||
} // namespace coordinates | |||
#endif // ANTKEEPER_COORDINATES_RECTANGULAR_HPP |
@ -0,0 +1,58 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_GEOM_CARTESIAN_HPP | |||
#define ANTKEEPER_GEOM_CARTESIAN_HPP | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace geom { | |||
/// Functions which operate on Cartesian (rectangular) coordinates. | |||
namespace cartesian { | |||
/** | |||
* Converts Cartesian (rectangular) coordinates to spherical coordinates. | |||
* | |||
* @param v Cartesian coordinates. | |||
* @return Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians). | |||
* | |||
* @see geom::coordinates::spherical | |||
*/ | |||
template <class T> | |||
math::vector3<T> to_spherical(const math::vector3<T>& v); | |||
template <class T> | |||
math::vector3<T> to_spherical(const math::vector3<T>& v) | |||
{ | |||
const T xx_yy = v.x * v.x + v.y * v.y; | |||
return math::vector3<T> | |||
{ | |||
std::sqrt(xx_yy + v.z * v.z), | |||
std::atan2(v.z, std::sqrt(xx_yy)), | |||
std::atan2(v.y, v.x) | |||
}; | |||
} | |||
} // namespace cartesian | |||
} // namespace geom | |||
#endif // ANTKEEPER_GEOM_CARTESIAN_HPP |
@ -0,0 +1,134 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_FRAME_HPP | |||
#define ANTKEEPER_PHYSICS_FRAME_HPP | |||
#include "utility/fundamental-types.hpp" | |||
#include <cmath> | |||
namespace physics { | |||
/** | |||
* 3-dimensional frame of reference. | |||
* | |||
* @tparam T Scalar type. | |||
*/ | |||
template <class T> | |||
struct frame | |||
{ | |||
public: | |||
/// Scalar type. | |||
typedef T scalar_type; | |||
/// Vector type. | |||
typedef math::vector3<T> vector_type; | |||
/// Quaternion type. | |||
typedef math::quaternion<T> quaternion_type; | |||
/// Transformation matrix type. | |||
typedef math::matrix<T, 4, 4> matrix_type; | |||
/// Vector representing a translation from the origin of this frame to the origin of the parent frame. | |||
vector_type translation; | |||
/// Quaternion representing a rotation from the orientation of this frame to the orientation of the parent frame. | |||
quaternion_type rotation; | |||
/// Returns the inverse of this frame. | |||
frame inverse() const; | |||
/// Returns a transformation matrix representation of this frame. | |||
matrix_type matrix() const; | |||
/** | |||
* Transforms a vector from the parent frame space to this frame's space. | |||
* | |||
* @param v Vector in parent frame space. | |||
* @return Vector in this frame's space. | |||
*/ | |||
vector_type transform(const vector_type& v) const; | |||
/** | |||
* Transforms a frame from the parent frame space to this frame's space. | |||
* | |||
* @param f Frame in parent frame space. | |||
* @return Frame in this frame's space. | |||
*/ | |||
frame transform(const frame& f) const; | |||
/// @copydoc frame::transform(const vector_type&) const | |||
vector_type operator*(const vector_type& v) const; | |||
/// @copydoc frame::transform(const frame&) const | |||
frame operator*(const frame& f) const; | |||
}; | |||
template <class T> | |||
frame<T> frame<T>::inverse() const | |||
{ | |||
const quaternion_type inverse_rotation = math::conjugate(rotation); | |||
const vector_type inverse_translation = -(inverse_rotation * translation); | |||
return frame{inverse_translation, inverse_rotation}; | |||
} | |||
template <class T> | |||
typename frame<T>::matrix_type frame<T>::matrix() const | |||
{ | |||
matrix_type m = math::resize<4, 4>(math::matrix_cast<T>(rotation)); | |||
m[3].x = translation.x; | |||
m[3].y = translation.y; | |||
m[3].z = translation.z; | |||
return m; | |||
} | |||
template <class T> | |||
typename frame<T>::vector_type frame<T>::transform(const vector_type& v) const | |||
{ | |||
return translation + rotation * v; | |||
} | |||
template <class T> | |||
frame<T> frame<T>::transform(const frame& f) const | |||
{ | |||
return frame | |||
{ | |||
transform(f.translation), | |||
math::normalize(rotation * f.rotation) | |||
}; | |||
} | |||
template <class T> | |||
typename frame<T>::vector_type frame<T>::operator*(const vector_type& v) const | |||
{ | |||
return transform(v); | |||
} | |||
template <class T> | |||
frame<T> frame<T>::operator*(const frame& f) const | |||
{ | |||
return transform(f); | |||
} | |||
} // namespace physics | |||
#endif // ANTKEEPER_PHYSICS_FRAME_HPP |
@ -0,0 +1,95 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_ORBIT_ELEMENTS_HPP | |||
#define ANTKEEPER_PHYSICS_ORBIT_ELEMENTS_HPP | |||
#include "utility/fundamental-types.hpp" | |||
#include "physics/orbit/state.hpp" | |||
#include <cmath> | |||
namespace physics { | |||
namespace orbit { | |||
/** | |||
* Set of six Keplerian elements required to uniquely identify an orbit. | |||
* | |||
* @tparam T Scalar type. | |||
*/ | |||
template <class T> | |||
struct elements | |||
{ | |||
/// Scalar type. | |||
typedef T scalar_type; | |||
/// Eccentricity (e). | |||
scalar_type e; | |||
/// Semimajor axis (a). | |||
scalar_type a; | |||
/// Inclination (i), in radians. | |||
scalar_type i; | |||
/// Right ascension of the ascending node (OMEGA), in radians. | |||
scalar_type raan; | |||
/// Argument of periapsis (omega), in radians. | |||
scalar_type w; | |||
/// True anomaly (nu) at epoch, in radians. | |||
scalar_type ta; | |||
}; | |||
/** | |||
* Derives the longitude of the periapsis (pomega) of an orbit, given the argument of periapsis (omega) and longitude of the ascending node (OMEGA). | |||
* | |||
* @param w Argument of periapsis (omega), in radians. | |||
* @param raan Right ascension of the ascending node (OMEGA), in radians. | |||
* @return Longitude of the periapsis (pomega), in radians. | |||
*/ | |||
template <class T> | |||
T derive_longitude_periapsis(T w, T raan); | |||
/** | |||
* Derives the semiminor axis (b) of an orbit, given the semimajor axis (a) and eccentricity (e). | |||
* | |||
* @param a Semimajor axis (a). | |||
* @param e Eccentricity (e). | |||
* @return Semiminor axis (b). | |||
*/ | |||
template <class T> | |||
T derive_semiminor_axis(T a, T e); | |||
template <class T> | |||
T derive_longitude_periapsis(T w, T raan) | |||
{ | |||
return w + raan; | |||
} | |||
template <class T> | |||
T derive_semiminor_axis(T a, T e) | |||
{ | |||
return a * std::sqrt(T(1) - e * e); | |||
} | |||
} // namespace orbit | |||
} // namespace physics | |||
#endif // ANTKEEPER_PHYSICS_ORBIT_ELEMENTS_HPP |
@ -0,0 +1,131 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP | |||
#define ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP | |||
#include "physics/frame.hpp" | |||
namespace physics { | |||
namespace orbit { | |||
/// Inertial right-handed coordinate system | |||
namespace inertial { | |||
/** | |||
* Constucts a reference frame which transforms coordinates from inertial space into perifocal space. | |||
* | |||
* @param focus Cartesian coordinates of the focus of the orbit, in the parent space. | |||
* @param raan Right ascension of the ascending node (OMEGA), in radians. | |||
* @param i Orbital inclination (i), in radians. | |||
* @param w Argument of periapsis (omega), in radians. | |||
* @return Perifocal frame. | |||
*/ | |||
template <typename T> | |||
physics::frame<T> to_perifocal(const math::vector3<T>& focus, T raan, T i, T w) | |||
{ | |||
const math::quaternion<T> rotation = math::normalize | |||
( | |||
math::quaternion<T>::rotate_z(raan) * | |||
math::quaternion<T>::rotate_x(i) * | |||
math::quaternion<T>::rotate_z(w) | |||
); | |||
return physics::frame<T>{focus, rotation}.inverse(); | |||
} | |||
/** | |||
* Constructs a reference frame which transforms coordinates from inertial space to body-centered inertial space. | |||
* | |||
* @param r Cartesian position vector (r) of the center of the body, in inertial space. | |||
* @param i Orbital inclination (i), in radians. | |||
* @param axial_tilt Angle between the body's rotational axis and its orbital axis, in radians. | |||
* @return Body-centered inertial frame. | |||
*/ | |||
template <typename T> | |||
physics::frame<T> to_bci(const math::vector3<T>& r, T i, T axial_tilt) | |||
{ | |||
return physics::frame<T>{r, math::quaternion<T>::rotate_x(-axial_tilt - i)}.inverse(); | |||
} | |||
/** | |||
* Constructs a reference frame which transforms coordinates from inertial space to body-centered, body-fixed space. | |||
* | |||
* @param r Cartesian position vector (r) of the center of the body, in inertial space. | |||
* @param i Orbital inclination (i), in radians. | |||
* @param axial_tilt Angle between the orbiting body's rotational axis and its orbital axis, in radians. | |||
* @param axial_rotation Angle of rotation about the orbiting body's rotational axis, in radians. | |||
*/ | |||
template <typename T> | |||
frame<T> to_bcbf(const math::vector3<T>& r, T i, T axial_tilt, T axial_rotation) | |||
{ | |||
const math::quaternion<T> rotation = math::normalize | |||
( | |||
math::quaternion<T>::rotate_x(-axial_tilt - i) * | |||
math::quaternion<T>::rotate_z(axial_rotation) | |||
); | |||
return physics::frame<T>{r, rotation}.inverse(); | |||
} | |||
} // namespace inertial | |||
/// Perifocal right-handed coordinate system in which the x-axis points toward the periapsis of the orbit, the y-axis has a true anomaly of 90 degrees past the periapsis, and the z-axis is the angular momentum vector, which is orthogonal to the orbital plane. | |||
namespace perifocal { | |||
} // namespace perifocal | |||
/// Non-inertial body-centered, body-fixed right-handed coordinate system. The x-axis is orthogonal to the intersection of the prime meridian and the equator. The z-axis points toward the positive pole. The y-axis is right-hand orthogonal to the xz-plane. | |||
namespace bcbf { | |||
/** | |||
* Constructs a reference frame which transforms coordinates from BCBF space to topocentric space. | |||
* | |||
* @param distance Radial distance of the observer from the center of the body. | |||
* @param latitude Latitude of the observer, in radians. | |||
* @param longitude Longitude of the obserer, in radians. | |||
* @return Topocentric frame. | |||
*/ | |||
template <typename T> | |||
physics::frame<T> to_topocentric(T distance, T latitude, T longitude) | |||
{ | |||
const math::vector3<T> translation = {T(0), T(0), distance}; | |||
const math::quaternion<T> rotation = math::normalize | |||
( | |||
math::quaternion<T>::rotate_z(longitude) * | |||
math::quaternion<T>::rotate_y(math::half_pi<T> - latitude) | |||
); | |||
return physics::frame<T>{rotation * translation, rotation}.inverse(); | |||
} | |||
} // namespace bcbf | |||
/// Non-inertial topocentric right-handed coordinate system. Topocentric frames are constructed as south-east-zenith (SEZ) frames; the x-axis points south, the y-axis points east, and the z-axis points toward the zenith (orthogonal to reference spheroid). | |||
namespace topocentric { | |||
} // namespace topocentric | |||
} // namespace orbit | |||
} // namespace physics | |||
#endif // ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP |
@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_ORBIT_KEPLER_HPP | |||
#define ANTKEEPER_PHYSICS_ORBIT_KEPLER_HPP | |||
#include <cmath> | |||
namespace physics { | |||
namespace orbit { | |||
/** | |||
* Iteratively solves Kepler's equation for eccentric anomaly (E). | |||
* | |||
* @param ec Eccentricity (e). | |||
* @param ma Mean anomaly (M). | |||
* @param iterations Maximum number of iterations. | |||
* @param tolerance Solution error tolerance. | |||
* @return Eccentric anomaly (E). | |||
*/ | |||
template <class T> | |||
T kepler_ea(T ec, T ma, std::size_t iterations, T tolerance = T(0)); | |||
/** | |||
* Solves Kepler's equation for mean anomaly (M). | |||
* | |||
* @param ec Eccentricity (e). | |||
* @param ea Eccentric anomaly (E). | |||
* @return Mean anomaly (M). | |||
*/ | |||
template <class T> | |||
T kepler_ma(T ec, T ea); | |||
template <class T> | |||
T kepler_ea(T ec, T ma, std::size_t iterations, T tolerance) | |||
{ | |||
// Approximate eccentric anomaly, E | |||
T ea0 = ma + ec * std::sin(ma) * (T(1.0) + ec * std::cos(ma)); | |||
// Iteratively converge E0 and E1 | |||
for (std::size_t i = 0; i < iterations; ++i) | |||
{ | |||
const T ea1 = ea0 - (ea0 - ec * std::sin(ea0) - ma) / (T(1.0) - ec * std::cos(ea0)); | |||
const T error = std::abs(ea1 - ea0); | |||
ea0 = ea1; | |||
if (error < tolerance) | |||
break; | |||
} | |||
return ea0; | |||
} | |||
template <class T> | |||
T kepler_ma(T ec, T ea) | |||
{ | |||
return ea - ec * std::sin(ea); | |||
} | |||
} // namespace orbit | |||
} // namespace physics | |||
#endif // ANTKEEPER_PHYSICS_ORBIT_KEPLER_HPP |
@ -0,0 +1,39 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_ORBIT_HPP | |||
#define ANTKEEPER_PHYSICS_ORBIT_HPP | |||
namespace physics { | |||
/** | |||
* Orbital mechanics. | |||
* | |||
* @see Curtis, H. D. (2005). *Orbital mechanics for engineering students*. Amsterdam: Elsevier Butterworth Heinemann. | |||
*/ | |||
namespace orbit {} | |||
} // namespace physics | |||
#include "physics/orbit/elements.hpp" | |||
#include "physics/orbit/frames.hpp" | |||
#include "physics/orbit/kepler.hpp" | |||
#include "physics/orbit/state.hpp" | |||
#endif // ANTKEEPER_PHYSICS_ORBIT_HPP |
@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHYSICS_ORBIT_STATE_HPP | |||
#define ANTKEEPER_PHYSICS_ORBIT_STATE_HPP | |||
#include "utility/fundamental-types.hpp" | |||
namespace physics { | |||
namespace orbit { | |||
/** | |||
* Pair of orbital state Cartesian position (r) and velocity (v) vectors. | |||
* | |||
* @tparam T Scalar type. | |||
*/ | |||
template <class T> | |||
struct state | |||
{ | |||
/// Scalar type. | |||
typedef T scalar_type; | |||
/// Vector type. | |||
typedef math::vector3<T> vector_type; | |||
/// Cartesian orbital position vector (r). | |||
vector_type r; | |||
/// Cartesian orbital velocity vector (v). | |||
vector_type v; | |||
}; | |||
} // namespace orbit | |||
} // namespace physics | |||
#endif // ANTKEEPER_PHYSICS_ORBIT_STATE_HPP |