💿🐜 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.

220 lines
6.5 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_COORDINATES_HORIZONTAL_HPP
  20. #define ANTKEEPER_COORDINATES_HORIZONTAL_HPP
  21. #include "coordinates/rectangular.hpp"
  22. #include "coordinates/spherical.hpp"
  23. #include "utility/fundamental-types.hpp"
  24. #include <cmath>
  25. namespace coordinates {
  26. namespace rectangular {
  27. /// 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.
  28. namespace horizontal {
  29. /**
  30. * Produces a matrix which rotates rectangular coordinates from local horizontal space into equatorial space.
  31. *
  32. * @param lat Observer's latitude, in radians.
  33. * @param lst Local sidereal time, in radians.
  34. * @return Rotation matrix.
  35. *
  36. * @see coordinates::equatorial
  37. */
  38. template <class T>
  39. math::matrix3<T> to_equatorial(T lat, T lst);
  40. /**
  41. * Rotates rectangular coordinates from local horizontal space into equatorial space.
  42. *
  43. * @param v Rectangular coordinates in local horizontal space.
  44. * @param lat Observer's latitude, in radians.
  45. * @param lst Local sidereal time, in radians.
  46. * @return Rectangular coordinates in equatorial space.
  47. *
  48. * @see coordinates::equatorial
  49. */
  50. template <class T>
  51. math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst);
  52. /**
  53. * Produces a matrix which rotates rectangular coordinates from local horizontal space into ecliptic space.
  54. *
  55. * @param ecl Obliquity of the ecliptic, in radians.
  56. * @param lat Observer's latitude, in radians.
  57. * @param lst Local sidereal time, in radians.
  58. * @return Rotation matrix.
  59. *
  60. * @see coordinates::ecliptic
  61. */
  62. template <class T>
  63. math::matrix3<T> to_ecliptic(T ecl, T lat, T lst);
  64. /**
  65. * Rotates rectangular coordinates from local horizontal space into ecliptic space.
  66. *
  67. * @param v Rectangular coordinates in local horizontal space.
  68. * @param ecl Obliquity of the ecliptic, in radians.
  69. * @param lat Observer's latitude, in radians.
  70. * @param lst Local sidereal time, in radians.
  71. * @return Rectangular coordinates in ecliptic space.
  72. *
  73. * @see coordinates::ecliptic
  74. */
  75. template <class T>
  76. math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst);
  77. } // namespace horizontal
  78. } // namespace rectangular
  79. namespace spherical {
  80. /// Spherical local horizontal coordinate system.
  81. namespace horizontal {
  82. /**
  83. * Rotates spherical coordinates from local horizontal space into equatorial space.
  84. *
  85. * @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians).
  86. * @param lat Observer's latitude, in radians.
  87. * @param lst Local sidereal time, in radians.
  88. * @return Spherical coordinates in equatorial space, in the ISO order of radial distance, declination (radians), and right ascension (radians).
  89. *
  90. * @see coordinates::equatorial
  91. */
  92. template <class T>
  93. math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst);
  94. /**
  95. * Rotates spherical coordinates from local horizontal space into ecliptic space.
  96. *
  97. * @param v Spherical coordinates in local horizontal space, in the ISO order of radial distance, altitude (radians), and azimuth (radians).
  98. * @param ecl Obliquity of the ecliptic, in radians.
  99. * @param lat Observer's latitude, in radians.
  100. * @param lst Local sidereal time, in radians.
  101. * @return Spherical coordinates in ecliptic space, in the ISO order of radial distance, ecliptic latitude (radians), and ecliptic longitude (radians).
  102. *
  103. * @see coordinates::ecliptic
  104. */
  105. template <class T>
  106. math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst);
  107. } // namespace horizontal
  108. } // namespace spherical
  109. namespace rectangular {
  110. namespace horizontal {
  111. template <class T>
  112. math::matrix3<T> to_equatorial(T lat, T lst)
  113. {
  114. const T c_lat = std::cos(lat);
  115. const T s_lat = std::sin(lat);
  116. const T c_lst = std::cos(lst);
  117. const T s_lst = std::sin(lst);
  118. return math::matrix3<T>
  119. {
  120. c_lst * s_lat, s_lst * s_lat, -c_lat,
  121. s_lst, c_lst, T(0.0),
  122. c_lst * c_lat, s_lst * c_lat, s_lat
  123. };
  124. }
  125. template <class T>
  126. math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst)
  127. {
  128. return to_equatorial<T>(lat, lst) * v;
  129. }
  130. template <class T>
  131. math::matrix3<T> to_ecliptic(T ecl, T lat, T lst)
  132. {
  133. const T c_ecl = std::cos(ecl);
  134. const T s_ecl = std::sin(ecl);
  135. const T c_lat = std::cos(lat);
  136. const T s_lat = std::sin(lat);
  137. const T c_lst = std::cos(lst);
  138. const T s_lst = std::sin(lst);
  139. return math::matrix3<T>
  140. {
  141. s_lat * c_lst, s_lat * s_lst * c_ecl - c_lat * s_ecl, s_lat * s_lst * -s_ecl - c_lat * c_ecl,
  142. s_lst, -c_lst * c_ecl, c_lst * s_ecl,
  143. c_lat * c_lst, c_lat * s_lst * c_ecl + s_lat * s_ecl, c_lat * s_lst * -s_ecl + s_lat * c_ecl
  144. };
  145. }
  146. template <class T>
  147. math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst)
  148. {
  149. return to_ecliptic<T>(ecl, lat, lst) * v;
  150. }
  151. } // namespace horizontal
  152. } // namespace rectangular
  153. namespace spherical {
  154. namespace horizontal {
  155. template <class T>
  156. math::vector3<T> to_equatorial(const math::vector3<T>& v, T lat, T lst)
  157. {
  158. return coordinates::rectangular::to_spherical<T>
  159. (
  160. coordinates::rectangular::horizontal::to_equatorial<T>
  161. (
  162. coordinates::spherical::to_rectangular<T>(v),
  163. lat,
  164. lst
  165. )
  166. );
  167. }
  168. template <class T>
  169. math::vector3<T> to_ecliptic(const math::vector3<T>& v, T ecl, T lat, T lst)
  170. {
  171. return coordinates::rectangular::to_spherical<T>
  172. (
  173. coordinates::rectangular::horizontal::to_ecliptic<T>
  174. (
  175. coordinates::spherical::to_rectangular<T>(v),
  176. ecl,
  177. lat,
  178. lst
  179. )
  180. );
  181. }
  182. } // namespace horizontal
  183. } // namespace spherical
  184. } // namespace coordinates
  185. #endif // ANTKEEPER_COORDINATES_HORIZONTAL_HPP