23#ifndef VCL_ALGORITHMS_CORE_INTERSECTION_MISC_H
24#define VCL_ALGORITHMS_CORE_INTERSECTION_MISC_H
26#include <vclib/space/core/box.h>
27#include <vclib/space/core/plane.h>
28#include <vclib/space/core/segment.h>
29#include <vclib/space/core/sphere.h>
30#include <vclib/space/core/triangle.h>
42template<PlaneConcept PlaneType, Segment3Concept SegmentType>
43void projectSegmentEndPoints(
46 typename SegmentType::ScalarType& p0Proj,
47 typename SegmentType::ScalarType& p1Proj)
49 using ScalarType = SegmentType::ScalarType;
52 p0Proj = s.
p1() * p.direction() - p.offset();
53 p1Proj = s.p0() * p.direction() - p.offset();
60template<
typename ScalarType>
61inline void findMinMax(
80template<
typename ScalarType, Po
intConcept Po
intType>
81inline bool axisTestX01(
88 const PointType& bHalfSize)
90 ScalarType p0 = a * v0.y() - b * v0.z();
91 ScalarType p2 = a * v2.y() - b * v2.z();
101 ScalarType rad = fa * bHalfSize.y() + fb * bHalfSize.z();
102 if (
min > rad ||
max < -rad)
107template<
typename ScalarType, Po
intConcept Po
intType>
108inline bool axisTestX2(
115 const PointType& bHalfSize)
117 ScalarType p0 = a * v0.y() - b * v0.z();
118 ScalarType p1 = a * v1.y() - b * v1.z();
128 ScalarType rad = fa * bHalfSize.y() + fb * bHalfSize.z();
129 if (
min > rad ||
max < -rad)
135template<
typename ScalarType, Po
intConcept Po
intType>
136inline bool axisTestY02(
143 const PointType& bHalfSize)
145 ScalarType p0 = -a * v0.x() + b * v0.z();
146 ScalarType p2 = -a * v2.x() + b * v2.z();
156 ScalarType rad = fa * bHalfSize.x() + fb * bHalfSize.z();
157 if (
min > rad ||
max < -rad)
162template<
typename ScalarType, Po
intConcept Po
intType>
163inline bool axisTestY1(
170 const PointType& bHalfSize)
172 ScalarType p0 = -a * v0.x() + b * v0.z();
173 ScalarType p1 = -a * v1.x() + b * v1.z();
183 ScalarType rad = fa * bHalfSize.x() + fb * bHalfSize.z();
184 if (
min > rad ||
max < -rad)
190template<
typename ScalarType, Po
intConcept Po
intType>
191inline bool axisTestZ12(
198 const PointType& bHalfSize)
200 ScalarType p1 = a * v1.x() - b * v1.y();
201 ScalarType p2 = a * v2.x() - b * v2.y();
211 ScalarType rad = fa * bHalfSize.x() + fb * bHalfSize.y();
212 if (
min > rad ||
max < -rad)
217template<
typename ScalarType, Po
intConcept Po
intType>
218inline bool axisTestZ0(
225 const PointType& bHalfSize)
227 ScalarType p0 = a * v0.x() - b * v0.y();
228 ScalarType p1 = a * v1.x() - b * v1.y();
238 ScalarType rad = fa * bHalfSize.x() + fb * bHalfSize.y();
239 if (
min > rad ||
max < -rad)
261template<PlaneConcept PlaneType, Box3Concept BoxType>
264 using PointType = BoxType::PointType;
265 using ScalarType = PointType::ScalarType;
268 PointType c =
box.center();
269 PointType e =
box.max() - c;
271 PointType
n =
plane.direction();
274 e[0] * std::abs(
n[0]) + e[1] * std::abs(
n[1]) + e[2] * std::abs(
n[2]);
277 ScalarType s =
n.dot(c) -
plane.offset();
280 return std::abs(s) <=
r;
288template<Box3Concept BoxType, PlaneConcept PlaneType>
311template<PlaneConcept PlaneType, Segment3Concept SegmentType>
314 using ScalarType = SegmentType::ScalarType;
339template<Segment3Concept SegmentType, PlaneConcept PlaneType>
367template<PlaneConcept PlaneType, Segment3Concept SegmentType>
372 std::optional<typename SegmentType::PointType>
intersection;
374 using ScalarType = SegmentType::ScalarType;
411template<SphereConcept SphereType, Box3Concept BoxType>
422template<Box3Concept BoxType, SphereConcept SphereType>
448template<Triangle2Concept TriangleType, Po
int2Concept Po
intType>
451 using TP = TriangleType::PointType;
452 using ScalarType = TP::ScalarType;
459 ScalarType
sign = A < 0 ? -1 : 1;
462 (p0.y() *
p2.x() - p0.x() *
p2.y() + (
p2.y() - p0.y()) * point.x() +
463 (p0.x() -
p2.x()) * point.y()) *
466 (p0.x() * p1.y() - p0.y() * p1.x() + (p0.y() - p1.y()) * point.x() +
467 (p1.x() - p0.x()) * point.y()) *
470 return s > 0 &&
tt > 0 && (s +
tt) < 2 * A *
sign;
478template<Po
int2Concept Po
intType, Triangle2Concept TriangleType>
498template<Triangle3Concept TriangleType, Po
int3Concept Po
intType>
499bool intersect(
const TriangleType& triangle,
const PointType& point)
501 PointType v1 = triangle.point(1) - triangle.point(0);
502 PointType v2 = triangle.point(2) - triangle.point(0);
503 PointType v3 = point - triangle.point(0);
505 return v1.dot(v2.cross(v3)) > 0;
513template<Po
int3Concept Po
intType, Triangle3Concept TriangleType>
514bool intersect(
const PointType& point,
const TriangleType& triangle)
541template<Triangle3Concept TriangleType, Box3Concept BoxType>
544 using PointType = TriangleType::PointType;
545 using ScalarType = PointType::ScalarType;
568 PointType
e0 = v1 -
v0;
569 PointType
e1 = v2 - v1;
570 PointType
e2 =
v0 - v2;
574 ScalarType
fex = std::abs(
e0.x());
575 ScalarType
fey = std::abs(
e0.y());
576 ScalarType
fez = std::abs(
e0.z());
585 fex = std::abs(
e1.x());
586 fey = std::abs(
e1.y());
587 fez = std::abs(
e1.z());
596 fex = std::abs(
e2.x());
597 fey = std::abs(
e2.y());
598 fez = std::abs(
e2.z());
614 detail::findMinMax(
v0.x(), v1.x(), v2.x(),
min,
max);
619 detail::findMinMax(
v0.y(), v1.y(), v2.y(),
min,
max);
624 detail::findMinMax(
v0.z(), v1.z(), v2.z(),
min,
max);
632 normal =
e0.cross(
e1);
646template<Box3Concept BoxType, Triangle3Concept TriangleType>
667 Triangle3Concept TriangleType,
668 SphereConcept SphereType,
669 Point3Concept PointType,
675 std::pair<ScalarType, ScalarType>&
res)
679 ScalarType radius =
sphere.radius();
680 PointType center =
sphere.center();
681 PointType p0 =
triangle.point0() - center;
682 PointType p1 =
triangle.point1() - center;
685 PointType
p10 = p1 - p0;
686 PointType
p21 =
p2 - p1;
687 PointType
p20 =
p2 - p0;
745 res.first = std::max<ScalarType>(
witness_norm - radius, ScalarType(0.0));
746 res.second = std::max<ScalarType>(radius -
witness_norm, ScalarType(0.0));
762template<Triangle3Concept TriangleType, SphereConcept SphereType>
765 using SScalar = SphereType::ScalarType;
766 typename TriangleType::PointType
witness;
767 std::pair<SScalar, SScalar>
res;
776template<SphereConcept SphereType, Triangle3Concept TriangleType>
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
PointT & p0()
Returns the first endpoint of the segment.
Definition segment.h:83
PointT & p1()
Returns the second endpoint of the segment.
Definition segment.h:97
bool intersect(const FaceType &f, const Box< PointType > &box)
Checks if a face intersects a box.
Definition element.h:57
std::optional< typename SegmentType::PointType > intersection(const PlaneType &plane, const SegmentType &segment)
Returns the intersection point between a plane and a segment, if it exists.
Definition misc.h:368
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:83
constexpr auto min(const T &p1, const T &p2)
Returns the minimum between the two parameters.
Definition min_max.h:42