mirror of https://github.com/CGAL/cgal
Add intersection Tetrahedron_3 / Segment_3
This commit is contained in:
parent
469ed5396b
commit
9cb1173a41
|
|
@ -40,7 +40,6 @@ CGAL_INTERSECTION_TRAITS_2(Segment_3, Line_3, Point_3, Segment_3)
|
|||
|
||||
CGAL_INTERSECTION_TRAITS_2(Line_3, Triangle_3, Point_3, Segment_3)
|
||||
CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3)
|
||||
CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3)
|
||||
CGAL_INTERSECTION_TRAITS_2(Triangle_3, Line_3, Point_3, Segment_3)
|
||||
|
||||
CGAL_INTERSECTION_TRAITS_2(Plane_3, Plane_3, Line_3, Plane_3)
|
||||
|
|
@ -68,10 +67,15 @@ CGAL_INTERSECTION_TRAITS_2(Triangle_3, Ray_3, Point_3, Segment_3)
|
|||
CGAL_INTERSECTION_TRAITS_2(Segment_3, Segment_3, Point_3, Segment_3)
|
||||
|
||||
CGAL_INTERSECTION_TRAITS_2(Segment_3, Triangle_3, Point_3, Segment_3)
|
||||
CGAL_INTERSECTION_TRAITS_2(Segment_3, Tetrahedron_3, Point_3, Segment_3)
|
||||
|
||||
CGAL_INTERSECTION_TRAITS_2(Triangle_3, Segment_3, Point_3, Segment_3)
|
||||
|
||||
CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3)
|
||||
|
||||
CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3)
|
||||
CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Segment_3, Point_3, Segment_3)
|
||||
|
||||
template<typename K>
|
||||
struct Intersection_traits<K, typename K::Triangle_3, typename K::Triangle_3> {
|
||||
typedef typename
|
||||
|
|
|
|||
|
|
@ -27,9 +27,11 @@
|
|||
#include <CGAL/Tetrahedron_3.h>
|
||||
|
||||
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Bounded_3_do_intersect.h>
|
||||
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h>
|
||||
|
||||
namespace CGAL {
|
||||
CGAL_DO_INTERSECT_FUNCTION(Segment_3, Tetrahedron_3, 3)
|
||||
CGAL_INTERSECTION_FUNCTION(Segment_3, Tetrahedron_3, 3)
|
||||
}
|
||||
|
||||
#endif // CGAL_INTERSECTIONS_3_SEGMENT_3_TETRAHEDRON_3_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
// Copyright (c) 2019 GeometryFactory(France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
//
|
||||
//
|
||||
// Author(s) : Maxime Gimeno
|
||||
//
|
||||
|
||||
#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H
|
||||
#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H
|
||||
|
||||
#include <CGAL/kernel_basic.h>
|
||||
#include <CGAL/intersections.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Intersections {
|
||||
|
||||
namespace internal {
|
||||
//Tetrahedron_3 Segment_3
|
||||
template <class K>
|
||||
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Segment_3>::result_type
|
||||
intersection(
|
||||
const typename K::Tetrahedron_3 &tet,
|
||||
const typename K::Segment_3 &seg,
|
||||
const K&)
|
||||
{
|
||||
typedef typename Intersection_traits<K,
|
||||
typename K::Tetrahedron_3,
|
||||
typename K::Segment_3>::result_type Result_type;
|
||||
|
||||
typedef typename Intersection_traits<K,
|
||||
typename K::Triangle_3,
|
||||
typename K::Segment_3>::result_type Inter_type;
|
||||
|
||||
//if both segment extremities are inside tet, return the input segment.
|
||||
if(tet.has_on_bounded_side(seg.source())
|
||||
&& tet.has_on_bounded_side(seg.target())){
|
||||
typename K::Segment_3 result = seg;
|
||||
return Result_type(std::forward<typename K::Segment_3>(result));
|
||||
}
|
||||
int res_id = -1;
|
||||
|
||||
Inter_type tr_seg[4];
|
||||
for(std::size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
const typename K::Triangle_3 triangle(tet.vertex((i+1)%4),
|
||||
tet.vertex((i+2)%4),
|
||||
tet.vertex((i+3)%4));
|
||||
tr_seg[i] = CGAL::intersection(seg, triangle);
|
||||
if(tr_seg[i])
|
||||
if( boost::get<typename K::Segment_3>(&*tr_seg[i]) != nullptr)
|
||||
res_id = i;
|
||||
}
|
||||
//if there is a segment in the intersections, then we return it
|
||||
if(res_id !=-1)
|
||||
return tr_seg[res_id];
|
||||
|
||||
//else if there is only 1 intersection
|
||||
std::vector<typename K::Point_3> res_points;
|
||||
res_points.reserve(4);
|
||||
res_id = -1;
|
||||
for(std::size_t i = 0; i< 4; ++i)
|
||||
{
|
||||
if(tr_seg[i])
|
||||
{
|
||||
if (const typename K::Point_3* p = boost::get<typename K::Point_3>(&*tr_seg[i]))
|
||||
{
|
||||
if(res_points.empty())
|
||||
{
|
||||
res_id = i;
|
||||
}
|
||||
else {
|
||||
if(*p != res_points.front())
|
||||
{
|
||||
res_id = -1;
|
||||
}
|
||||
}
|
||||
res_points.push_back(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(res_id != -1)
|
||||
{
|
||||
//If one extremity is inside tet : return a segment
|
||||
if(tet.has_on_bounded_side(seg.source()))
|
||||
{
|
||||
typename K::Segment_3 result(seg.source(), res_points.front());
|
||||
return Result_type(std::forward<typename K::Segment_3>(result));
|
||||
}
|
||||
else if(tet.has_on_bounded_side(seg.target())){
|
||||
typename K::Segment_3 result(res_points.front(), seg.target());
|
||||
return Result_type(std::forward<typename K::Segment_3>(result));
|
||||
}
|
||||
//else point and segment entirely not inside:
|
||||
return tr_seg[res_id];
|
||||
}
|
||||
//else, we return a segment of the 2 intersection points (the most far away, in case of inexact)
|
||||
typename K::FT max_dist = 0;
|
||||
std::size_t res_id_2 = -1;
|
||||
std::vector<std::vector<typename K::FT> > sq_distances(res_points.size());
|
||||
for(std::size_t i = 0; i< res_points.size(); ++i)
|
||||
{
|
||||
auto p1 = res_points[i];
|
||||
for(auto p2 : res_points)
|
||||
{
|
||||
sq_distances[i].push_back(CGAL::squared_distance(p1, p2));
|
||||
if(sq_distances[i].back() > max_dist)
|
||||
{
|
||||
res_id = i;
|
||||
res_id_2 = sq_distances[i].size()-1;
|
||||
max_dist = sq_distances[i].back();
|
||||
}
|
||||
}
|
||||
}
|
||||
CGAL_assertion(res_id != -1);
|
||||
CGAL_assertion(res_id_2 != -1);
|
||||
CGAL_assertion(max_dist >0 );
|
||||
|
||||
typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]);
|
||||
|
||||
return Result_type(std::forward<typename K::Segment_3>(res_seg));
|
||||
}
|
||||
|
||||
template <class K>
|
||||
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Segment_3>::result_type
|
||||
intersection(
|
||||
const typename K::Segment_3 &seg,
|
||||
const typename K::Tetrahedron_3 &tet,
|
||||
const K& k)
|
||||
{
|
||||
return intersection(tet, seg, k);
|
||||
}
|
||||
|
||||
}}}
|
||||
#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H
|
||||
|
|
@ -134,6 +134,7 @@ struct Test {
|
|||
Res tmp;
|
||||
assert(CGAL::do_intersect(o1, o2));
|
||||
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
|
||||
std::cout<<tmp<<std::endl;
|
||||
assert(approx_equal(tmp, result));
|
||||
if (do_opposite) {
|
||||
assert(CGAL::do_intersect(o2, o1));
|
||||
|
|
@ -569,8 +570,6 @@ struct Test {
|
|||
{
|
||||
std::cout << "Tetrahedron_3 - Line_3\n";
|
||||
|
||||
//check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,-2,0),P(3,0,0)),P(3,0,0));
|
||||
//check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,-1,0),P(0,-2,0)));
|
||||
Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1));
|
||||
check_no_intersection (tet, L(P(5,0,0), P(5,1,0)));
|
||||
check_intersection (tet, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0)));
|
||||
|
|
@ -579,11 +578,27 @@ struct Test {
|
|||
|
||||
}
|
||||
|
||||
void Tet_S()
|
||||
{
|
||||
std::cout << "Tetrahedron_3 - Segment_3\n";
|
||||
|
||||
Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1));
|
||||
check_no_intersection (tet, L(P(5,0,0), P(5,1,0)));
|
||||
check_intersection (tet, S(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0)));
|
||||
check_intersection (tet, S(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25)));
|
||||
check_intersection (tet, S(P(2,1,0), P(-2,1,0)), P(0,1,0));
|
||||
|
||||
check_intersection (tet, S(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(0.2,0.2,0.2)));
|
||||
typename K::FT coord = 1.0/3.0;
|
||||
check_intersection (tet, S(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord)));
|
||||
|
||||
}
|
||||
|
||||
void run(bool is_exact = false)
|
||||
{
|
||||
std::cout << "3D Intersection tests\n";
|
||||
P_do_intersect();
|
||||
Cub_Cub();
|
||||
/* Cub_Cub();
|
||||
L_Cub();
|
||||
Pl_L();
|
||||
Pl_Pl();
|
||||
|
|
@ -596,12 +611,16 @@ struct Test {
|
|||
S_L();
|
||||
R_L();
|
||||
R_S();
|
||||
R_R();
|
||||
if(is_exact)
|
||||
R_R();*/
|
||||
if(is_exact){
|
||||
Tet_L();
|
||||
Tet_S();
|
||||
}
|
||||
/*
|
||||
Bbox_L();
|
||||
Bbox_R();
|
||||
Bbox_Tr();
|
||||
*/
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue