11#ifndef PBAT_GEOMETRY_CLOSESTPOINTQUERIES_H
12#define PBAT_GEOMETRY_CLOSESTPOINTQUERIES_H
14#include "pbat/HostDevice.h"
39template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixP, mini::CMatrix TMatrixN>
40PBAT_HOST_DEVICE
auto PointOnPlane(TMatrixX
const& X, TMatrixP
const& P, TMatrixN
const& n)
41 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>;
53template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ>
54PBAT_HOST_DEVICE
auto PointOnLineSegment(TMatrixX
const& X, TMatrixP
const& P, TMatrixQ
const& Q)
55 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>;
68template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
71 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>;
86 mini::CMatrix TMatrixP,
87 mini::CMatrix TMatrixA,
88 mini::CMatrix TMatrixB,
89 mini::CMatrix TMatrixC>
91UvwPointInTriangle(TMatrixP
const& P, TMatrixA
const& A, TMatrixB
const& B, TMatrixC
const& C)
92 -> mini::SVector<typename TMatrixP::ScalarType, 3>;
107 mini::CMatrix TMatrixP,
108 mini::CMatrix TMatrixA,
109 mini::CMatrix TMatrixB,
110 mini::CMatrix TMatrixC>
112PointInTriangle(TMatrixP
const& P, TMatrixA
const& A, TMatrixB
const& B, TMatrixC
const& C)
113 -> mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>;
132 mini::CMatrix TMatrixP,
133 mini::CMatrix TMatrixA,
134 mini::CMatrix TMatrixB,
135 mini::CMatrix TMatrixC,
136 mini::CMatrix TMatrixD>
142 TMatrixD
const& D) -> mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>;
229 mini::CMatrix TMatrixP1,
230 mini::CMatrix TMatrixQ1,
231 mini::CMatrix TMatrixP2,
232 mini::CMatrix TMatrixQ2,
233 class TScalar =
typename TMatrixP1::ScalarType>
234PBAT_HOST_DEVICE
auto Lines(
239 TScalar eps = std::numeric_limits<TScalar>::min()) -> mini::SVector<TScalar, 2>;
241template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixP, mini::CMatrix TMatrixN>
242PBAT_HOST_DEVICE
auto PointOnPlane(TMatrixX
const& X, TMatrixP
const& P, TMatrixN
const& n)
243 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>
246 using ScalarType =
typename TMatrixX::ScalarType;
248 bool const bIsNormalUnit = abs(SquaredNorm(n) - ScalarType(1)) <= ScalarType(1e-15);
249 assert(bIsNormalUnit);
254 ScalarType
const t = Dot(n, X - P);
255 mini::SVector<ScalarType, TMatrixX::kRows> Xplane = X - t * n;
259template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ>
261 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>
263 using ScalarType =
typename TMatrixX::ScalarType;
268 mini::SVector<ScalarType, TMatrixX::kRows>
const PQ = Q - P;
270 ScalarType t = Dot(X - P, PQ) / SquaredNorm(PQ);
272 t = min(max(t, ScalarType(0)), ScalarType(1));
274 auto const Xpq = P + t * PQ;
278template <mini::CMatrix TMatrixX, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
281 -> mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows>
287 mini::SVector<typename TMatrixX::ScalarType, TMatrixX::kRows> X = P;
289 [&]<
auto i>() { X(i) = min(max(X(i), L(i)), U(i)); });
294 mini::CMatrix TMatrixP,
295 mini::CMatrix TMatrixA,
296 mini::CMatrix TMatrixB,
297 mini::CMatrix TMatrixC>
300 -> mini::SVector<typename TMatrixP::ScalarType, 3>
302 using ScalarType =
typename TMatrixP::ScalarType;
308 auto constexpr kRows = TMatrixP::kRows;
309 mini::SVector<ScalarType, kRows>
const AB = B - A;
310 mini::SVector<ScalarType, kRows>
const AC = C - A;
311 mini::SVector<ScalarType, kRows>
const AP = P - A;
312 ScalarType
const d1 = Dot(AB, AP);
313 ScalarType
const d2 = Dot(AC, AP);
314 if (d1 <= ScalarType(0) and d2 <= ScalarType(0))
316 return mini::Unit<ScalarType, 3>(0);
320 mini::SVector<ScalarType, kRows>
const BP = P - B;
321 ScalarType
const d3 = Dot(AB, BP);
322 ScalarType
const d4 = Dot(AC, BP);
323 if (d3 >= ScalarType(0) and d4 <= d3)
325 return mini::Unit<ScalarType, 3>(1);
329 ScalarType
const vc = d1 * d4 - d3 * d2;
330 if (vc <= ScalarType(0) and d1 >= ScalarType(0) and d3 <= ScalarType(0))
332 ScalarType
const v = d1 / (d1 - d3);
333 return mini::SVector<ScalarType, 3>{
340 mini::SVector<ScalarType, kRows>
const CP = P - C;
341 ScalarType
const d5 = Dot(AB, CP);
342 ScalarType
const d6 = Dot(AC, CP);
343 if (d6 >= ScalarType(0) and d5 <= d6)
345 return mini::Unit<ScalarType, 3>(2);
349 ScalarType
const vb = d5 * d2 - d1 * d6;
350 if (vb <= ScalarType(0) and d2 >= ScalarType(0) and d6 <= ScalarType(0))
352 ScalarType
const w = d2 / (d2 - d6);
353 return mini::SVector<ScalarType, 3>{
359 ScalarType
const va = d3 * d6 - d5 * d4;
360 if (va <= ScalarType(0) and (d4 - d3) >= ScalarType(0) and (d5 - d6) >= ScalarType(0))
362 ScalarType
const w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
363 return mini::SVector<ScalarType, 3>{
369 ScalarType
const denom = ScalarType(1) / (va + vb + vc);
370 ScalarType
const v = vb * denom;
371 ScalarType
const w = vc * denom;
372 return mini::SVector<ScalarType, 3>{
373 ScalarType(1) - v - w,
379 mini::CMatrix TMatrixP,
380 mini::CMatrix TMatrixA,
381 mini::CMatrix TMatrixB,
382 mini::CMatrix TMatrixC>
384PointInTriangle(TMatrixP
const& P, TMatrixA
const& A, TMatrixB
const& B, TMatrixC
const& C)
385 -> mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>
388 return A * uvw(0) + B * uvw(1) + C * uvw(2);
392 mini::CMatrix TMatrixP,
393 mini::CMatrix TMatrixA,
394 mini::CMatrix TMatrixB,
395 mini::CMatrix TMatrixC,
396 mini::CMatrix TMatrixD>
402 TMatrixD
const& D) -> mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>
404 using ScalarType =
typename TMatrixP::ScalarType;
405 auto constexpr kRows = TMatrixP::kRows;
406 auto constexpr kDims = 3;
407 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
414 mini::SVector<ScalarType, kDims> X = P;
415 ScalarType d2min = std::numeric_limits<ScalarType>::max();
417 auto const PointOutsidePlane = [](
auto const& p,
auto const& a,
auto const& b,
auto const& c) {
418 ScalarType
const d = Dot(p - a, Cross(b - a, c - a));
419 return d > ScalarType(0);
421 auto const TestFace = [&](
auto const& a,
auto const& b,
auto const& c) {
423 if (PointOutsidePlane(P, a, b, c))
426 ScalarType
const d2 = SquaredNorm(Q - P);
443 mini::CMatrix TMatrixP1,
444 mini::CMatrix TMatrixQ1,
445 mini::CMatrix TMatrixP2,
446 mini::CMatrix TMatrixQ2,
453 TScalar eps) -> mini::SVector<TScalar, 2>
455 auto constexpr kDims = TMatrixP1::kRows;
456 mini::SVector<TScalar, kDims>
const d1 = Q1 - P1;
457 mini::SVector<TScalar, kDims>
const d2 = Q2 - P2;
458 mini::SVector<TScalar, kDims>
const P2P1 = P1 - P2;
459 TScalar
const d1sq = SquaredNorm(d1);
460 TScalar
const d2sq = SquaredNorm(d2);
461 TScalar
const d1d2 = Dot(d1, d2);
462 TScalar
const similarity = d1sq * d2sq - d1d2 * d1d2;
463 bool const bIsLine1Degenerate = d1sq <= eps;
464 bool const bIsLine2Degenerate = d2sq <= eps;
465 bool const bAreParallel = (-eps <= similarity) and (similarity <= eps);
466 TScalar alpha{0}, beta{0};
467 if (not(bIsLine1Degenerate and bIsLine2Degenerate))
469 if (bIsLine1Degenerate)
471 beta = Dot(P2P1, d2) / d2sq;
473 else if (bIsLine2Degenerate)
475 alpha = -Dot(P2P1, d1) / d1sq;
479 if (not bAreParallel)
480 alpha = Dot(P2P1, d2 * d1d2 - d2sq * d1) / similarity;
481 beta = Dot(P2P1 + alpha * d1, d2) / d2sq;
484 return mini::SVector<TScalar, 2>{alpha, beta};
This file includes all the mini linear algebra headers.
constexpr void ForRange(F &&f)
Compile-time for loop over a range of values.
Definition ConstexprFor.h:55
This namespace contains functions to answer closest point queries.
Definition ClosestPointQueries.h:25
PBAT_HOST_DEVICE auto PointOnAxisAlignedBoundingBox(TMatrixX const &X, TMatrixL const &L, TMatrixU const &U) -> mini::SVector< typename TMatrixX::ScalarType, TMatrixX::kRows >
Obtain the point on the axis-aligned bounding box (AABB) defined by the lower and upper corners close...
Definition ClosestPointQueries.h:280
PBAT_HOST_DEVICE auto PointOnLineSegment(TMatrixX const &X, TMatrixP const &P, TMatrixQ const &Q) -> mini::SVector< typename TMatrixX::ScalarType, TMatrixX::kRows >
Obtain the point on the line segment PQ closest to the point X.
Definition ClosestPointQueries.h:260
PBAT_HOST_DEVICE auto UvwPointInTriangle(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> mini::SVector< typename TMatrixP::ScalarType, 3 >
Obtain the point on the triangle ABC closest to the point P in barycentric coordinates.
Definition ClosestPointQueries.h:299
PBAT_HOST_DEVICE auto Lines(TMatrixP1 const &P1, TMatrixQ1 const &Q1, TMatrixP2 const &P2, TMatrixQ2 const &Q2, TScalar eps=std::numeric_limits< TScalar >::min()) -> mini::SVector< TScalar, 2 >
Find closest points on two lines defined by points P1, Q1 and P2, Q2.
Definition ClosestPointQueries.h:448
PBAT_HOST_DEVICE auto PointInTetrahedron(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixD const &D) -> mini::SVector< typename TMatrixP::ScalarType, TMatrixP::kRows >
Obtain the point in the tetrahedron ABCD closest to the point P. The order of ABCD must be such that ...
Definition ClosestPointQueries.h:397
PBAT_HOST_DEVICE auto PointOnPlane(TMatrixX const &X, TMatrixP const &P, TMatrixN const &n) -> mini::SVector< typename TMatrixX::ScalarType, TMatrixX::kRows >
Obtain the point on the plane (P,n) closest to the point X.
Definition ClosestPointQueries.h:242
PBAT_HOST_DEVICE auto PointInTriangle(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> mini::SVector< typename TMatrixP::ScalarType, TMatrixP::kRows >
Obtain the point on the triangle ABC closest to the point P.
Definition ClosestPointQueries.h:384
Geometric queries, quantities and data structures.
Definition AabbKdTreeHierarchy.h:23
Mini linear algebra related functionality.
Definition Assign.h:12
The main namespace of the library.
Definition Aliases.h:15