💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
4.8 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP
  20. #define ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP
  21. #include "physics/frame.hpp"
  22. namespace physics {
  23. namespace orbit {
  24. /// Inertial right-handed coordinate system
  25. namespace inertial {
  26. /**
  27. * Constucts a reference frame which transforms coordinates from inertial space into perifocal space.
  28. *
  29. * @param focus Cartesian coordinates of the focus of the orbit, in the parent space.
  30. * @param raan Right ascension of the ascending node (OMEGA), in radians.
  31. * @param i Orbital inclination (i), in radians.
  32. * @param w Argument of periapsis (omega), in radians.
  33. * @return Perifocal frame.
  34. */
  35. template <typename T>
  36. physics::frame<T> to_perifocal(const math::vector3<T>& focus, T raan, T i, T w)
  37. {
  38. const math::quaternion<T> rotation = math::normalize
  39. (
  40. math::quaternion<T>::rotate_z(raan) *
  41. math::quaternion<T>::rotate_x(i) *
  42. math::quaternion<T>::rotate_z(w)
  43. );
  44. return physics::frame<T>{focus, rotation}.inverse();
  45. }
  46. /**
  47. * Constructs a reference frame which transforms coordinates from inertial space to body-centered inertial space.
  48. *
  49. * @param r Cartesian position vector (r) of the center of the body, in inertial space.
  50. * @param i Orbital inclination (i), in radians.
  51. * @param axial_tilt Angle between the body's rotational axis and its orbital axis, in radians.
  52. * @return Body-centered inertial frame.
  53. */
  54. template <typename T>
  55. physics::frame<T> to_bci(const math::vector3<T>& r, T i, T axial_tilt)
  56. {
  57. return physics::frame<T>{r, math::quaternion<T>::rotate_x(-axial_tilt - i)}.inverse();
  58. }
  59. /**
  60. * Constructs a reference frame which transforms coordinates from inertial space to body-centered, body-fixed space.
  61. *
  62. * @param r Cartesian position vector (r) of the center of the body, in inertial space.
  63. * @param i Orbital inclination (i), in radians.
  64. * @param axial_tilt Angle between the orbiting body's rotational axis and its orbital axis, in radians.
  65. * @param axial_rotation Angle of rotation about the orbiting body's rotational axis, in radians.
  66. */
  67. template <typename T>
  68. frame<T> to_bcbf(const math::vector3<T>& r, T i, T axial_tilt, T axial_rotation)
  69. {
  70. const math::quaternion<T> rotation = math::normalize
  71. (
  72. math::quaternion<T>::rotate_x(-axial_tilt - i) *
  73. math::quaternion<T>::rotate_z(axial_rotation)
  74. );
  75. return physics::frame<T>{r, rotation}.inverse();
  76. }
  77. } // namespace inertial
  78. /// 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.
  79. namespace perifocal {
  80. } // namespace perifocal
  81. /// 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.
  82. namespace bcbf {
  83. /**
  84. * Constructs a reference frame which transforms coordinates from BCBF space to topocentric space.
  85. *
  86. * @param distance Radial distance of the observer from the center of the body.
  87. * @param latitude Latitude of the observer, in radians.
  88. * @param longitude Longitude of the obserer, in radians.
  89. * @return Topocentric frame.
  90. */
  91. template <typename T>
  92. physics::frame<T> to_topocentric(T distance, T latitude, T longitude)
  93. {
  94. const math::vector3<T> translation = {T(0), T(0), distance};
  95. const math::quaternion<T> rotation = math::normalize
  96. (
  97. math::quaternion<T>::rotate_z(longitude) *
  98. math::quaternion<T>::rotate_y(math::half_pi<T> - latitude)
  99. );
  100. return physics::frame<T>{rotation * translation, rotation}.inverse();
  101. }
  102. } // namespace bcbf
  103. /// 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).
  104. namespace topocentric {
  105. } // namespace topocentric
  106. } // namespace orbit
  107. } // namespace physics
  108. #endif // ANTKEEPER_PHYSICS_ORBIT_FRAMES_HPP