Visual Computing Library  devel
Loading...
Searching...
No Matches
intersection.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2026 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MESH_ELEM_ALGORITHMS_INTERSECTION_H
24#define VCL_MESH_ELEM_ALGORITHMS_INTERSECTION_H
25
26#include <vclib/mesh/elements.h>
27
28#include <vclib/algorithms/core.h>
29#include <vclib/space/core.h>
30
31namespace vcl {
32
53template<FaceConcept FaceType, PointConcept PointType>
54bool intersect(const FaceType& f, const Box<PointType>& box)
55{
56 if constexpr (TriangleFaceConcept<FaceType>) {
57 return intersect(
59 f.vertex(0)->position(),
60 f.vertex(1)->position(),
61 f.vertex(2)->position()),
62 box);
63 }
64 else {
65 bool b = false;
66
67 std::vector<uint> tris = earCut(f);
68 for (uint i = 0; i < tris.size() && !b; i += 3) {
69 b |= intersect(
71 f.vertex(tris[i])->position(),
72 f.vertex(tris[i + 1])->position(),
73 f.vertex(tris[i + 2])->position()),
74 box);
75 }
76 return b;
77 }
78}
79
85template<PointConcept PointType, FaceConcept FaceType>
86bool intersect(const Box<PointType>& box, const FaceType& f)
87{
88 return intersect(f, box);
89}
90
111template<FaceConcept FaceType, PointConcept PointType, typename SScalar>
113 const FaceType& f,
114 const Sphere<SScalar>& sphere,
115 PointType& witness,
116 std::pair<SScalar, SScalar>& res)
117{
118 if constexpr (TriangleFaceConcept<FaceType>) {
119 return intersect(
121 f.vertex(0)->position(),
122 f.vertex(1)->position(),
123 f.vertex(2)->position()),
124 sphere,
125 witness,
126 res);
127 }
128 else {
129 if (f.vertexCount() == 3) {
130 return intersect(
132 f.vertex(0)->position(),
133 f.vertex(1)->position(),
134 f.vertex(2)->position()),
135 sphere,
136 witness,
137 res);
138 }
139 else {
140 res.first = std::numeric_limits<SScalar>::max();
141 std::pair<SScalar, SScalar> r;
142
143 bool b = false;
144 PointType w;
145
146 std::vector<uint> tris = earCut(f);
147 for (uint i = 0; i < tris.size() && !b; i += 3) {
148 b |= intersect(
150 f.vertex(tris[i])->position(),
151 f.vertex(tris[i + 1])->position(),
152 f.vertex(tris[i + 2])->position()),
153 sphere,
154 w,
155 r);
156
157 if (r.first < res.first) {
158 res = r;
159 witness = w;
160 }
161 }
162 return b;
163 }
164 }
165}
166
182template<FaceConcept FaceType, typename SScalar>
183bool intersect(const FaceType& f, const Sphere<SScalar>& sphere)
184{
186 std::pair<SScalar, SScalar> res;
187 return intersect(f, sphere, witness, res);
188}
189
195template<typename SScalar, FaceConcept FaceType>
196bool intersect(const Sphere<SScalar>& sphere, const FaceType& f)
197{
198 return intersect(f, sphere);
199}
200
227template<Ray3Concept RayType, FaceConcept FaceType>
228std::optional<typename RayType::PointType> intersection(
229 const RayType& ray,
230 const FaceType& face,
231 std::optional<std::reference_wrapper<typename RayType::ScalarType>> t = {})
232 requires std::same_as<
233 typename RayType::ScalarType,
234 typename FaceType::VertexType::PositionType::ScalarType>
235{
236 using PointType = typename RayType::PointType;
237 using ScalarType = typename PointType::ScalarType;
238
239 auto triangleIntersection = [](const FaceType& f,
240 const RayType& r,
241 auto t) -> std::optional<PointType> {
242 return intersection(
243 r,
244 TriangleWrapper(
245 f.vertex(0)->position(),
246 f.vertex(1)->position(),
247 f.vertex(2)->position()),
248 t);
249 };
250
251 if constexpr (TriangleFaceConcept<FaceType>) {
252 return triangleIntersection(face, ray, t);
253 }
254 else {
255 if (face.vertexCount() == 3) {
256 return triangleIntersection(face, ray, t);
257 }
258 else {
259 std::vector<uint> tris = earCut(face);
260 for (uint i = 0; i < tris.size(); i += 3) {
261 std::optional<PointType> res = intersection(
262 ray,
263 TriangleWrapper(
264 face.vertex(tris[i])->position(),
265 face.vertex(tris[i + 1])->position(),
266 face.vertex(tris[i + 2])->position()),
267 t);
268 if (res.has_value())
269 return res;
270 }
271 return std::nullopt;
272 }
273 }
274}
275
297template<Ray3Concept RayType, FaceConcept FaceType>
298bool intersect(const RayType& ray, const FaceType& face)
299{
300 return intersection(ray, face).has_value();
301}
302
308template<FaceConcept FaceType, Ray3Concept RayType>
309bool intersect(const FaceType& face, const RayType& ray)
310{
311 return intersect(ray, face);
312}
313
314} // namespace vcl
315
316#endif // VCL_MESH_ELEM_ALGORITHMS_INTERSECTION_H
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:41
The TriangleWrapper class is a wrapper around a N-Dimensional triangle.
Definition triangle_wrapper.h:54
Definition face.h:312
bool intersect(const PlaneType &plane, const BoxType &box)
Checks if a plane intersects with a box.
Definition intersect.h:258
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 intersect.h:364
std::vector< uint > earCut(Iterator begin, Iterator end)
Triangulates a simple polygon with no holes using the ear-cutting algorithm.
Definition ear_cut.h:90