@ -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 |