Antkeeper  0.0.1
primitives/intersection.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 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 
20 #ifndef ANTKEEPER_GEOM_PRIMITIVES_INTERSECTION_HPP
21 #define ANTKEEPER_GEOM_PRIMITIVES_INTERSECTION_HPP
22 
27 #include <algorithm>
28 #include <optional>
29 
30 namespace geom {
31 namespace primitive {
32 
42 template <class T, std::size_t N>
43 constexpr std::optional<T> intersection(const ray<T, N>& ray, const hyperplane<T, N>& hyperplane) noexcept
44 {
45  const T cos_theta = math::dot(ray.direction, hyperplane.normal);
46  if (cos_theta != T{0})
47  {
48  const T t = -hyperplane.distance(ray.origin) / cos_theta;
49  if (t >= T{0})
50  return t;
51  }
52 
53  return std::nullopt;
54 }
55 
56 template <class T, std::size_t N>
57 inline constexpr std::optional<T> intersection(const hyperplane<T, N>& hyperplane, const ray<T, N>& ray) noexcept
58 {
59  return intersection<T, N>(ray, hyperplane);
60 }
62 
72 template <class T, std::size_t N>
73 constexpr std::optional<std::tuple<T, T>> intersection(const ray<T, N>& ray, const hyperrectangle<T, N>& hyperrectangle) noexcept
74 {
75  T t0 = -std::numeric_limits<T>::infinity();
76  T t1 = std::numeric_limits<T>::infinity();
77 
78  for (std::size_t i = 0; i < N; ++i)
79  {
80  if (!ray.direction[i])
81  {
82  if (ray.origin[i] < hyperrectangle.min[i] || ray.origin[i] > hyperrectangle.max[i])
83  return std::nullopt;
84  }
85  else
86  {
87  T min = (hyperrectangle.min[i] - ray.origin[i]) / ray.direction[i];
88  T max = (hyperrectangle.max[i] - ray.origin[i]) / ray.direction[i];
89  t0 = std::max(t0, std::min(min, max));
90  t1 = std::min(t1, std::max(min, max));
91  }
92  }
93 
94  if (t0 > t1 || t1 < T{0})
95  return std::nullopt;
96 
97  return {t0, t1};
98 }
99 
100 template <class T, std::size_t N>
101 inline constexpr std::optional<std::tuple<T, T>> intersection(const hyperrectangle<T, N>& hyperrectangle, const ray<T, N>& ray) noexcept
102 {
103  return intersection<T, N>(ray, hyperrectangle);
104 }
106 
115 template <class T, std::size_t N>
116 std::optional<std::tuple<T, T>> intersection(const ray<T, N>& ray, const hypersphere<T, N>& hypersphere) noexcept
117 {
118  const math::vector<T, N> displacement = ray.origin - hypersphere.center;
119  const T b = math::dot(displacement, ray.direction);
120  const T c = math::sqr_length(displacement) - hypersphere.radius * hypersphere.radius;
121  T h = b * b - c;
122 
123  if (h < T{0})
124  return std::nullopt;
125 
126  h = std::sqrt(h);
127 
128  T t0 = -b - h;
129  T t1 = -b + h;
130  if (t0 > t1)
131  std::swap(t0, t1);
132 
133  if (t0 < T{0})
134  return std::nullopt;
135 
136  return std::tuple<T, T>{t0, t1};
137 }
138 
147 template <class T, std::size_t N>
148 inline constexpr bool intersection(const hyperrectangle<T, N>& a, const hyperrectangle<T, N>& b) noexcept
149 {
150  return a.intersects(b);
151 }
152 
162 template <class T, std::size_t N>
164 {
165  T sqr_distance{0};
166  for (std::size_t i = 0; i < N; ++i)
167  {
168  if (hypersphere.center[i] < hyperrectangle.min[i])
169  {
170  const T difference = hyperrectangle.min[i] - hypersphere.center[i];
172  }
173  else if (hypersphere.center[i] > hyperrectangle.max[i])
174  {
175  const T difference = hypersphere.center[i] - hyperrectangle.max[i];
177  }
178  }
179 
181 }
182 
183 template <class T, std::size_t N>
184 inline constexpr bool intersection(const hypersphere<T, N>& hypersphere, const hyperrectangle<T, N>& hyperrectangle) noexcept
185 {
186  return intersection<T, N>(hyperrectangle, hypersphere);
187 }
189 
198 template <class T, std::size_t N>
199 inline constexpr bool intersection(const hypersphere<T, N>& a, const hypersphere<T, N>& b) noexcept
200 {
201  return a.intersects(b);
202 }
203 
204 } // namespace primitive
205 } // namespace geom
206 
207 #endif // ANTKEEPER_GEOM_PRIMITIVES_INTERSECTION_HPP
constexpr int difference(T x, T y) noexcept
Returns the number of differing bits between two values, known as Hamming distance.
Definition: bit-math.hpp:280
constexpr std::optional< T > intersection(const ray< T, N > &ray, const hyperplane< T, N > &hyperplane) noexcept
Ray-hyperplane intersection test.
Geometry.
Definition: aabb.hpp:30
constexpr T sqr_distance(const vector< T, N > &p0, const vector< T, N > &p1) noexcept
Calculates the square distance between two points.
Definition: vector.hpp:1360
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
Definition: vector.hpp:1180
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
Definition: quaternion.hpp:642
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
constexpr T dot(const quaternion< T > &a, const quaternion< T > &b) noexcept
Calculates the dot product of two quaternions.
Definition: quaternion.hpp:500
constexpr vector< T, N > min(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the minimum elements of two vectors.
Definition: vector.hpp:1199
n-dimensional plane.
Definition: hyperplane.hpp:36
vector_type normal
Hyperplane normal.
Definition: hyperplane.hpp:41
constexpr T distance(const vector_type &point) const noexcept
Calculates the signed distance from the hyperplane to a point.
Definition: hyperplane.hpp:78
n-dimensional axis-aligned rectangle.
vector_type max
Maximum extent of the hyperrectangle.
vector_type min
Minimum extent of the hyperrectangle.
n-dimensional sphere.
Definition: hypersphere.hpp:37
vector_type center
Hypersphere center.
Definition: hypersphere.hpp:42
T radius
Hypersphere radius.
Definition: hypersphere.hpp:45
Half of a line proceeding from an initial point.
vector_type direction
Ray direction vector.
vector_type origin
Ray origin position.
n-dimensional vector.
Definition: vector.hpp:43