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

139 lines
3.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_GEOM_PRIMITIVE_HYPERSPHERE_HPP
  20. #define ANTKEEPER_GEOM_PRIMITIVE_HYPERSPHERE_HPP
  21. #include "math/constants.hpp"
  22. #include "math/vector.hpp"
  23. namespace geom {
  24. namespace primitive {
  25. /**
  26. * *n*-dimensional sphere.
  27. *
  28. * @tparam T Real type.
  29. * @tparam N Number of dimensions.
  30. */
  31. template <class T, std::size_t N>
  32. struct hypersphere
  33. {
  34. typedef math::vector<T, N> vector_type;
  35. /// Hypersphere center.
  36. vector_type center;
  37. /// Hypersphere radius.
  38. T radius;
  39. /**
  40. * Tests whether a point is contained within this hypersphere.
  41. *
  42. * @param point Point to test for containment.
  43. *
  44. * @return `true` if the point is contained within this hypersphere, `false` otherwise.
  45. */
  46. constexpr bool contains(const vector_type& point) const noexcept
  47. {
  48. return math::sqr_distance(center, point) <= radius * radius;
  49. }
  50. /**
  51. * Tests whether another hypersphere is contained within this hypersphere.
  52. *
  53. * @param other Hypersphere to test for containment.
  54. *
  55. * @return `true` if the hypersphere is contained within this hypersphere, `false` otherwise.
  56. */
  57. constexpr bool contains(const hypersphere& other) const noexcept
  58. {
  59. const T containment_radius = radius - other.radius;
  60. if (containment_radius < T{0})
  61. return false;
  62. return math::sqr_distance(center, other.center) <= containment_radius * containment_radius;
  63. }
  64. /**
  65. * Calculates the signed distance from the hypersphere to a point.
  66. *
  67. * @param point Input point.
  68. *
  69. * @return Signed distance from the hypersphere to @p point.
  70. */
  71. T distance(const vector_type& point) const noexcept
  72. {
  73. return math::distance(center, point) - radius;
  74. }
  75. /**
  76. * Tests whether another hypersphere intersects this hypersphere.
  77. *
  78. * @param other Hypersphere to test for intersection.
  79. *
  80. * @return `true` if the hypersphere intersects this hypersphere, `false` otherwise.
  81. */
  82. constexpr bool intersects(const hypersphere& other) const noexcept
  83. {
  84. const T intersection_radius = radius + other.radius;
  85. return math::sqr_distance(center, other.center) <= intersection_radius * intersection_radius;
  86. }
  87. /**
  88. * Volume calculation helper function.
  89. *
  90. * @tparam M Dimension.
  91. *
  92. * @param r Radius.
  93. *
  94. * @return Volume.
  95. */
  96. /// @private
  97. /// @{
  98. template <std::size_t M>
  99. static constexpr T volume(T r) noexcept
  100. {
  101. return (math::two_pi<T> / static_cast<T>(M)) * r * r * volume<M - 2>(r);
  102. }
  103. template <>
  104. static constexpr T volume<1>(T r) noexcept
  105. {
  106. return r * T{2};
  107. }
  108. template <>
  109. static constexpr T volume<0>(T r) noexcept
  110. {
  111. return T{1};
  112. }
  113. /// @}
  114. /// Calculates the volume of the hypersphere.
  115. inline constexpr T volume() const noexcept
  116. {
  117. return volume<N>(radius);
  118. }
  119. };
  120. } // namespace primitive
  121. } // namespace geom
  122. #endif // ANTKEEPER_GEOM_PRIMITIVE_HYPERSPHERE_HPP