11#ifndef PBAT_GEOMETRY_INTERSECTIONQUERIES_H
12#define PBAT_GEOMETRY_INTERSECTIONQUERIES_H
15#include "pbat/HostDevice.h"
43template <mini::CMatrix TMatrixAP, mini::CMatrix TMatrixAB, mini::CMatrix TMatrixAC>
49 -> mini::SMatrix<typename TMatrixAP::ScalarType, 3, 1>
51 using ScalarType =
typename TMatrixAP::ScalarType;
53 ScalarType
const d00 = Dot(AB, AB);
54 ScalarType
const d01 = Dot(AB, AC);
55 ScalarType
const d11 = Dot(AC, AC);
56 ScalarType
const d20 = Dot(AP, AB);
57 ScalarType
const d21 = Dot(AP, AC);
58 ScalarType
const denom = d00 * d11 - d01 * d01;
59 ScalarType
const v = (d11 * d20 - d01 * d21) / denom;
60 ScalarType
const w = (d00 * d21 - d01 * d20) / denom;
61 ScalarType
const u = ScalarType(1) - v - w;
62 SMatrix<ScalarType, 3, 1> uvw{};
85 mini::CMatrix TMatrixP,
86 mini::CMatrix TMatrixA,
87 mini::CMatrix TMatrixB,
88 mini::CMatrix TMatrixC>
93 TMatrixC
const& C) -> mini::SVector<typename TMatrixP::ScalarType, 3>
95 using ScalarType =
typename TMatrixP::ScalarType;
96 auto constexpr kRows = TMatrixP::kRows;
97 mini::SVector<ScalarType, kRows>
const AP = P - A;
98 mini::SVector<ScalarType, kRows>
const AB = B - A;
99 mini::SVector<ScalarType, kRows>
const AC = C - A;
116 mini::CMatrix TMatrixL1,
117 mini::CMatrix TMatrixU1,
118 mini::CMatrix TMatrixL2,
119 mini::CMatrix TMatrixU2>
124 TMatrixU2
const& U2) -> mini::SMatrix<typename TMatrixL1::ScalarType, TMatrixL1::Rows, 2>;
137template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixC>
142 typename TMatrixC::ScalarType R)
143 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>;
162 mini::CMatrix TMatrixP,
163 mini::CMatrix TMatrixQ,
164 mini::CMatrix TMatrixA,
165 mini::CMatrix TMatrixB,
166 mini::CMatrix TMatrixC>
173 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>;
188template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixN>
193 typename TMatrixN::ScalarType d)
194 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>;
213 mini::CMatrix TMatrixP,
214 mini::CMatrix TMatrixQ,
215 mini::CMatrix TMatrixA,
216 mini::CMatrix TMatrixB,
217 mini::CMatrix TMatrixC>
223 TMatrixC
const& C) -> std::optional<mini::SVector<typename TMatrixP::ScalarType, 3>>;
244 mini::CMatrix TMatrixP,
245 mini::CMatrix TMatrixQ,
246 mini::CMatrix TMatrixA,
247 mini::CMatrix TMatrixB,
248 mini::CMatrix TMatrixC>
254 TMatrixC
const& C) -> std::optional<mini::SVector<typename TMatrixP::ScalarType, 4>>;
276 mini::CMatrix TMatrixA1,
277 mini::CMatrix TMatrixB1,
278 mini::CMatrix TMatrixC1,
279 mini::CMatrix TMatrixA2,
280 mini::CMatrix TMatrixB2,
281 mini::CMatrix TMatrixC2>
289 -> std::array<std::optional<mini::SVector<typename TMatrixA1::ScalarType, 3>>, 6u>;
292 mini::CMatrix TMatrixL1,
293 mini::CMatrix TMatrixU1,
294 mini::CMatrix TMatrixL2,
295 mini::CMatrix TMatrixU2>
300 TMatrixU2
const& U2) -> mini::SMatrix<typename TMatrixL1::ScalarType, TMatrixL1::Rows, 2>
302 using ScalarType =
typename TMatrixL1::ScalarType;
303 mini::SMatrix<ScalarType, TMatrixL1::Rows, 2> LU;
304 LU.Col(0) = Max(L1, L2);
305 LU.Col(1) = Min(U1, U2);
309template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixC>
314 typename TMatrixC::ScalarType R)
315 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>
317 using ScalarType =
typename TMatrixP::ScalarType;
318 auto constexpr kRows = TMatrixP::kRows;
319 mini::SVector<ScalarType, kRows>
const PQ = (Q - P);
320 ScalarType
const len = Norm(PQ);
321 mini::SVector<ScalarType, kRows>
const d = PQ / len;
322 mini::SVector<ScalarType, kRows>
const m = P - C;
323 ScalarType
const b = Dot(m, d);
324 ScalarType
const c = Dot(m, m) - (R * R);
326 if (c > ScalarType(0) and b > ScalarType(0))
328 ScalarType
const discr = b * b - c;
330 if (discr < ScalarType(0))
334 ScalarType t = -b - sqrt(discr);
336 if (t < ScalarType(0))
342 mini::SVector<ScalarType, kRows> I = P + t * d;
347 mini::CMatrix TMatrixP,
348 mini::CMatrix TMatrixQ,
349 mini::CMatrix TMatrixA,
350 mini::CMatrix TMatrixB,
351 mini::CMatrix TMatrixC>
358 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>
360 using ScalarType =
typename TMatrixP::ScalarType;
361 auto constexpr kRows = TMatrixP::kRows;
362 auto constexpr kDims = 3;
363 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
366 mini::SVector<ScalarType, kRows>
const n = Cross(B - A, C - A);
367 ScalarType
const d = Dot(n, A);
371template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixN>
376 typename TMatrixN::ScalarType d)
377 -> std::optional<mini::SVector<typename TMatrixP::ScalarType, TMatrixP::kRows>>
379 using ScalarType =
typename TMatrixP::ScalarType;
380 auto constexpr kRows = TMatrixP::kRows;
382 mini::SVector<ScalarType, kRows>
const PQ = Q - P;
383 ScalarType
const t = (d - Dot(n, P)) / Dot(n, PQ);
385 if (t >= ScalarType(0) and t <= ScalarType(1))
395 mini::CMatrix TMatrixP,
396 mini::CMatrix TMatrixQ,
397 mini::CMatrix TMatrixA,
398 mini::CMatrix TMatrixB,
399 mini::CMatrix TMatrixC>
405 TMatrixC
const& C) -> std::optional<mini::SVector<typename TMatrixP::ScalarType, 3>>
407 using ScalarType =
typename TMatrixP::ScalarType;
408 auto constexpr kRows = TMatrixP::kRows;
409 auto constexpr kDims = 3;
410 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
414 mini::SVector<ScalarType, kDims>
const PQ = Q - P;
415 mini::SVector<ScalarType, kDims>
const PA = A - P;
416 mini::SVector<ScalarType, kDims>
const PB = B - P;
417 mini::SVector<ScalarType, kDims>
const PC = C - P;
421 mini::SVector<ScalarType, kDims>
const m = Cross(PQ, PC);
422 mini::SVector<ScalarType, kDims> uvw = mini::Zeros<ScalarType, kDims, 1>();
424 ScalarType& u = uvw(0);
425 ScalarType& v = uvw(1);
426 ScalarType& w = uvw(2);
430 auto const SameSign = [](ScalarType a, ScalarType b) ->
bool {
431 return signbit(a) == signbit(b);
433 if (not SameSign(u, v))
435 w = Dot(PQ, Cross(PB, PA));
436 if (not SameSign(u, w))
439 ScalarType
constexpr eps = 1e-15;
440 ScalarType
const uvwSum = u + v + w;
441 bool const bIsLineInPlaneOfTriangle = abs(uvwSum) < eps;
442 if (bIsLineInPlaneOfTriangle)
455 ScalarType
const denom = ScalarType(1) / (uvwSum);
463 mini::CMatrix TMatrixP,
464 mini::CMatrix TMatrixQ,
465 mini::CMatrix TMatrixA,
466 mini::CMatrix TMatrixB,
467 mini::CMatrix TMatrixC>
473 TMatrixC
const& C) -> std::optional<mini::SVector<typename TMatrixP::ScalarType, 4>>
475 using ScalarType =
typename TMatrixP::ScalarType;
476 auto constexpr kRows = TMatrixP::kRows;
477 auto constexpr kDims = 3;
478 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
479 mini::SVector<ScalarType, kDims>
const AB = B - A;
480 mini::SVector<ScalarType, kDims>
const AC = C - A;
481 mini::SVector<ScalarType, kDims>
const PQ = Q - P;
482 mini::SVector<ScalarType, kDims>
const n = Cross(AB, AC);
484 ScalarType
constexpr eps =
static_cast<ScalarType
>(1e-15);
485 ScalarType
const d = Dot(PQ, n);
487 bool const bIsSegmentParallelToTriangle = abs(d) < eps;
488 if (bIsSegmentParallelToTriangle)
492 ScalarType
const t = Dot(n, A - P) / d;
493 if (t < ScalarType(0) or t > ScalarType(1))
496 mini::SVector<ScalarType, kDims>
const I = P + t * PQ;
497 mini::SVector<ScalarType, 4> uvwt;
498 auto uvw = uvwt.template Slice<3, 1>(1, 0);
500 bool const bIsInsideTriangle = All((uvw >= ScalarType(0)) and (uvw <= ScalarType(1)));
501 if (not bIsInsideTriangle)
508 mini::CMatrix TMatrixA1,
509 mini::CMatrix TMatrixB1,
510 mini::CMatrix TMatrixC1,
511 mini::CMatrix TMatrixA2,
512 mini::CMatrix TMatrixB2,
513 mini::CMatrix TMatrixC2>
521 -> std::array<std::optional<mini::SVector<typename TMatrixA1::ScalarType, 3>>, 6u>
523 using ScalarType =
typename TMatrixA1::ScalarType;
524 auto constexpr kRows = TMatrixA1::kRows;
525 auto constexpr kDims = 3;
526 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
529 mini::SVector<ScalarType, kDims>
const n1 = Normalized(Cross(B1 - A1, C1 - A1));
530 mini::SVector<ScalarType, kDims>
const n2 = Normalized(Cross(B2 - A2, C2 - A2));
531 ScalarType
constexpr eps = 1e-15;
532 bool const bAreTrianglesCoplanar = (ScalarType(1) - abs(Dot(n1, n2))) < eps;
533 if (bAreTrianglesCoplanar)
547 std::array<std::optional<mini::SVector<ScalarType, 3>>, 6u> intersections;
549 #if defined(CUDART_VERSION)
550 #pragma nv_diag_suppress 174
553 intersections[0] = uvwt->template Slice<3, 1>(1, 0);
556 intersections[1] = uvwt->template Slice<3, 1>(1, 0);
559 intersections[2] = uvwt->template Slice<3, 1>(1, 0);
562 intersections[3] = uvwt->template Slice<3, 1>(1, 0);
565 intersections[4] = uvwt->template Slice<3, 1>(1, 0);
568 intersections[5] = uvwt->template Slice<3, 1>(1, 0);
569 #if defined(CUDART_VERSION)
570 #pragma nv_diag_default 174
572 return intersections;
This file includes all the mini linear algebra headers.
This namespace contains functions to answer intersection queries.
Definition IntersectionQueries.h:27
PBAT_HOST_DEVICE auto LineSegmentPlane3D(TMatrixP const &P, TMatrixQ const &Q, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> std::optional< mini::SVector< typename TMatrixP::ScalarType, TMatrixP::kRows > >
Computes the intersection point, if any, between a line including points P,Q and the plane spanned by...
Definition IntersectionQueries.h:352
PBAT_HOST_DEVICE auto UvwLineSegmentTriangle3D(TMatrixP const &P, TMatrixQ const &Q, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> std::optional< mini::SVector< typename TMatrixP::ScalarType, 4 > >
Computes the intersection point, if any, between a line segment delimited by points P,...
Definition IntersectionQueries.h:468
PBAT_HOST_DEVICE auto LineSegmentSphere(TMatrixP const &P, TMatrixQ const &Q, TMatrixC const &C, typename TMatrixC::ScalarType R) -> std::optional< mini::SVector< typename TMatrixP::ScalarType, TMatrixP::kRows > >
Computes the intersection point, if any, between a line segment PQ and a sphere (C,...
Definition IntersectionQueries.h:310
PBAT_HOST_DEVICE auto UvwLineTriangle3D(TMatrixP const &P, TMatrixQ const &Q, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C) -> std::optional< mini::SVector< typename TMatrixP::ScalarType, 3 > >
Computes the intersection point, if any, between a line including points P,Q and a triangle ABC,...
Definition IntersectionQueries.h:400
PBAT_HOST_DEVICE auto AxisAlignedBoundingBoxes(TMatrixL1 const &L1, TMatrixU1 const &U1, TMatrixL2 const &L2, TMatrixU2 const &U2) -> mini::SMatrix< typename TMatrixL1::ScalarType, TMatrixL1::Rows, 2 >
Computes the intersection volume between 2 axis aligned bounding boxes.
Definition IntersectionQueries.h:296
PBAT_HOST_DEVICE auto UvwTriangles3D(TMatrixA1 const &A1, TMatrixB1 const &B1, TMatrixC1 const &C1, TMatrixA2 const &A2, TMatrixB2 const &B2, TMatrixC2 const &C2) -> std::array< std::optional< mini::SVector< typename TMatrixA1::ScalarType, 3 > >, 6u >
Computes intersection points between 3 edges (as line segments) of triangle A1B1C1 and triangle A2B2C...
Definition IntersectionQueries.h:514
PBAT_HOST_DEVICE auto TriangleBarycentricCoordinates(TMatrixAP const &AP, TMatrixAB const &AB, TMatrixAC const &AC) -> mini::SMatrix< typename TMatrixAP::ScalarType, 3, 1 >
Computes the barycentric coordinates of point P with respect to the triangle spanned by vertices A,...
Definition IntersectionQueries.h:45
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