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

175 lines
4.1 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_RECTANGULAR_HPP
  20. #define ANTKEEPER_COORDINATES_RECTANGULAR_HPP
  21. #include "utility/fundamental-types.hpp"
  22. #include <cmath>
  23. namespace coordinates {
  24. /// Rectangular (Cartesian) coordinate systems.
  25. namespace rectangular {
  26. /**
  27. * Produces a matrix which rotates rectangular coordinates about the x-axis by a given angle.
  28. *
  29. * @param angle Angle of rotation, in radians.
  30. * @return Rotation matrix.
  31. */
  32. template <class T>
  33. math::matrix3<T> rotate_x(T angle);
  34. /**
  35. * Rotates rectangular coordinates about the x-axis.
  36. *
  37. * @param v Rectangular coordinates to rotate.
  38. * @param angle Angle of rotation, in radians.
  39. * @return Rotated rectangular coordinates.
  40. */
  41. template <class T>
  42. math::vector3<T> rotate_x(const math::vector3<T>& v, T angle);
  43. /**
  44. * Produces a matrix which rotates rectangular coordinates about the y-axis by a given angle.
  45. *
  46. * @param angle Angle of rotation, in radians.
  47. * @return Rotation matrix.
  48. */
  49. template <class T>
  50. math::matrix3<T> rotate_y(T angle);
  51. /**
  52. * Rotates rectangular coordinates about the y-axis.
  53. *
  54. * @param v Rectangular coordinates to rotate.
  55. * @param angle Angle of rotation, in radians.
  56. * @return Rotated rectangular coordinates.
  57. */
  58. template <class T>
  59. math::vector3<T> rotate_y(const math::vector3<T>& v, T angle);
  60. /**
  61. * Produces a matrix which rotates rectangular coordinates about the z-axis by a given angle.
  62. *
  63. * @param angle Angle of rotation, in radians.
  64. * @return Rotation matrix.
  65. */
  66. template <class T>
  67. math::matrix3<T> rotate_z(T angle);
  68. /**
  69. * Rotates rectangular coordinates about the z-axis.
  70. *
  71. * @param v Rectangular coordinates to rotate.
  72. * @param angle Angle of rotation, in radians.
  73. * @return Rotated rectangular coordinates.
  74. */
  75. template <class T>
  76. math::vector3<T> rotate_z(const math::vector3<T>& v, T angle);
  77. /**
  78. * Converts rectangular coordinates to spherical coordinates.
  79. *
  80. * @param v Rectangular coordinates.
  81. * @return Spherical coordinates, in the ISO order of radial distance, polar angle (radians), and azimuthal angle (radians).
  82. *
  83. * @see coordinates::spherical
  84. */
  85. template <class T>
  86. math::vector3<T> to_spherical(const math::vector3<T>& v);
  87. template <class T>
  88. math::vector3<T> to_spherical(const math::vector3<T>& v)
  89. {
  90. const T xx_yy = v.x * v.x + v.y * v.y;
  91. return math::vector3<T>
  92. {
  93. std::sqrt(xx_yy + v.z * v.z),
  94. std::atan2(v.z, std::sqrt(xx_yy)),
  95. std::atan2(v.y, v.x)
  96. };
  97. }
  98. template <class T>
  99. math::matrix3<T> rotate_x(T angle)
  100. {
  101. const T c = std::cos(angle);
  102. const T s = std::sin(angle);
  103. return math::matrix3<T>
  104. {
  105. T(1), T(0), T(0),
  106. T(0), c, -s,
  107. T(0), s, c
  108. };
  109. }
  110. template <class T>
  111. math::vector3<T> rotate_x(const math::vector3<T>& v, T angle)
  112. {
  113. return rotate_x(angle) * v;
  114. }
  115. template <class T>
  116. math::matrix3<T> rotate_y(T angle)
  117. {
  118. const T c = std::cos(angle);
  119. const T s = std::sin(angle);
  120. return math::matrix3<T>
  121. {
  122. c, T(0), s,
  123. T(0), T(1), T(0),
  124. -s, T(0), c
  125. };
  126. }
  127. template <class T>
  128. math::vector3<T> rotate_y(const math::vector3<T>& v, T angle)
  129. {
  130. return rotate_y(angle) * v;
  131. }
  132. template <class T>
  133. math::matrix3<T> rotate_z(T angle)
  134. {
  135. const T c = std::cos(angle);
  136. const T s = std::sin(angle);
  137. return math::matrix3<T>
  138. {
  139. c, -s, T(0),
  140. s, c, T(0),
  141. T(0), T(0), T(1)
  142. };
  143. }
  144. template <class T>
  145. math::vector3<T> rotate_z(const math::vector3<T>& v, T angle)
  146. {
  147. return rotate_z(angle) * v;
  148. }
  149. } // namespace rectangular
  150. } // namespace coordinates
  151. #endif // ANTKEEPER_COORDINATES_RECTANGULAR_HPP