20 #ifndef ANTKEEPER_GEOM_CLOSEST_POINT_HPP
21 #define ANTKEEPER_GEOM_CLOSEST_POINT_HPP
49 template <
class T, std::
size_t N>
52 return a.extrapolate(std::max<T>(T{0},
math::dot(
b -
a.origin,
a.direction)));
66 template <
class T, std::
size_t N>
69 const auto direction_ab =
ab.b -
ab.a;
71 const auto distance_ab =
math::dot(
c -
ab.a, direction_ab);
72 if (distance_ab <= T{0})
79 if (distance_ab >= sqr_length_ab)
85 return ab.a + direction_ab * (distance_ab / sqr_length_ab);
103 template <
class T, std::
size_t N>
106 const auto direction_ab =
ab.b -
ab.a;
107 const auto direction_cd = cd.b - cd.a;
108 const auto direction_ca =
ab.a - cd.a;
112 const auto cd_dot_ca =
math::dot(direction_cd, direction_ca);
114 if (sqr_length_ab <= T{0})
116 if (sqr_length_cd <= T{0})
127 cd.a + direction_cd * std::min<T>(std::max<T>(cd_dot_ca / sqr_length_cd, T{0}), T{1})
133 const auto ab_dot_ca =
math::dot(direction_ab, direction_ca);
135 if (sqr_length_cd <= T{0})
140 ab.a + direction_ab * std::min<T>(std::max<T>(-ab_dot_ca / sqr_length_ab, T{0}), T{1}),
146 const auto ab_dot_cd =
math::dot(direction_ab, direction_cd);
148 const auto den = sqr_length_ab * sqr_length_cd - ab_dot_cd * ab_dot_cd;
150 auto distance_ab = (den) ? std::min<T>(std::max<T>((ab_dot_cd * cd_dot_ca - ab_dot_ca * sqr_length_cd) / den, T{0}), T{1}) : T{0};
151 auto distance_cd = (ab_dot_cd * distance_ab + cd_dot_ca) / sqr_length_cd;
153 if (distance_cd < T{0})
157 ab.a + direction_ab * std::min<T>(std::max<T>(-ab_dot_ca / sqr_length_ab, T{0}), T{1}),
161 else if (distance_cd > T{1})
165 ab.a + direction_ab * std::min<T>(std::max<T>((ab_dot_cd - ab_dot_ca) / sqr_length_ab, T{0}), T{1}),
172 ab.a + direction_ab * distance_ab,
173 cd.a + direction_cd * distance_cd
190 template <
class T, std::
size_t N>
215 const auto ab =
b -
a;
216 const auto ac =
c -
a;
217 const auto ap = p -
a;
219 const auto ap_dot_ac =
math::dot(ap, ac);
220 if (ap_dot_ab <= T{0} && ap_dot_ac <= T{0})
225 const auto bc =
c -
b;
226 const auto bp = p -
b;
229 if (bp_dot_ba <= T{0} && bp_dot_bc <= T{0})
234 const auto cp = p -
c;
237 if (cp_dot_ca <= T{0} && cp_dot_cb <= T{0})
243 const auto pa =
a - p;
244 const auto pb =
b - p;
246 if (vc <= T{0} && ap_dot_ab >= T{0} && bp_dot_ba >= T{0})
251 const auto pc =
c - p;
253 if (va <= T{0} && bp_dot_bc >= T{0} && cp_dot_cb >= T{0})
259 if (vb <= T{0} && ap_dot_ac >= T{0} && cp_dot_ca >= T{0})
264 const auto u = va / (va + vb + vc);
265 const auto v = vb / (va + vb + vc);
266 const auto w = T{1} - u - v;
289 template <
class T, std::
size_t N>
292 const auto ab =
b -
a.center;
294 return d >
a.radius *
a.radius ?
a.center +
ab * (
a.radius /
std::sqrt(d)) :
b;
308 template <
class T, std::
size_t N>
312 const auto cb =
b -
c;
314 return d >
a.radius *
a.radius ?
c + cb * (
a.radius /
std::sqrt(d)) :
b;
328 template <
class T, std::
size_t N>
triangle_region
Voronoi regions of a triangle.
constexpr point< T, N > closest_point(const ray< T, N > &a, const point< T, N > &b) noexcept
Calculates the closest point on a ray to a point.
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.
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
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.
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.
n-dimensional axis-aligned rectangle.
n-dimensional line segment.
Half of a line proceeding from an initial point.