11#ifndef PBAT_GEOMETRY_OVERLAPQUERIES_H
12#define PBAT_GEOMETRY_OVERLAPQUERIES_H
16#include "pbat/HostDevice.h"
41template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
58 mini::CMatrix TMatrixP,
59 mini::CMatrix TMatrixA,
60 mini::CMatrix TMatrixB,
61 mini::CMatrix TMatrixC>
63PointTriangle(TMatrixP
const& P, TMatrixA
const& A, TMatrixB
const& B, TMatrixC
const& C);
80 mini::CMatrix TMatrixP,
81 mini::CMatrix TMatrixA,
82 mini::CMatrix TMatrixB,
83 mini::CMatrix TMatrixC,
84 mini::CMatrix TMatrixD>
102template <mini::CMatrix TMatrixC1, mini::CMatrix TMatrixC2>
105 typename TMatrixC1::ScalarType R1,
107 typename TMatrixC2::ScalarType R2);
123 mini::CMatrix TMatrixL1,
124 mini::CMatrix TMatrixU1,
125 mini::CMatrix TMatrixL2,
126 mini::CMatrix TMatrixU2>
131 TMatrixU2
const& U2);
144template <mini::CMatrix TMatrixC, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
147 typename TMatrixC::ScalarType R,
162template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixC>
167 typename TMatrixC::ScalarType R);
182 mini::CMatrix TMatrixP,
183 mini::CMatrix TMatrixQ,
184 mini::CMatrix TMatrixL,
185 mini::CMatrix TMatrixU>
207 mini::CMatrix TMatrixP,
208 mini::CMatrix TMatrixQ,
209 mini::CMatrix TMatrixA,
210 mini::CMatrix TMatrixB,
211 mini::CMatrix TMatrixC>
244 mini::CMatrix TMatrixP,
245 mini::CMatrix TMatrixQ,
246 mini::CMatrix TMatrixA1,
247 mini::CMatrix TMatrixB1,
248 mini::CMatrix TMatrixC1,
249 mini::CMatrix TMatrixA2,
250 mini::CMatrix TMatrixB2,
251 mini::CMatrix TMatrixC2>
260 TMatrixC2
const& C2);
275 mini::CMatrix TMatrixP,
276 mini::CMatrix TMatrixN,
277 mini::CMatrix TMatrixL,
278 mini::CMatrix TMatrixU>
300 mini::CMatrix TMatrixA,
301 mini::CMatrix TMatrixB,
302 mini::CMatrix TMatrixC,
303 mini::CMatrix TMatrixL,
304 mini::CMatrix TMatrixU>
330 mini::CMatrix TMatrixA,
331 mini::CMatrix TMatrixB,
332 mini::CMatrix TMatrixC,
333 mini::CMatrix TMatrixD,
334 mini::CMatrix TMatrixL,
335 mini::CMatrix TMatrixU>
361 mini::CMatrix TMatrixA1,
362 mini::CMatrix TMatrixB1,
363 mini::CMatrix TMatrixC1,
364 mini::CMatrix TMatrixA2,
365 mini::CMatrix TMatrixB2,
366 mini::CMatrix TMatrixC2>
373 TMatrixC2
const& C2);
392 mini::CMatrix TMatrixA1,
393 mini::CMatrix TMatrixB1,
394 mini::CMatrix TMatrixC1,
395 mini::CMatrix TMatrixA2,
396 mini::CMatrix TMatrixB2,
397 mini::CMatrix TMatrixC2>
404 TMatrixC2
const& C2);
425 mini::CMatrix TMatrixA,
426 mini::CMatrix TMatrixB,
427 mini::CMatrix TMatrixC,
428 mini::CMatrix TMatrixI,
429 mini::CMatrix TMatrixJ,
430 mini::CMatrix TMatrixK,
431 mini::CMatrix TMatrixL>
462 mini::CMatrix TMatrixA1,
463 mini::CMatrix TMatrixB1,
464 mini::CMatrix TMatrixC1,
465 mini::CMatrix TMatrixD1,
466 mini::CMatrix TMatrixA2,
467 mini::CMatrix TMatrixB2,
468 mini::CMatrix TMatrixC2,
469 mini::CMatrix TMatrixD2>
478 TMatrixD2
const& D2);
494 mini::CMatrix TMatrixA,
495 mini::CMatrix TMatrixB,
496 mini::CMatrix TMatrixC,
497 mini::CMatrix TMatrixSC>
503 typename TMatrixSC::ScalarType R);
521 mini::CMatrix TMatrixA,
522 mini::CMatrix TMatrixB,
523 mini::CMatrix TMatrixC,
524 mini::CMatrix TMatrixD,
525 mini::CMatrix TMatrixSC>
532 typename TMatrixSC::ScalarType R);
534template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
538 bool bIsOutsideBox = Any((P < L) or (P > U));
539 return not bIsOutsideBox;
543 mini::CMatrix TMatrixP,
544 mini::CMatrix TMatrixA,
545 mini::CMatrix TMatrixB,
546 mini::CMatrix TMatrixC>
548PointTriangle(TMatrixP
const& P, TMatrixA
const& A, TMatrixB
const& B, TMatrixC
const& C)
551 using ScalarType =
typename TMatrixP::ScalarType;
552 bool bIsInsideTriangle = All((uvw >= ScalarType(0)) and (uvw <= ScalarType(1)));
553 return bIsInsideTriangle;
557 mini::CMatrix TMatrixP,
558 mini::CMatrix TMatrixA,
559 mini::CMatrix TMatrixB,
560 mini::CMatrix TMatrixC,
561 mini::CMatrix TMatrixD>
569 using ScalarType =
typename TMatrixP::ScalarType;
570 auto constexpr kRows = TMatrixP::kRows;
571 auto constexpr kDims = 3;
572 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
574 auto const PointOutsidePlane = [](
auto const& p,
auto const& a,
auto const& b,
auto const& c) {
575 ScalarType
const d = Dot(p - a, Cross(b - a, c - a));
576 return d > ScalarType(0);
578 if (PointOutsidePlane(P, A, B, D))
580 if (PointOutsidePlane(P, B, C, D))
582 if (PointOutsidePlane(P, C, A, D))
584 if (PointOutsidePlane(P, A, C, B))
589template <mini::CMatrix TMatrixC1, mini::CMatrix TMatrixC2>
592 typename TMatrixC1::ScalarType R1,
594 typename TMatrixC2::ScalarType R2)
596 using ScalarType =
typename TMatrixC1::ScalarType;
597 ScalarType
const upper = R1 + R2;
598 ScalarType
const upper2 = upper * upper;
599 ScalarType
const d2 = SquaredNorm(C1 - C2);
604 mini::CMatrix TMatrixL1,
605 mini::CMatrix TMatrixU1,
606 mini::CMatrix TMatrixL2,
607 mini::CMatrix TMatrixU2>
614 bool bOverlap = All((L1 <= U2) and (L2 <= U1));
618template <mini::CMatrix TMatrixC, mini::CMatrix TMatrixL, mini::CMatrix TMatrixU>
621 typename TMatrixC::ScalarType R,
626 auto const d2 = SquaredNorm(C - Xaabb);
627 auto const r2 = R * R;
631template <mini::CMatrix TMatrixP, mini::CMatrix TMatrixQ, mini::CMatrix TMatrixC>
636 typename TMatrixC::ScalarType R)
638 using ScalarType =
typename TMatrixC::ScalarType;
639 auto constexpr kRows = TMatrixP::kRows;
640 mini::SVector<ScalarType, kRows>
const d = Q - P;
641 mini::SVector<ScalarType, kRows>
const m = P - C;
642 ScalarType
const b = Dot(m, d);
643 ScalarType
const c = Dot(m, m) - R * R;
645 if (c > ScalarType(0) and b > ScalarType(0))
647 ScalarType
const discr = b * b - c;
649 if (discr < ScalarType(0))
653 ScalarType t = -b - sqrt(discr);
654 if (t > ScalarType(1))
660 mini::CMatrix TMatrixP,
661 mini::CMatrix TMatrixQ,
662 mini::CMatrix TMatrixL,
663 mini::CMatrix TMatrixU>
670 using ScalarType =
typename TMatrixP::ScalarType;
671 auto constexpr kRows = TMatrixP::kRows;
673 mini::SVector<ScalarType, kRows>
const c = ScalarType(0.5) * (L + U);
674 mini::SVector<ScalarType, kRows>
const e = U - L;
675 mini::SVector<ScalarType, kRows>
const d = Q - P;
676 mini::SVector<ScalarType, kRows> m = P + Q - L - U;
681 auto constexpr kDims = c.Rows();
682 bool bAxesSeparating = Any(Abs(m) > (e + Abs(d)));
688 ScalarType
constexpr eps{1e-15};
690 auto i = (kDim + 1) % kDims;
691 auto j = (kDim + 2) % kDims;
693 bAxesSeparating &= abs(m(i) * d(i) - m(i) * d(i)) > e(i) * ad(j) + e(j) * ad(i);
696 return not bAxesSeparating;
700 mini::CMatrix TMatrixP,
701 mini::CMatrix TMatrixQ,
702 mini::CMatrix TMatrixA,
703 mini::CMatrix TMatrixB,
704 mini::CMatrix TMatrixC>
716 mini::CMatrix TMatrixP,
717 mini::CMatrix TMatrixQ,
718 mini::CMatrix TMatrixA1,
719 mini::CMatrix TMatrixB1,
720 mini::CMatrix TMatrixC1,
721 mini::CMatrix TMatrixA2,
722 mini::CMatrix TMatrixB2,
723 mini::CMatrix TMatrixC2>
741 using ScalarType =
typename TMatrixP::ScalarType;
742 static auto constexpr kDims = 3;
744 auto const fSignWrtPlane = [=](
auto const& X,
auto const& A,
auto const& B,
auto const& C) {
745 mini::SVector<ScalarType, kDims>
const n = Cross(B - A, C - A);
746 auto const d = Dot(X - A, n);
751 bool const bCoplanar = fSignWrtPlane(A1, A2, B2, C2) == ScalarType(0) and
752 fSignWrtPlane(B1, A2, B2, C2) == ScalarType(0) and
753 fSignWrtPlane(C1, A2, B2, C2) == ScalarType(0);
769 mini::SVector<ScalarType, 10> sgn{};
770 sgn(0) = fSignWrtPlane(P, A1, B1, C1);
771 sgn(1) = fSignWrtPlane(P, A2, C2, B2);
772 sgn(2) = fSignWrtPlane(P, A1, A2, B2);
773 sgn(3) = fSignWrtPlane(P, B1, B2, C2);
774 sgn(4) = fSignWrtPlane(P, C1, C2, A2);
775 sgn(5) = fSignWrtPlane(Q, A1, B1, C1);
776 sgn(6) = fSignWrtPlane(Q, A2, C2, B2);
777 sgn(7) = fSignWrtPlane(Q, A1, A2, B2);
778 sgn(8) = fSignWrtPlane(Q, B1, B2, C2);
779 sgn(9) = fSignWrtPlane(Q, C1, C2, A2);
780 bool const bIsPqInside = All(sgn <= ScalarType(0)) or All(sgn >= ScalarType(0));
799 mini::CMatrix TMatrixP,
800 mini::CMatrix TMatrixN,
801 mini::CMatrix TMatrixL,
802 mini::CMatrix TMatrixU>
809 using ScalarType =
typename TMatrixP::ScalarType;
810 auto constexpr kRows = TMatrixP::kRows;
811 mini::SVector<ScalarType, kRows>
const C = ScalarType(0.5) * (L + U);
812 mini::SVector<ScalarType, kRows>
const e = U - C;
814 ScalarType
const r = Dot(e, Abs(n));
816 ScalarType
const s = Dot(n, C - P);
823 mini::CMatrix TMatrixA,
824 mini::CMatrix TMatrixB,
825 mini::CMatrix TMatrixC,
826 mini::CMatrix TMatrixL,
827 mini::CMatrix TMatrixU>
839 using ScalarType =
typename TMatrixA::ScalarType;
840 auto constexpr kRows = TMatrixL::kRows;
841 auto constexpr kDims = 3;
842 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
844 mini::SVector<ScalarType, kDims>
const O = ScalarType(0.5) * (L + U);
845 mini::SVector<ScalarType, kDims>
const e = U - O;
846 mini::SVector<ScalarType, kDims>
const AO = A - O;
847 mini::SVector<ScalarType, kDims>
const BO = B - O;
848 mini::SVector<ScalarType, kDims>
const CO = C - O;
858 auto const ProjectTriangle = [&](
auto const& a) -> std::pair<ScalarType, ScalarType> {
859 mini::SVector<ScalarType, 3>
const p{Dot(AO, a), Dot(BO, a), Dot(CO, a)};
860 return make_pair(Min(p), Max(p));
862 auto const ProjectAabb = [&](
auto const& a) -> ScalarType {
863 return Dot(e, Abs(a));
865 auto const AreDisjoint = [](ScalarType ABCprojlow, ScalarType ABCprojup, ScalarType AABBproj) {
866 return (AABBproj < ABCprojlow) or (ABCprojup < -AABBproj);
868 auto const TestAxis = [&ProjectTriangle, &ProjectAabb, &AreDisjoint](
auto const& axis) {
869 auto const [ABCmin, ABCmax] = ProjectTriangle(axis);
870 ScalarType
const r = ProjectAabb(axis);
871 return AreDisjoint(ABCmin, ABCmax, r);
875 auto const IsEdgePairIntersecting = [&TestAxis](
auto const& a,
auto const& b,
auto dim) {
876 ScalarType
constexpr eps = 1e-15;
877 auto const ab = b - a;
879 auto const u = mini::Unit<ScalarType, kDims>(dim);
880 mini::SVector<ScalarType, kDims> axis = Normalized(Cross(ab, u ));
881 bool bAxisIsZero = All(Abs(axis) <= eps);
884 return TestAxis(axis);
889 auto const n = Cross(ab, -a);
891 axis = Normalized(Cross(ab, n));
892 bAxisIsZero = All(Abs(axis) <= eps);
894 return TestAxis(axis);
906 for (
auto dim = 0; dim < kDims; ++dim)
908 if (IsEdgePairIntersecting(AO, BO, dim))
910 if (IsEdgePairIntersecting(BO, CO, dim))
912 if (IsEdgePairIntersecting(CO, AO, dim))
917 for (
auto dim = 0; dim < kDims; ++dim)
919 ScalarType
const ma = max({AO(dim), BO(dim), CO(dim)});
920 ScalarType
const mi = min({AO(dim), BO(dim), CO(dim)});
921 if (ma < -e(dim) or mi > e(dim))
926 mini::SVector<ScalarType, kDims>
const n = Normalized(Cross(B - A, C - A));
931 mini::CMatrix TMatrixA,
932 mini::CMatrix TMatrixB,
933 mini::CMatrix TMatrixC,
934 mini::CMatrix TMatrixD,
935 mini::CMatrix TMatrixL,
936 mini::CMatrix TMatrixU>
945 using ScalarType =
typename TMatrixA::ScalarType;
946 auto constexpr kRows = TMatrixL::kRows;
947 auto constexpr kDims = 3;
948 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
951 mini::SVector<ScalarType, kDims>
const O = ScalarType(0.5) * (L + U);
952 mini::SVector<ScalarType, kDims>
const e = U - O;
953 mini::SVector<ScalarType, kDims>
const AO = A - O;
954 mini::SVector<ScalarType, kDims>
const BO = B - O;
955 mini::SVector<ScalarType, kDims>
const CO = C - O;
956 mini::SVector<ScalarType, kDims>
const DO = D - O;
966 auto const ProjectTetrahedron = [&](
auto const& a) -> std::pair<ScalarType, ScalarType> {
967 mini::SVector<ScalarType, 4>
const p{Dot(AO, a), Dot(BO, a), Dot(CO, a), Dot(DO, a)};
968 return make_pair(Min(p), Max(p));
970 auto const ProjectAabb = [&](
auto const& a) -> ScalarType {
971 return Dot(e, Abs(a));
973 auto const AreDisjoint = [](ScalarType low, ScalarType up, ScalarType r) {
974 return (up < -r) or (r < low);
976 auto const TestAxis = [&ProjectTetrahedron, &ProjectAabb, &AreDisjoint](
auto const& axis) {
977 auto const [low, up] = ProjectTetrahedron(axis);
978 ScalarType
const r = ProjectAabb(axis);
979 return AreDisjoint(low, up, r);
983 auto const IsEdgePairIntersecting = [&TestAxis](
auto const& a,
auto const& b,
auto dim) {
984 ScalarType
constexpr eps = 1e-15;
985 auto const ab = b - a;
987 auto const u = mini::Unit<ScalarType, kDims>(dim);
988 mini::SVector<ScalarType, kDims> axis = Normalized(Cross(ab, u ));
989 bool bAxisIsZero = All(Abs(axis) <= eps);
992 return TestAxis(axis);
997 auto const n = Cross(ab, -a);
999 axis = Normalized(Cross(ab, n));
1000 bAxisIsZero = All(Abs(axis) <= eps);
1001 if (not bAxisIsZero)
1002 return TestAxis(axis);
1014 for (
auto dim = 0; dim < kDims; ++dim)
1017 if (IsEdgePairIntersecting(A, B, dim))
1020 if (IsEdgePairIntersecting(B, C, dim))
1023 if (IsEdgePairIntersecting(C, A, dim))
1026 if (IsEdgePairIntersecting(A, D, dim))
1029 if (IsEdgePairIntersecting(B, D, dim))
1032 if (IsEdgePairIntersecting(C, D, dim))
1037 for (
auto dim = 0; dim < kDims; ++dim)
1039 ScalarType
const ma = max({AO(dim), BO(dim), CO(dim), DO(dim)});
1040 ScalarType
const mi = min({AO(dim), BO(dim), CO(dim), DO(dim)});
1041 if (ma < -e(dim) or mi > e(dim))
1047 mini::SVector<ScalarType, kDims> n = Normalized(Cross(B - A, D - A));
1050 n = Normalized(Cross(C - B, D - B));
1053 n = Normalized(Cross(A - C, D - C));
1056 n = Normalized(Cross(C - A, B - A));
1061 mini::CMatrix TMatrixA1,
1062 mini::CMatrix TMatrixB1,
1063 mini::CMatrix TMatrixC1,
1064 mini::CMatrix TMatrixA2,
1065 mini::CMatrix TMatrixB2,
1066 mini::CMatrix TMatrixC2>
1068 TMatrixA1
const& A1,
1069 TMatrixB1
const& B1,
1070 TMatrixC1
const& C1,
1071 TMatrixA2
const& A2,
1072 TMatrixB2
const& B2,
1073 TMatrixC2
const& C2)
1075 using ScalarType =
typename TMatrixA1::ScalarType;
1076 auto constexpr kRows = TMatrixA1::kRows;
1077 auto constexpr kDims = 2;
1078 static_assert(kRows == kDims,
"This overlap test is specialized for 2D");
1080 using namespace std;
1082 auto const ProjectTriangle = [&](
auto const& a,
1085 auto const& axis) -> std::pair<ScalarType, ScalarType> {
1086 mini::SVector<ScalarType, 3>
const p{Dot(a, axis), Dot(b, axis), Dot(c, axis)};
1087 return make_pair(Min(p), Max(p));
1089 auto const AreDisjoint = [](ScalarType low1, ScalarType up1, ScalarType low2, ScalarType up2) {
1090 return (up1 < low2) or (up2 < low1);
1092 auto const TestAxis = [&](
auto const& axis) {
1093 auto const [low1, up1] = ProjectTriangle(A1, B1, C1, axis);
1094 auto const [low2, up2] = ProjectTriangle(A2, B2, C2, axis);
1095 return AreDisjoint(low1, up1, low2, up2);
1097 auto const EdgeNormal = [](
auto e) {
1098 return Normalized(mini::SVector<ScalarType, kDims>{-e(1), e(0)});
1100 if (TestAxis(EdgeNormal(B1 - A1)))
1102 if (TestAxis(EdgeNormal(C1 - B1)))
1104 if (TestAxis(EdgeNormal(A1 - C1)))
1106 if (TestAxis(EdgeNormal(B2 - A2)))
1108 if (TestAxis(EdgeNormal(C2 - B2)))
1110 if (TestAxis(EdgeNormal(A2 - C2)))
1116 mini::CMatrix TMatrixA1,
1117 mini::CMatrix TMatrixB1,
1118 mini::CMatrix TMatrixC1,
1119 mini::CMatrix TMatrixA2,
1120 mini::CMatrix TMatrixB2,
1121 mini::CMatrix TMatrixC2>
1123 TMatrixA1
const& A1,
1124 TMatrixB1
const& B1,
1125 TMatrixC1
const& C1,
1126 TMatrixA2
const& A2,
1127 TMatrixB2
const& B2,
1128 TMatrixC2
const& C2)
1131 for (
auto const& intersection : intersections)
1132 if (intersection.has_value())
1138 mini::CMatrix TMatrixA,
1139 mini::CMatrix TMatrixB,
1140 mini::CMatrix TMatrixC,
1141 mini::CMatrix TMatrixI,
1142 mini::CMatrix TMatrixJ,
1143 mini::CMatrix TMatrixK,
1144 mini::CMatrix TMatrixL>
1154 using ScalarType =
typename TMatrixA::ScalarType;
1162 auto constexpr kRows = TMatrixA::kRows;
1163 auto constexpr kDims = 3;
1164 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
1166 using namespace std;
1168 auto const ProjectTriangle = [&](
auto const& a) -> pair<ScalarType, ScalarType> {
1169 mini::SVector<ScalarType, 3>
const p{Dot(A, a), Dot(B, a), Dot(C, a)};
1170 return make_pair(Min(p), Max(p));
1172 auto const ProjectTetrahedron = [&](
auto const& a) -> pair<ScalarType, ScalarType> {
1173 mini::SVector<ScalarType, 4>
const p{Dot(I, a), Dot(J, a), Dot(K, a), Dot(L, a)};
1174 return make_pair(min({p(0), p(1), p(2), p(3)}), max({p(0), p(1), p(2), p(3)}));
1176 auto const AreDisjoint = [](ScalarType low1, ScalarType up1, ScalarType low2, ScalarType up2) {
1177 return (up1 < low2) or (up2 < low1);
1179 auto const TestAxis = [&ProjectTriangle, &ProjectTetrahedron, &AreDisjoint](
auto const& a) {
1180 auto const [low1, up1] = ProjectTriangle(a);
1181 auto const [low2, up2] = ProjectTetrahedron(a);
1182 return AreDisjoint(low1, up1, low2, up2);
1184 auto const IsEdgePairSeparating =
1185 [&TestAxis](
auto const& a,
auto const& b,
auto const& c,
auto const& d) {
1186 ScalarType
constexpr eps = 1e-15;
1187 auto const ab = b - a;
1188 mini::SVector<ScalarType, kDims> axis = Normalized(Cross(ab, d - c));
1189 bool bAxisIsZero = All(Abs(axis) <= eps);
1190 if (not bAxisIsZero)
1192 return TestAxis(axis);
1197 auto const n = Cross(ab, c - a);
1199 axis = Normalized(Cross(ab, n));
1200 bAxisIsZero = All(Abs(axis) <= eps);
1201 if (not bAxisIsZero)
1202 return TestAxis(axis);
1211 if (IsEdgePairSeparating(A, B, I, J))
1213 if (IsEdgePairSeparating(B, C, I, J))
1215 if (IsEdgePairSeparating(C, A, I, J))
1218 if (IsEdgePairSeparating(A, B, J, K))
1220 if (IsEdgePairSeparating(B, C, J, K))
1222 if (IsEdgePairSeparating(C, A, J, K))
1225 if (IsEdgePairSeparating(A, B, K, I))
1227 if (IsEdgePairSeparating(B, C, K, I))
1229 if (IsEdgePairSeparating(C, A, K, I))
1232 if (IsEdgePairSeparating(A, B, I, L))
1234 if (IsEdgePairSeparating(B, C, I, L))
1236 if (IsEdgePairSeparating(C, A, I, L))
1239 if (IsEdgePairSeparating(A, B, J, L))
1241 if (IsEdgePairSeparating(B, C, J, L))
1243 if (IsEdgePairSeparating(C, A, J, L))
1246 if (IsEdgePairSeparating(A, B, K, L))
1248 if (IsEdgePairSeparating(B, C, K, L))
1250 if (IsEdgePairSeparating(C, A, K, L))
1254 mini::SVector<ScalarType, kDims>
const IJ = J - I;
1255 mini::SVector<ScalarType, kDims>
const JK = K - J;
1256 mini::SVector<ScalarType, kDims>
const KI = I - K;
1257 mini::SVector<ScalarType, kDims>
const IL = L - I;
1258 mini::SVector<ScalarType, kDims>
const JL = L - J;
1259 mini::SVector<ScalarType, kDims>
const KL = L - K;
1260 mini::SVector<ScalarType, kDims> n = Normalized(Cross(IJ, IL));
1263 n = Normalized(Cross(JK, JL));
1266 n = Normalized(Cross(KI, KL));
1269 mini::SVector<ScalarType, kDims>
const IK = K - I;
1270 n = Normalized(Cross(IK, IJ));
1275 n = Normalized(Cross(B - A, C - A));
1276 return not TestAxis(n);
1280 mini::CMatrix TMatrixA1,
1281 mini::CMatrix TMatrixB1,
1282 mini::CMatrix TMatrixC1,
1283 mini::CMatrix TMatrixD1,
1284 mini::CMatrix TMatrixA2,
1285 mini::CMatrix TMatrixB2,
1286 mini::CMatrix TMatrixC2,
1287 mini::CMatrix TMatrixD2>
1289 TMatrixA1
const& A1,
1290 TMatrixB1
const& B1,
1291 TMatrixC1
const& C1,
1292 TMatrixD1
const& D1,
1293 TMatrixA2
const& A2,
1294 TMatrixB2
const& B2,
1295 TMatrixC2
const& C2,
1296 TMatrixD2
const& D2)
1298 using ScalarType =
typename TMatrixA1::ScalarType;
1305 auto constexpr kRows = TMatrixA1::kRows;
1306 auto constexpr kDims = 3;
1307 static_assert(kRows == kDims,
"This overlap test is specialized for 3D");
1309 using namespace std;
1310 auto const ProjectTetrahedron1 = [&](
auto const& a) -> pair<ScalarType, ScalarType> {
1311 mini::SVector<ScalarType, 4>
const p{Dot(A1, a), Dot(B1, a), Dot(C1, a), Dot(D1, a)};
1312 return make_pair(Min(p), Max(p));
1314 auto const ProjectTetrahedron2 = [&](
auto const& a) -> pair<ScalarType, ScalarType> {
1315 mini::SVector<ScalarType, 4>
const p{Dot(A2, a), Dot(B2, a), Dot(C2, a), Dot(D2, a)};
1316 return make_pair(Min(p), Max(p));
1318 auto const AreDisjoint = [](ScalarType low1, ScalarType up1, ScalarType low2, ScalarType up2) {
1319 return (up1 < low2) or (up2 < low1);
1321 auto const TestAxis =
1322 [&ProjectTetrahedron1, &ProjectTetrahedron2, &AreDisjoint](
auto const& a) {
1323 auto const [low1, up1] = ProjectTetrahedron1(a);
1324 auto const [low2, up2] = ProjectTetrahedron2(a);
1325 return AreDisjoint(low1, up1, low2, up2);
1329 auto const IsEdgePairSeparating =
1330 [&TestAxis](
auto const& a,
auto const& b,
auto const& c,
auto const& d) {
1331 ScalarType
constexpr eps = 1e-15;
1332 auto const ab = b - a;
1333 mini::SVector<ScalarType, kDims> axis = Normalized(Cross(ab, d - c));
1334 bool bAxisIsZero = All(Abs(axis) <= eps);
1335 if (not bAxisIsZero)
1337 return TestAxis(axis);
1342 auto const n = Cross(ab, c - a);
1344 axis = Normalized(Cross(ab, n));
1345 bAxisIsZero = All(Abs(axis) <= eps);
1346 if (not bAxisIsZero)
1348 return TestAxis(axis);
1358 if (IsEdgePairSeparating(A1, B1, A2, B2))
1360 if (IsEdgePairSeparating(B1, C1, A2, B2))
1362 if (IsEdgePairSeparating(C1, A1, A2, B2))
1364 if (IsEdgePairSeparating(A1, D1, A2, B2))
1366 if (IsEdgePairSeparating(B1, D1, A2, B2))
1368 if (IsEdgePairSeparating(C1, D1, A2, B2))
1371 if (IsEdgePairSeparating(A1, B1, B2, C2))
1373 if (IsEdgePairSeparating(B1, C1, B2, C2))
1375 if (IsEdgePairSeparating(C1, A1, B2, C2))
1377 if (IsEdgePairSeparating(A1, D1, B2, C2))
1379 if (IsEdgePairSeparating(B1, D1, B2, C2))
1381 if (IsEdgePairSeparating(C1, D1, B2, C2))
1384 if (IsEdgePairSeparating(A1, B1, C2, A2))
1386 if (IsEdgePairSeparating(B1, C1, C2, A2))
1388 if (IsEdgePairSeparating(C1, A1, C2, A2))
1390 if (IsEdgePairSeparating(A1, D1, C2, A2))
1392 if (IsEdgePairSeparating(B1, D1, C2, A2))
1394 if (IsEdgePairSeparating(C1, D1, C2, A2))
1397 if (IsEdgePairSeparating(A1, B1, A2, D2))
1399 if (IsEdgePairSeparating(B1, C1, A2, D2))
1401 if (IsEdgePairSeparating(C1, A1, A2, D2))
1403 if (IsEdgePairSeparating(A1, D1, A2, D2))
1405 if (IsEdgePairSeparating(B1, D1, A2, D2))
1407 if (IsEdgePairSeparating(C1, D1, A2, D2))
1410 if (IsEdgePairSeparating(A1, B1, B2, D2))
1412 if (IsEdgePairSeparating(B1, C1, B2, D2))
1414 if (IsEdgePairSeparating(C1, A1, B2, D2))
1416 if (IsEdgePairSeparating(A1, D1, B2, D2))
1418 if (IsEdgePairSeparating(B1, D1, B2, D2))
1420 if (IsEdgePairSeparating(C1, D1, B2, D2))
1423 if (IsEdgePairSeparating(A1, B1, C2, D2))
1425 if (IsEdgePairSeparating(B1, C1, C2, D2))
1427 if (IsEdgePairSeparating(C1, A1, C2, D2))
1429 if (IsEdgePairSeparating(A1, D1, C2, D2))
1431 if (IsEdgePairSeparating(B1, D1, C2, D2))
1433 if (IsEdgePairSeparating(C1, D1, C2, D2))
1439 mini::SVector<ScalarType, kDims> n = Normalized(Cross(B1 - A1, D1 - A1));
1442 n = Normalized(Cross(C1 - B1, D1 - B1));
1445 n = Normalized(Cross(A1 - C1, D1 - C1));
1448 n = Normalized(Cross(C1 - A1, B1 - A1));
1452 n = Normalized(Cross(B2 - A2, D2 - A2));
1455 n = Normalized(Cross(C2 - B2, D2 - B2));
1458 n = Normalized(Cross(A2 - C2, D2 - C2));
1461 n = Normalized(Cross(C2 - A2, B2 - A2));
1462 return not TestAxis(n);
1466 mini::CMatrix TMatrixA,
1467 mini::CMatrix TMatrixB,
1468 mini::CMatrix TMatrixC,
1469 mini::CMatrix TMatrixSC>
1474 TMatrixSC
const& SC,
1475 typename TMatrixSC::ScalarType R)
1477 using ScalarType =
typename TMatrixSC::ScalarType;
1479 ScalarType
const d2 = SquaredNorm(X - SC);
1480 ScalarType
const r2 = R * R;
1485 mini::CMatrix TMatrixA,
1486 mini::CMatrix TMatrixB,
1487 mini::CMatrix TMatrixC,
1488 mini::CMatrix TMatrixD,
1489 mini::CMatrix TMatrixSC>
1495 TMatrixSC
const& SC,
1496 typename TMatrixSC::ScalarType R)
1498 using ScalarType =
typename TMatrixSC::ScalarType;
1500 ScalarType
const d2 = SquaredNorm(X - SC);
1501 ScalarType
const r2 = R * R;
This file contains functions to answer closest point queries.
This file contains functions to answer intersection queries.
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
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 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 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
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 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
This namespace contains functions to answer overlap queries.
Definition OverlapQueries.h:27
PBAT_HOST_DEVICE bool Triangles3D(TMatrixA1 const &A1, TMatrixB1 const &B1, TMatrixC1 const &C1, TMatrixA2 const &A2, TMatrixB2 const &B2, TMatrixC2 const &C2)
Tests for overlap between triangle A1B1C1 and triangle A2B2C2, in 3D.
Definition OverlapQueries.h:1122
PBAT_HOST_DEVICE bool AxisAlignedBoundingBoxes(TMatrixL1 const &L1, TMatrixU1 const &U1, TMatrixL2 const &L2, TMatrixU2 const &U2)
Tests for overlap between axis-aligned bounding box (L1,U1) and axis-aligned bounding box (L2,...
Definition OverlapQueries.h:608
PBAT_HOST_DEVICE bool TriangleSphere(TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixSC const &SC, typename TMatrixSC::ScalarType R)
Tests for overlap between a triangle ABC and a sphere with center SC of radius R.
Definition OverlapQueries.h:1470
PBAT_HOST_DEVICE bool LineSegmentSphere(TMatrixP const &P, TMatrixQ const &Q, TMatrixC const &C, typename TMatrixC::ScalarType R)
Tests for overlap between line segment PQ and sphere (C,R)
Definition OverlapQueries.h:632
PBAT_HOST_DEVICE bool TetrahedronAxisAlignedBoundingBox(TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixD const &D, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between tetrahedron ABCD and axis-aligned bounding box (L,U), in at least 3D.
Definition OverlapQueries.h:937
PBAT_HOST_DEVICE bool LineSegmentSweptTriangle3D(TMatrixP const &P, TMatrixQ const &Q, TMatrixA1 const &A1, TMatrixB1 const &B1, TMatrixC1 const &C1, TMatrixA2 const &A2, TMatrixB2 const &B2, TMatrixC2 const &C2)
Tests overlap between line segment PQ and the swept volume spanned by linear interpolation of A1B1C1 ...
Definition OverlapQueries.h:724
PBAT_HOST_DEVICE bool PointTetrahedron3D(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixD const &D)
Checks if point P is contained in tetrahedron ABCD, in at least 3D.
Definition OverlapQueries.h:562
PBAT_HOST_DEVICE bool TetrahedronSphere(TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixD const &D, TMatrixSC const &SC, typename TMatrixSC::ScalarType R)
Tests for overlap between a tetrahedron ABCD and a sphere with center SC of radius R.
Definition OverlapQueries.h:1490
PBAT_HOST_DEVICE bool PointTriangle(TMatrixP const &P, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C)
Tests for overlap between point P and triangle ABC.
Definition OverlapQueries.h:548
PBAT_HOST_DEVICE bool LineSegmentTriangle3D(TMatrixP const &P, TMatrixQ const &Q, TMatrixA const &A, TMatrixB const &B, TMatrixC const &C)
Detects if the line segment PQ passes through the triangle ABC, in 3D.
Definition OverlapQueries.h:705
PBAT_HOST_DEVICE bool PlaneAxisAlignedBoundingBox(TMatrixP const &P, TMatrixN const &n, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between plane (P,n) and axis-aligned bounding box (low,up)
Definition OverlapQueries.h:803
PBAT_HOST_DEVICE bool TriangleAxisAlignedBoundingBox(TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between triangle ABC and axis-aligned bounding box (low,up)
Definition OverlapQueries.h:828
PBAT_HOST_DEVICE bool Spheres(TMatrixC1 const &C1, typename TMatrixC1::ScalarType R1, TMatrixC2 const &C2, typename TMatrixC2::ScalarType R2)
Tests for overlap between sphere (C1,R1) and sphere (C2,R2).
Definition OverlapQueries.h:590
PBAT_HOST_DEVICE bool LineSegmentAxisAlignedBoundingBox(TMatrixP const &P, TMatrixQ const &Q, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between line segment PQ and axis-aligned bounding box (L,U)
Definition OverlapQueries.h:664
PBAT_HOST_DEVICE bool SphereAxisAlignedBoundingBox(TMatrixC const &C, typename TMatrixC::ScalarType R, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between sphere (c,r) and axis-aligned bounding box (low,up)
Definition OverlapQueries.h:619
PBAT_HOST_DEVICE bool PointAxisAlignedBoundingBox(TMatrixP const &P, TMatrixL const &L, TMatrixU const &U)
Tests for overlap between point P and axis-aligned bounding box (L,U)
Definition OverlapQueries.h:536
PBAT_HOST_DEVICE bool TriangleTetrahedron(TMatrixA const &A, TMatrixB const &B, TMatrixC const &C, TMatrixI const &I, TMatrixJ const &J, TMatrixK const &K, TMatrixL const &L)
Tests for overlap between triangle ABC and tetrahedron IJKL, in at least 3D.
Definition OverlapQueries.h:1145
PBAT_HOST_DEVICE bool Tetrahedra(TMatrixA1 const &A1, TMatrixB1 const &B1, TMatrixC1 const &C1, TMatrixD1 const &D1, TMatrixA2 const &A2, TMatrixB2 const &B2, TMatrixC2 const &C2, TMatrixD2 const &D2)
Tests for overlap between tetrahedron A1B1C1D1 and tetrahedron A2B2C2D2, in at least 3D.
Definition OverlapQueries.h:1288
PBAT_HOST_DEVICE bool Triangles2D(TMatrixA1 const &A1, TMatrixB1 const &B1, TMatrixC1 const &C1, TMatrixA2 const &A2, TMatrixB2 const &B2, TMatrixC2 const &C2)
Tests for overlap between triangle A1B1C1 and triangle A2B2C2, in 2D.
Definition OverlapQueries.h:1067
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