This commit is contained in:
Maxime Gimeno 2019-06-06 10:46:02 +02:00
parent 38bf604b4a
commit 5e9891ea75
13 changed files with 1308 additions and 176 deletions

View File

@ -187,6 +187,28 @@ struct Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Point_3> {
typedef typename boost::optional< variant_type > result_type;
};
// Iso_cuboid_3 Plane_3, variant of 4
template<typename K>
struct Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Plane_3> {
typedef typename
boost::variant< typename K::Point_3, typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
template<typename K>
struct Intersection_traits<K, typename K::Plane_3, typename K::Iso_cuboid_3> {
typedef typename
boost::variant< typename K::Point_3, typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
// Point_3 Line_3, variant of one
template<typename K>
struct Intersection_traits<K, typename K::Point_3, typename K::Line_3> {
@ -324,6 +346,27 @@ struct Intersection_traits<K, typename K::Plane_3,typename K::Tetrahedron_3>
};
//Triangle_3 Tetrahedron_3, variant of 4
template<class K>
struct Intersection_traits<K, typename K::Triangle_3,typename K::Tetrahedron_3>
{
typedef typename
boost::variant< typename K::Point_3 , typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
// Tetrahedron_3 Triangle_3, variant of 4
template<class K>
struct Intersection_traits<K, typename K::Tetrahedron_3,typename K::Triangle_3>
{
typedef typename
boost::variant< typename K::Point_3 , typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
} // namespace
#endif /* CGAL_INTERSECTION_TRAITS_3_H */

View File

@ -26,10 +26,12 @@
#include <CGAL/Iso_cuboid_3.h>
#include <CGAL/Plane_3.h>
#include <CGAL/Intersections_3/internal/Bbox_3_Plane_3_do_intersect.h>
#include <CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h>
namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3, Plane_3, 3)
CGAL_INTERSECTION_FUNCTION(Iso_cuboid_3, Plane_3, 3)
}
#endif // CGAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_H

View File

@ -27,7 +27,7 @@
#include <CGAL/Tetrahedron_3.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Unbounded_3_do_intersect.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h>
namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Tetrahedron_3, Plane_3, 3)

View File

@ -27,7 +27,7 @@
#include <CGAL/Tetrahedron_3.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Unbounded_3_do_intersect.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h>
namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Ray_3, Tetrahedron_3, 3)

View File

@ -27,7 +27,7 @@
#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>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h>
namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Segment_3, Tetrahedron_3, 3)

View File

@ -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_Triangle_3_intersection.h>
namespace CGAL {
CGAL_DO_INTERSECT_FUNCTION(Tetrahedron_3, Triangle_3, 3)
CGAL_INTERSECTION_FUNCTION(Tetrahedron_3, Triangle_3, 3)
}
#endif // CGAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_H

View File

@ -0,0 +1,262 @@
// 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_ISO_CUBOID_3_PLANE_3_INTERSECTION_H
#define CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H
#include <CGAL/kernel_basic.h>
#include <CGAL/intersections.h>
#include <CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Segment_3.h>
#include <CGAL/Intersections_3/Plane_3_Plane_3.h>
#include <set>
namespace CGAL {
namespace Intersections {
namespace internal {
template<typename Point>
void filter_points(const std::vector<Point>& input,
std::vector<Point>& output)
{
std::set<Point> tmp;
for( auto p : input)
tmp.insert(p);
for(auto p: tmp)
output.push_back(p);
}
//Tetrahedron_3 Line_3
template <class K>
typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Plane_3>::result_type
intersection(
const typename K::Iso_cuboid_3 &cub,
const typename K::Plane_3 &pl,
const K&)
{
typedef typename K::Point_3 Point_3;
typedef typename K::Segment_3 Segment_3;
typedef typename K::Line_3 Line_3;
typedef typename K::Plane_3 Plane_3;
typedef std::vector<Point_3> Poly;
typedef typename Intersection_traits<K,
CGAL::Iso_cuboid_3<K>,
CGAL::Plane_3<K> >::result_type Result_type;
typedef typename Intersection_traits<K,
CGAL::Segment_3<K>,
CGAL::Plane_3<K> >::result_type Inter_type;
std::vector<Segment_3> edges;
edges.reserve(12);
//get all edges of cub
for(int i=0; i< 4; ++i)
{
edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4)));
}
for(int i=0; i < 4; ++i)
{
edges.push_back(Segment_3(cub.vertex(i+4), cub.vertex((i+1)%4+4)));
}
for(int i=0; i < 4; ++i)
{
edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4+4)));
}
//get all intersections between pl and cub edges
std::vector<Segment_3> segments;
std::vector<Point_3> points;
for(int i=0; i < 12; ++i)
{
Inter_type inter = typename K::Intersect_3()(pl, edges[i]);
if(inter){
if(const Segment_3* seg = boost::get<Segment_3>(&*inter))
{
segments.push_back(*seg);
}
else if(const Point_3* p = boost::get<Point_3>(&*inter))
{
points.push_back(*p);
}
}
}
switch(segments.size())
{
case 1: //adj to an edge
{
return Result_type(std::forward<Segment_3>(segments.front()));
}
break;
case 2: //intersects diagonally
{
Poly res(4);
Segment_3 front(segments.front()),
back(segments.back());
res[0] = front.target();
if((front.target() - front.source())
* (back.target() - back.source()) > 0)
{
res[1] = back.target();
res[2] = back.source();
}
else
{
res[1] = back.source();
res[2] = back.target();
}
res[3] = front.source();
return Result_type(std::forward<Poly>(res));
}
break;
case 4: // intersects a face
{
Poly res;
res.reserve(4);
std::list<Point_3> tmp;
std::list<Segment_3> seg_list;
for(auto s : segments)
seg_list.push_back(s);
fill_points_list(seg_list, tmp);
for(auto p : tmp)
res.push_back(p);
return Result_type(std::forward<Poly>(res));
}
break;
default:
break;
}
Poly filtered_points;
filter_points(points, filtered_points);
if(filtered_points.empty())
return Result_type();
//adjacent to a vertex
if(filtered_points.size() == 1)
{
return Result_type(std::forward<Point_3>(filtered_points.front()));
}
else
{
//get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon.
typedef typename Intersection_traits<K,
CGAL::Plane_3<K>,
CGAL::Plane_3<K> >::result_type Pl_pl_type;
std::vector<Line_3> plane_intersections;
Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0),
cub.vertex(1),
cub.vertex(5)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0),
cub.vertex(3),
cub.vertex(4)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0),
cub.vertex(1),
cub.vertex(3)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7),
cub.vertex(6),
cub.vertex(1)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7),
cub.vertex(4),
cub.vertex(3)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7),
cub.vertex(6),
cub.vertex(4)));
if(const Line_3* line = boost::get<Line_3>(&*pl_inter)){
plane_intersections.push_back(*line);
}
std::list<Segment_3> tmp_segs;
for(auto line : plane_intersections)
{
bool first_found = false;
Point_3 first_p;
for(auto p : filtered_points)
{
if(line.has_on(p))
{
if(!first_found)
{
first_found = true;
first_p = p;
}
else
{
tmp_segs.push_back(Segment_3(first_p, p));
break;
}
}
}
}
if(tmp_segs.size() < 3)
return Result_type();
std::list<Point_3> tmp_pts;
fill_points_list(tmp_segs,tmp_pts);
Poly res;
for(auto p : tmp_pts)
res.push_back(p);
if(res.size() == 3){
typename K::Triangle_3 tr(res[0], res[1], res[2]);
return Result_type(std::forward<typename K::Triangle_3>(tr));
}
else
{
return Result_type(std::forward<Poly>(res));
}
}
}
template <class K>
typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Plane_3>::result_type
intersection(
const typename K::Plane_3 &pl,
const typename K::Iso_cuboid_3 &cub,
const K& k)
{
return intersection(cub, pl, k);
}
}}}
#endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H

View File

@ -27,6 +27,7 @@
#include <CGAL/kernel_basic.h>
#include <CGAL/intersections.h>
#include <CGAL/Intersections_3/internal/Triangle_3_Plane_3_do_intersect.h>
#include <CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h>
#include <set>
namespace CGAL {
@ -34,6 +35,7 @@ namespace Intersections {
namespace internal {
//Tetrahedron_3 Segment_3
template <class K>
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Plane_3>::result_type
@ -123,56 +125,15 @@ intersection(
}
else //size = 4
{
Segment_3 edge = segments.back();
segments.pop_back();
std::vector<typename K::Point_3> result;
auto s_it = segments.begin();
result.push_back(edge.source());
result.push_back(edge.target());
int counter = 0;
for(; counter <2; ++counter )//1 or 2 rounds
{
if(edge.target() == s_it->source())
{
result.push_back(s_it->target());
break;
}
else if (edge.target() == s_it->target())
{
result.push_back(s_it->source());
break;
}
else
++s_it;
}
if(counter > 1) //not exact, won't find the right inter anyway.
return Result_type();
segments.erase(s_it);
s_it = segments.begin();
if(edge.source() == s_it->target())
{
result.push_back(s_it->source());
}
else if(edge.source() == s_it->source())
{
result.push_back(s_it->target());
}
else
{
if(result.back() == s_it->target())
{
result.push_back(s_it->source());
}
else if(result.back() == s_it->source())
{
result.push_back(s_it->target());
}
}
return Result_type(std::forward<std::vector<typename K::Point_3> >(result));
std::list<Segment_3> segs;
for(auto s : segments)
segs.push_back(s);
std::list<typename K::Point_3> tmp;
fill_points_list(segs, tmp);
std::vector<typename K::Point_3> res;
for( auto p : tmp)
res.push_back(p);
return Result_type(std::forward<std::vector<typename K::Point_3> >(res));
}
}
break;

View File

@ -0,0 +1,299 @@
// 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_TRIANGLE_3_INTERSECTIONS_H
#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_INTERSECTIONS_H
#include <CGAL/kernel_basic.h>
#include <CGAL/intersections.h>
#include <CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h>
#include <CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h>
#include <CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h>
namespace CGAL {
namespace Intersections {
namespace internal {
//Tetrahedron_3 Segment_3
template <class K>
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Triangle_3>::result_type
intersection(
const typename K::Tetrahedron_3 &tet,
const typename K::Triangle_3 &tr,
const K&)
{
typedef typename Intersection_traits<K,
typename K::Tetrahedron_3,
typename K::Triangle_3>::result_type Result_type;
typedef typename Intersection_traits<K,
typename K::Triangle_3,
typename K::Triangle_3>::result_type Inter_type;
typedef typename K::Segment_3 Segment_3;
typedef typename K::Point_3 Point_3;
typedef typename K::Triangle_3 Triangle_3;
typedef std::vector<Point_3> Poly;
std::vector<Point_3> inside_points;
for(int i = 0; i< 3; ++i)
{
if(tet.has_on_bounded_side(tr.vertex(i))
|| tet.has_on_boundary(tr.vertex(i)))
inside_points.push_back(tr.vertex(i));
}
switch(inside_points.size())
{
case 0:
{
Inter_type intersections[4];
std::vector<Segment_3> segments;
std::vector<std::size_t> seg_ids;
std::vector<Point_3> points;
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));
intersections[i] = typename K::Intersect_3()(tr, triangle);
if(intersections[i]){
//a face is inside the input tr
if(const Triangle_3* t = boost::get<typename K::Triangle_3>(&*intersections[i]))
{
Triangle_3 res = *t;
return Result_type(std::forward<Triangle_3>(res));
}
//get segs and pts to construct poly
else if( const Segment_3* s
= boost::get<Segment_3>(&*intersections[i]))
{
segments.push_back(*s);
seg_ids.push_back(i);
}
else if( const typename K::Point_3* p
= boost::get<typename K::Point_3>(&*intersections[i]))
{
points.push_back(*p);
}
//if poly : then the input is in a supporting plane of a face, return the poly.
else if( const Poly* p
= boost::get<Poly>(&*intersections[i]))
{
Poly res = *p;
return Result_type(std::forward<Poly>(res));
}
}
}
if(segments.size() > 1)
{
std::vector<Segment_3> filtered;
filter_segments(segments, filtered);
segments = filtered;
}
//if there are several segments, then we need to compute the polygone.
if(segments.size() > 1)
{
std::list<Point_3> tmp;
fill_segments_infos(segments,tmp, tr);
Poly res;
res.reserve(4);
for( auto p : tmp)
res.push_back(p);
return Result_type(std::forward<Poly>(res));
}
//else it must be adjacent to an vertex, so we return the point
else if(segments.size() == 1)
{
//adjacency to an edge, return resulting segment.
return Result_type(std::forward<Segment_3>(segments.front()));
}
else
{
//no segment = adjacency to an vertex or an edge : return result point
return Result_type(std::forward<Point_3>(points.front()));
}
}
break;
case 1:
case 2:
{
//tricky cases
Inter_type intersections[4];
std::vector<typename K::Point_3> points;
std::vector<Segment_3> segments;
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));
intersections[i] = typename K::Intersect_3()(tr, triangle);
if(intersections[i]){
if(const Triangle_3* t = boost::get<typename K::Triangle_3>(&*intersections[i]))
{
Triangle_3 res = *t;
return Result_type(std::forward<Triangle_3>(res));
}
//get segs and pts to construct poly
else if( const Segment_3* s
= boost::get<Segment_3>(&*intersections[i]))
{
segments.push_back(*s);
}
else if( const typename K::Point_3* p
= boost::get<typename K::Point_3>(&*intersections[i]))
{
points.push_back(*p);
}
//if poly : then the input is in a supporting plane of a face, return the poly.
else if( const Poly* p
= boost::get<Poly>(&*intersections[i]))
{
Poly res = *p;
return Result_type(std::forward<Poly>(res));
}
}
}
if(segments.empty())
{
//then there is only one point of contact. Return it:
return Result_type(std::forward<Point_3>(points.front()));
}
if(segments.size() > 1)
{
std::vector<Segment_3> filtered;
filter_segments(segments, filtered);
segments = filtered;
}
switch(segments.size())
{
case 1:
{
bool return_solo_seg = true;
//only one intersection, a triangle edge is one of the tet edges, and
//the 3rd point is outside. This is the only intersection.
for(auto p : inside_points)
{
if(!tet.has_on_boundary(p))
{
return_solo_seg = false;
break;
}
}
if(return_solo_seg)
{
return Result_type(std::forward<Segment_3>(segments.front()));
}
if(inside_points.size() == 1)
{
Triangle_3 res(inside_points.front(), segments.front().source(),
segments.front().target());
return Result_type(std::forward<Triangle_3>(res));
}
else //size 2
{
Poly res(4);
res[0] = inside_points.front();
res[1] = inside_points.back();
if((inside_points.front() - inside_points.back()) *
(segments.front().source() - segments.front().target()) > 0)
{
res[2] = segments.front().target();
res[3] = segments.front().source();
}
else
{
res[3] = segments.front().target();
res[2] = segments.front().source();
}
return Result_type(std::forward<Poly>(res));
}
}
break;
case 2:
case 3:
{
std::list<Segment_3> segs;
for(auto s : segments)
segs.push_back(s);
std::list<Point_3> tmp;
fill_points_list(segs, tmp);
if(inside_points.size() == 1)
{
Poly res;
res.reserve(4);
res.push_back(inside_points.front());
for( auto p : tmp)
res.push_back(p);
return Result_type(std::forward<Poly>(res));
}
else //size 2
{
Poly res;
res.reserve(5);
if((inside_points.front() - inside_points.back()) *
(tmp.front() - tmp.back()) > 0)
res.push_back(inside_points.front());
res.push_back(inside_points.back());
for( auto p : tmp)
res.push_back(p);
return Result_type(std::forward<Poly>(res));
}
}
break;
default:
//3 faces max if a point or more are inside tetrahedron
break;
}
}
break;
case 3:
{
//triangle entirely inside tetra : return input triangle
typename K::Triangle_3 res = tr;
return Result_type(std::forward<typename K::Triangle_3>(res));
}
break;
default:
//never happens (only 3 pts in a tr)
break;
}
}
template <class K>
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Triangle_3>::result_type
intersection(
const typename K::Triangle_3 &pl,
const typename K::Tetrahedron_3 &tet,
const K& k)
{
return intersection(tet, pl, k);
}
}}}
#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_INTERSECTIONS_H

View File

@ -0,0 +1,246 @@
#ifndef CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H
#define CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H
#include <CGAL/kernel_basic.h>
#include <list>
#include <vector>
namespace CGAL {
namespace Intersections {
namespace internal {
template<typename Segment>
void filter_segments(const std::vector<Segment>& input,
std::vector<Segment>& output)
{
std::list<Segment> tmp(input.begin(), input.end());
do
{
Segment s = tmp.back();
tmp.pop_back();
auto s_it = tmp.begin();
for(; s_it != tmp.end();)
{
if(s == *s_it || s == s_it->opposite())
{
s_it = tmp.erase(s_it);
}
else {
++s_it;
}
}
output.push_back(s);
}while (!tmp.empty());
}
template <typename Segment,
typename Point,
typename Triangle>
void fill_segments_infos(std::vector<Segment>& segments,
std::list<Point>& points, const Triangle& input_tr)
{
struct Wrapped_segment
{
Segment segment;
bool s_dangling;
bool t_dangling;
std::size_t s_neighbor;
std::size_t t_neighbor;
Wrapped_segment(const Segment& s)
:segment(s), s_dangling(true),
t_dangling(true){}
};
std::vector<Wrapped_segment> wrapped_segments;
for(auto s:segments)
wrapped_segments.push_back(Wrapped_segment(s));
std::vector<Segment> bis = segments;
for(int plouf = 0; plouf < bis.size()-1; ++plouf)
{
Segment s = bis.back();
bis.pop_back();
Wrapped_segment& super_s = wrapped_segments.back();
if(!super_s.s_dangling && ! super_s.t_dangling)
continue;
for(std::size_t i = 0; i< bis.size(); ++i)
{
const Segment& s2 = bis[i];
if(s2.target() == s.source())
{
super_s.s_dangling = false;
super_s.s_neighbor = i;
//same i because we empty from the bottom
wrapped_segments[i].t_dangling = false;
wrapped_segments[i].t_neighbor = bis.size();
}
else if(s2.target() == s.target())
{
super_s.t_dangling = false;
super_s.t_neighbor = i;
wrapped_segments[i].s_dangling = false;
wrapped_segments[i].s_neighbor = bis.size();
wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); //also orient the structure
}
else if(s2.source() == s.source())
{
super_s.s_dangling = false;
super_s.s_neighbor = i;
wrapped_segments[i].t_dangling = false;
wrapped_segments[i].t_neighbor = bis.size();
wrapped_segments[i].segment = wrapped_segments[i].segment.opposite();
}
else if(s2.source() == s.target())
{
super_s.t_dangling = false;
super_s.t_neighbor = i;
wrapped_segments[i].s_dangling = false;
wrapped_segments[i].s_neighbor = bis.size();
}
}
//fill dangling extremities using triangle edges
if(super_s.s_dangling)
{
for(std::size_t e_id = 0; e_id < 3; ++e_id)
{
Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1));
if(!edge.has_on(s.source()))
{
continue;
}
for(std::size_t i = 0; i< bis.size(); ++i)
{
if(edge.has_on(bis[i].source()))
{
super_s.s_dangling = false;
super_s.s_neighbor = i;
//same i because we empty from the bottom
wrapped_segments[i].t_dangling = false;
wrapped_segments[i].t_neighbor = bis.size();
wrapped_segments[i].segment = wrapped_segments[i].segment.opposite();
}
else if(edge.has_on(bis[i].target()))
{
super_s.s_dangling = false;
super_s.s_neighbor = i;
//same i because we empty from the bottom
wrapped_segments[i].t_dangling = false;
wrapped_segments[i].t_neighbor = bis.size();
}
}
}
}
if(super_s.t_dangling)
{
for(std::size_t e_id = 0; e_id < 3; ++e_id)
{
Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1));
if(!edge.has_on(s.target()))
{
continue;
}
for(std::size_t i = 0; i< bis.size(); ++i)
{
if(edge.has_on(bis[i].source()))
{
super_s.t_dangling = false;
super_s.t_neighbor = i;
//same i because we empty from the bottom
wrapped_segments[i].s_dangling = false;
wrapped_segments[i].s_neighbor = bis.size();
}
else if(edge.has_on(bis[i].target()))
{
super_s.t_dangling = false;
super_s.t_neighbor = i;
//same i because we empty from the bottom
wrapped_segments[i].s_dangling = false;
wrapped_segments[i].s_neighbor = bis.size();
wrapped_segments[i].segment = wrapped_segments[i].segment.opposite();
}
}
}
}
if(super_s.s_dangling || super_s.t_dangling)
{
std::cerr<<"Error. Kernel must have exact constructions to compute this intersection."<<std::endl;
return;
}
}
//finally fill points
std::size_t voyager = 0;
do
{
Wrapped_segment& ws = wrapped_segments[voyager];
points.push_back(ws.segment.source());
if(wrapped_segments[ws.t_neighbor].segment.source() != ws.segment.target())
points.push_back(ws.segment.target());
voyager = ws.t_neighbor;
}while(voyager!=0);
}
template <typename Segment,
typename Point>
void fill_points_list(std::list<Segment>& segments, std::list<Point>& points)
{
assert(segments.size() > 1);
//init : take seg.front = seg.
Segment seg = segments.front();
segments.pop_front();
//put source and target in points.
points.push_back(seg.source());
points.push_back(seg.target());
//find first seg with a point in common with seg.front = s2.
do{
auto seg_it = segments.begin();
bool found = false;
for(;seg_it != segments.end(); ++seg_it)
{
if(seg_it->source() == points.front())
{
points.push_front(seg_it->target());
found = true;
}
else if(seg_it->source() == points.back())
{
points.push_back(seg_it->target());
found = true;
}
else if(seg_it->target() == points.front())
{
points.push_front(seg_it->source());
found = true;
}
else if(seg_it->target() == points.back())
{
points.push_back(seg_it->source());
found = true;
}
if(found)
{
break;
}
}
if(!found)
{
std::cerr<<"Error. Kernel must have exact constructions to compute this intersection."<<std::endl;
return;
}
segments.erase(seg_it);
//if loop, pop first point to avoid double
if(points.front() == points.back())
points.pop_front();
}while(!segments.empty());
}
}}}//end namespaces
#endif // CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H

View File

@ -47,7 +47,7 @@ randomint ri;
inline double to_nt(int d)
{
return double(d);
return double(d);
}
template < typename K >
@ -68,79 +68,78 @@ struct Test {
template < typename Type >
bool approx_equal_nt(const Type &t1, const Type &t2)
{
if (t1 == t2)
return true;
if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon)
return true;
std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n";
return false;
if (t1 == t2)
return true;
if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon)
return true;
std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n";
return false;
}
template < typename Type >
bool approx_equal(const Type&t1, const Type&t2)
{
return t1 == t2;
// we need approx equal to check approx kernels, but maybe we should only test with exact kernels
// (approx kernels were useful before, when the text output was checked by diff ?)
// idea : test containment with intervals ? or use some "epsilon double"?
// I need to convert the text output to exact rationals in the source...
// Well, for now the current scheme works.
return t1 == t2;
// we need approx equal to check approx kernels, but maybe we should only test with exact kernels
// (approx kernels were useful before, when the text output was checked by diff ?)
// idea : test containment with intervals ? or use some "epsilon double"?
// I need to convert the text output to exact rationals in the source...
// Well, for now the current scheme works.
}
bool approx_equal(const P & p, const P & q)
{
return approx_equal_nt(p.x(), q.x()) &&
approx_equal_nt(p.y(), q.y()) &&
approx_equal_nt(p.z(), q.z());
return approx_equal_nt(p.x(), q.x()) &&
approx_equal_nt(p.y(), q.y()) &&
approx_equal_nt(p.z(), q.z());
}
bool approx_equal(const S & p, const S & q)
{
return approx_equal(p.source(), q.source()) && approx_equal(p.target(), q.target());
return approx_equal(p.source(), q.source()) && approx_equal(p.target(), q.target());
}
/*
bool approx_equal(const Pol & p, const Pol & q)
{
if (p.size() != q.size())
return false;
for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq)
if (!approx_equal(*itp, *itq))
return false;
return true;
if (p.size() != q.size())
return false;
for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq)
if (!approx_equal(*itp, *itq))
return false;
return true;
}
*/
template < typename O1, typename O2>
void check_no_intersection(const O1& o1, const O2& o2)
{
assert(!CGAL::do_intersect(o1, o2));
assert(!CGAL::do_intersect(o2, o1));
assert(!CGAL::do_intersect(o1, o2));
assert(!CGAL::do_intersect(o2, o1));
}
template < typename Res, typename O1, typename O2 >
void check_intersection(const O1& o1, const O2& o2)
{
Res tmp;
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
assert(CGAL::do_intersect(o2, o1));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
Res tmp;
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
assert(CGAL::do_intersect(o2, o1));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
}
template < typename Res, typename O1, typename O2 >
void check_intersection(const O1& o1, const O2& o2, const Res& result, bool do_opposite = true)
{
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));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
assert(approx_equal(tmp, result));
}
Res tmp;
assert(CGAL::do_intersect(o1, o2));
assert(CGAL::assign(tmp, CGAL::intersection(o1, o2)));
assert(approx_equal(tmp, result));
if (do_opposite) {
assert(CGAL::do_intersect(o2, o1));
assert(CGAL::assign(tmp, CGAL::intersection(o2, o1)));
assert(approx_equal(tmp, result));
}
}
@ -167,12 +166,12 @@ struct Test {
assert(! do_intersect(cub,s));
}
void Cub_Cub()
{
std::cout << "Iso_cuboid - Iso_cuboid\n";
check_intersection (Cub(p(-7, 6, 1), p(7092, 71, 58)), Cub(p(-758, -98725, 43), p(17, 9025473, 47)),
Cub(p(-7, 6, 43), p(17, 71, 47)));
Cub(p(-7, 6, 43), p(17, 71, 47)));
check_no_intersection (Cub(p(-7, 6, 1), p(7092, 71, 58)), Cub(p(-758, 98725, 43), p(17, 9025473, 47)));
check_no_intersection (Cub(p(-73, 6, 1), p(-70, 71, 58)), Cub(p(8, -98725, 43), p(17, 9025473, 47)));
check_no_intersection (Cub(p(-7, 6, 1), p(7092, 71, 58)), Cub(p(-758, -98725, -47), p(17, 9025473, -43)));
@ -182,30 +181,30 @@ struct Test {
{
std::cout << "Line - Iso_cuboid\n";
check_intersection (L(p(-3, 1,-5), p( -2, -5, -7)), Cub(p( -7, -8, -9), p(-1, 2, -4)),
S(P(-3.16667, 2, -4.66667), P(-1.5, -8, -8)));
S(P(-3.16667, 2, -4.66667), P(-1.5, -8, -8)));
check_intersection (L(p( 0, 0, 3), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 2, 3), P( 2.5, 5, 3)));
S(P( 1, 2, 3), P( 2.5, 5, 3)));
check_intersection (L(p( 1, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 1, 1.5), P( 1, 5, 7.5)));
S(P( 1, 1, 1.5), P( 1, 5, 7.5)));
check_intersection (L(p( 0, 2, 0), p( 1, 2, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)),
S(P( 2, 2, 6), P(2.66667, 2, 8)));
S(P( 2, 2, 6), P(2.66667, 2, 8)));
check_no_intersection (L(p( 0, 0, 0), p( 1, 0, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_no_intersection (L(p( 4, 0, 0), p( 4, 1, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_intersection (L(p( 0, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 2, 3), P(2.5, 5, 7.5)));
S(P( 1, 2, 3), P(2.5, 5, 7.5)));
}
void Pl_L()
{
std::cout << "Plane - Line\n";
check_intersection (pl(1, 1, 1, 0), L(p( 1, 1, 1), p( 2, 3, 4)),
P(0.5, 0, -0.5));
P(0.5, 0, -0.5));
check_intersection<L> (pl(0, 0, 1,-1), L(p( 1, 1, 1), p( 2, 3, 1)));
check_no_intersection (pl(0, 0, 1,-2), L(p( 1, 1, 1), p( 2, 3, 1)));
check_intersection (pl(1, 0, 1, 3), L(p( 1, 1, 1), p( 2, 3, -1)),
P( 6, 11, -9));
P( 6, 11, -9));
check_intersection (pl(1, 2, 4, 7), L(p( 1, 1, 1), p( 2, 3, 4)),
P( 0.176471, -0.647059, -1.47059));
P( 0.176471, -0.647059, -1.47059));
}
void Pl_Pl()
@ -292,35 +291,35 @@ struct Test {
{
std::cout << "Ray - Iso_cuboid\n";
check_intersection (R(p( -3, 1, -5), p( -2, -5, -7)), Cub(p( -7, -8, -9), p( -1, 2, -4)),
S(P(-3, 1, -5), P(-1.5, -8, -8)));
S(P(-3, 1, -5), P(-1.5, -8, -8)));
check_intersection (R(p( 0, 0, 3), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 2, 3), P( 2.5, 5, 3)));
S(P( 1, 2, 3), P( 2.5, 5, 3)));
check_intersection (R(p( 1, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 1,1.5), P( 1, 5,7.5)));
S(P( 1, 1,1.5), P( 1, 5,7.5)));
check_intersection (R(p( 0, 2, 0), p( 1, 2, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)),
S(P( 2, 2, 6), P(2.66667,2, 8)));
S(P( 2, 2, 6), P(2.66667,2, 8)));
check_no_intersection (R(p( 0, 0, 0), p( 1, 0, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_no_intersection (R(p( 4, 0, 0), p( 4, 1, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_intersection (R(p( 0, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 2, 3), P(2.5, 5, 7.5)));
S(P( 1, 2, 3), P(2.5, 5, 7.5)));
}
void S_Cub()
{
std::cout << "Segment - Iso_cuboid\n";
check_intersection (S(p( -3, 1, -5), p( -2, -5, -7)), Cub(p( -7, -8, -9), p( -1, 2, -4)),
S(P(-3, 1, -5), P( -2, -5, -7)));
S(P(-3, 1, -5), P( -2, -5, -7)));
check_intersection (S(p( 0, 0, 3), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
P( 1, 2, 3));
P( 1, 2, 3));
check_intersection (S(p( 1, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
S(P( 1, 1, 1.5), P( 1, 2, 3)));
S(P( 1, 1, 1.5), P( 1, 2, 3)));
check_no_intersection (S(p( 0, 2, 0), p( 1, 2, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_no_intersection (S(p( 0, 0, 0), p( 1, 0, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_no_intersection (S(p( 4, 0, 0), p( 4, 1, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)));
check_intersection (S(p( 0, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)),
P( 1, 2, 3));
P( 1, 2, 3));
}
void Pl_Tr()
{
std::cout << "Plane - Triangle\n";
@ -329,7 +328,7 @@ struct Test {
check_intersection ( Pl(P(0,0,0),P(12,0,0),P(0,11,0)),Tr(P(0,0,0),P(1,0,0),P(0,1,1)),S(P(0,0,0),P(1,0,0)),true);
check_intersection ( Pl(P(0,0,0),P(12,0,0),P(0,11,0)),Tr(P(1,0,-1),P(-1,0,-1),P(0,0,1)),S(P(0.5,0,0),P(-0.5,0,0)),true);
}
void S_L()
{
std::cout << "Segment - Line\n";
@ -337,7 +336,7 @@ struct Test {
check_intersection ( S(P(0,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true);
check_intersection ( S(P(-12,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true);
}
void R_L()
{
std::cout << "Ray - Line\n";
@ -395,11 +394,11 @@ struct Test {
check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,-1,0),P(0,-2,0)));
check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,1,0),P(0,2,0)));
}
void Bbox_L(){
std::cout << "Bbox - Line\n";
Bbox box(-1,-1,-1,1,1,1);
//not in x,y,z slab
check_no_intersection (box,L(P(2,0,0),P(2,0,0.5)));
check_no_intersection (box,L(P(0,2,0),P(0,2,0.5)));
@ -411,41 +410,41 @@ struct Test {
//in each slab, time not matching
//xz
check_no_intersection (box,L(P(-8,0,0),P(0,0, 8)));
check_no_intersection (box,L(P( 8,0,0),P(0,0, 8)));
check_no_intersection (box,L(P( 8,0,0),P(0,0, 8)));
check_no_intersection (box,L(P(-8,0,0),P(0,0,-8)));
check_no_intersection (box,L(P( 8,0,0),P(0,0,-8)));
//yz
check_no_intersection (box,L(P(0,-8,0),P(0,0, 8)));
check_no_intersection (box,L(P(0, 8,0),P(0,0, 8)));
check_no_intersection (box,L(P(0, 8,0),P(0,0, 8)));
check_no_intersection (box,L(P(0,-8,0),P(0,0,-8)));
check_no_intersection (box,L(P(0, 8,0),P(0,0,-8)));
//xy
check_no_intersection (box,L(P(0,-8,0),P(8,0,0)));
check_no_intersection (box,L(P(0, 8,0),P(8,0,0)));
check_no_intersection (box,L(P(0, 8,0),P(8,0,0)));
check_no_intersection (box,L(P(0,-8,0),P(-8,0,0)));
check_no_intersection (box,L(P(0, 8,0),P(-8,0,0)));
//Intersecting
//xz
check_intersection<S> (box,L(P(-0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P( 0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P( 0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P(-0.5,0,0),P(0,0,-0.5)));
check_intersection<S> (box,L(P( 0.5,0,0),P(0,0,-0.5)));
//yz
check_intersection<S> (box,L(P(0,-0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P(0, 0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P(0, 0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,L(P(0,-0.5,0),P(0,0,-0.5)));
check_intersection<S> (box,L(P(0, 0.5,0),P(0,0,-0.5)));
//xy
check_intersection<S> (box,L(P(0,-0.5,0),P(0.5,0,0)));
check_intersection<S> (box,L(P(0, 0.5,0),P(0.5,0,0)));
check_intersection<S> (box,L(P(0, 0.5,0),P(0.5,0,0)));
check_intersection<S> (box,L(P(0,-0.5,0),P(-0.5,0,0)));
check_intersection<S> (box,L(P(0, 0.5,0),P(-0.5,0,0)));
}
void Bbox_R(){
std::cout << "Bbox - Ray\n";
Bbox box(-1,-1,-1,1,1,1);
//not in x,y,z slab
check_no_intersection (box,R(P(2,0,0),P(2,0,0.5)));
check_no_intersection (box,R(P(0,2,0),P(0,2,0.5)));
@ -457,33 +456,33 @@ struct Test {
//in each slab, time not matching
//xz
check_no_intersection (box,R(P(-8,0,0),P(0,0, 8)));
check_no_intersection (box,R(P( 8,0,0),P(0,0, 8)));
check_no_intersection (box,R(P( 8,0,0),P(0,0, 8)));
check_no_intersection (box,R(P(-8,0,0),P(0,0,-8)));
check_no_intersection (box,R(P( 8,0,0),P(0,0,-8)));
//yz
check_no_intersection (box,R(P(0,-8,0),P(0,0, 8)));
check_no_intersection (box,R(P(0, 8,0),P(0,0, 8)));
check_no_intersection (box,R(P(0, 8,0),P(0,0, 8)));
check_no_intersection (box,R(P(0,-8,0),P(0,0,-8)));
check_no_intersection (box,R(P(0, 8,0),P(0,0,-8)));
//xy
check_no_intersection (box,R(P(0,-8,0),P(8,0,0)));
check_no_intersection (box,R(P(0, 8,0),P(8,0,0)));
check_no_intersection (box,R(P(0, 8,0),P(8,0,0)));
check_no_intersection (box,R(P(0,-8,0),P(-8,0,0)));
check_no_intersection (box,R(P(0, 8,0),P(-8,0,0)));
//Intersecting
//xz
check_intersection<S> (box,R(P(-0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P( 0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P( 0.5,0,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P(-0.5,0,0),P(0,0,-0.5)));
check_intersection<S> (box,R(P( 0.5,0,0),P(0,0,-0.5)));
//yz
check_intersection<S> (box,R(P(0,-0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P(0, 0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P(0, 0.5,0),P(0,0, 0.5)));
check_intersection<S> (box,R(P(0,-0.5,0),P(0,0,-0.5)));
check_intersection<S> (box,R(P(0, 0.5,0),P(0,0,-0.5)));
//xy
check_intersection<S> (box,R(P(0,-0.5,0),P(0.5,0,0)));
check_intersection<S> (box,R(P(0, 0.5,0),P(0.5,0,0)));
check_intersection<S> (box,R(P(0, 0.5,0),P(0.5,0,0)));
check_intersection<S> (box,R(P(0,-0.5,0),P(-0.5,0,0)));
check_intersection<S> (box,R(P(0, 0.5,0),P(-0.5,0,0)));
}
@ -566,85 +565,400 @@ struct Test {
<< do_intersect_counter << "\n";
} // end function Bbox_Tr
void Tet_L()
void Tet_L(bool is_exact)
{
std::cout << "Tetrahedron_3 - Line_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, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0)));
check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25)));
check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0));
if(is_exact)
{
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)));
check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25)));
check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0));
}
}
void Tet_S()
void Tet_S(bool is_exact)
{
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, S(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));
if(is_exact)
{
check_no_intersection (tet, S(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)));
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)));
}
else
{
CGAL::intersection (tet, S(P(0,2,0), P(0,-2,0)));
CGAL::intersection (tet, S(P(0,1,0), P(0.25,0,0.25)));
CGAL::intersection (tet, S(P(2,1,0), P(-2,1,0)));
CGAL::intersection (tet, S(P(0.1,0.1,0.1), P(0.2,0.2,0.2)));
CGAL::intersection (tet, S(P(0.25,0.25,0.25), P(2,2,2)));
}
}
void Tet_R()
void Tet_R(bool is_exact)
{
std::cout << "Tetrahedron_3 - Ray_3\n";
Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1));
check_no_intersection (tet, R(P(5,0,0), P(5,1,0)));
if(is_exact)
{
check_no_intersection (tet, R(P(5,0,0), P(5,1,0)));
check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0)));
check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25)));
check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0));
check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0)));
check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25)));
check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0));
typename K::FT coord = 1.0/3.0;
check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord)));
check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord)));
typename K::FT coord = 1.0/3.0;
check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord)));
check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord)));
}
else
{
CGAL::intersection (tet, R(P(0,2,0), P(0,-2,0)));
CGAL::intersection (tet, R(P(0,1,0), P(0.25,0,0.25)));
CGAL::intersection (tet, R(P(2,1,0), P(-2,1,0)));
CGAL::intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)));
CGAL::intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)));
}
}
void Tet_Pl()
void Tet_Pl(bool is_exact)
{
std::cout << "Tetrahedron_3 - Plane_3\n";
Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1));
check_no_intersection (tet, Pl(P(2,0,0),
P(2,1,0),
P(2,0,1)));
if(is_exact)
{
check_no_intersection (tet, Pl(P(2,0,0),
P(2,1,0),
P(2,0,1)));
check_intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)),
Tr(P(0,0,0), P(0,1,0), P(0,0,1)));
check_intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)),
Tr(P(0,0,0), P(0,1,0), P(0,0,1)));
check_intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)),
S(P(0,1,0), P(1,0,0)));
check_intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)),
S(P(0,1,0), P(1,0,0)));
check_intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)),
P(0,1,0));
check_intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)),
P(0,1,0));
check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)),
Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5)));
Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06));
check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)),
Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5)));
Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06));
typedef typename CGAL::Intersection_traits<K,
typename K::Tetrahedron_3,
typename K::Plane_3>::result_type Res;
//Don't have the right values to test further.
Res res = CGAL::intersection (tet, pl);
const std::vector<P>* poly = boost::get<std::vector<P> >(&*res);
CGAL_assertion(poly != nullptr);
CGAL_assertion(poly->size() == 4);
}
else
{
CGAL::intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)));
CGAL::intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)));
CGAL::intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)));
CGAL::intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)));
}
}
void Tet_Tr(bool is_exact)
{
std::cout << "Tetrahedron_3 - Triangle_3\n";
typedef typename CGAL::Intersection_traits<K,
typename K::Tetrahedron_3,
typename K::Plane_3>::result_type Res;
assert(CGAL::do_intersect(tet, pl));
//Don't have the right values to test further.
typename K::Triangle_3>::result_type Res;
Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1));
if(is_exact)
{
check_no_intersection (tet, Tr(P(2,0,0),
P(2,1,0),
P(2,0,1)));
//tr inside a face
check_intersection (tet, Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9)),
Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9)));
//face inside tr
check_intersection (tet, Tr(P(0,2,0), P(0,-2,0), P(0,0,2)),
Tr(P(0,0,1), P(0,0,0), P(0,1,0)));
Tr tr(P(-2,2,0), P(2,2,0), P(0.25,0.25,0));
Res res = CGAL::intersection(tet, tr);
const std::vector<P>* poly = boost::get<std::vector<P> >(&*res);
CGAL_assertion(poly != nullptr);
CGAL_assertion(poly->size() == 4);
for(auto p : *poly)
{
CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p));
}
//only one edge intersecting
check_intersection (tet, Tr(P(-2, 0.5, 0.5), P(-2,0.75,1), P(1.5, 0.5, 0.5)),
P(0,0.5,0.5));
//edge shared, 3rd point outside
check_intersection (tet, Tr(P(0,1,0), P(1,0,0), P(0.5,0,-100)),
S(P(0,1,0), P(1,0,0)));
//shared edge, 3rd point inside
check_intersection (tet, Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25)),
Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25)));
//tr adjacent to a vertex, outside
check_intersection (tet, Tr(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)),
P(0,1,0));
//tr adjacent to an edge, outside
check_intersection (tet, Tr(P(-0.6, 1, 0.6),
P(0.5, 1.20, -0.5),
P(0, -0.5, 0)),
S(P(0,0,0), P(0,1,0)));
//tr share a vertex, inside
check_intersection (tet, Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0)),
Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0)));
//tr edge adjacent to a vertex
check_intersection (tet, Tr(P(-1,1,0), P(3,1,0), P(0,3,0)),
P(0,1,0));
//tr vertex adjacent to a vertex
check_intersection (tet, Tr(P(0,1,0), P(3,1,0), P(0,3,0)),
P(0,1,0));
//traversing triangles
tr = Tr(P(-2, 0.5, 0.25),
P(-2, 0.75, 0.6),
P(1.5, 0.5, 0.25));
res = CGAL::intersection(tet, tr);
std::vector<P>* inter = boost::get<std::vector<P> >(&*res);
CGAL_assertion(inter != nullptr);
CGAL_assertion(inter->size() == 4);
for(auto p : *inter)
{
CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p));
}
tr = Tr(P(-2, 0.25, 0),
P(-2, 0.75, 0),
P(1.5, 0.5, 0));
res = CGAL::intersection(tet, tr);
inter = boost::get<std::vector<P> >(&*res);
CGAL_assertion(inter != nullptr);
CGAL_assertion(inter->size() == 4);
for(auto p : *inter)
{
CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p));
}
tr = Tr(P(0.2, 0.15, 0.3),
P(-2, 0.6, 0.15),
P(-2, 0.12, 0.15));
res = CGAL::intersection(tet, tr);
Tr* res_tr = boost::get<Tr>(&*res);
CGAL_assertion(res_tr != nullptr);
tr = Tr(P(0.2, 0.15, 0.3),
P(-1, 0.15, -2),
P(-1, 0.15, 2));
res = CGAL::intersection(tet, tr);
inter = boost::get<std::vector<P> >(&*res);
CGAL_assertion(inter != nullptr);
CGAL_assertion(inter->size() == 4);
tr = Tr(P(0.45, 0.20, 0.1),
P(0.1, 0.20, 0.5),
P(-0.5, 0.25, -0.5));
res = CGAL::intersection(tet, tr);
inter = boost::get<std::vector<P> >(&*res);
CGAL_assertion(inter != nullptr);
CGAL_assertion(inter->size() == 4);
for(auto p : *inter)
{
CGAL_assertion(
(tet.has_on_bounded_side(p) || tet.has_on_boundary(p))
&& tr.has_on(p));
}
//tr share a vertex, through
tr = Tr(P(0,1,0), P(0.1,0.1,0), P(0.9,0.1,0));
res = CGAL::intersection(tet, tr);
res_tr = boost::get<Tr>(&*res);
CGAL_assertion(res_tr != nullptr);
tr = Tr(P(0.1, 0.5, 0.1), P(0.3,0.1,0.1), P(4,0.3,0.9));
res = CGAL::intersection(tet, tr);
inter = boost::get<std::vector<P> >(&*res);
CGAL_assertion(inter != nullptr);
CGAL_assertion(inter->size() == 4);
}
else
{
//tr inside a face
CGAL::intersection(tet, Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9)));
//face inside tr
CGAL::intersection(tet, Tr(P(0,2,0), P(0,-2,0), P(0,0,2)));
//only one edge intersecting
CGAL::intersection(tet, Tr(P(-2, 0.5, 0.5), P(-2,0.75,1), P(1.5, 0.5, 0.5)));
//edge shared, 3rd point outside
CGAL::intersection(tet, Tr(P(0,1,0), P(1,0,0), P(0.5,0,-100)));
//shared edge, 3rd point inside
CGAL::intersection(tet, Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25)));
//tr adjacent to a vertex, outside
CGAL::intersection(tet, Tr(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)));
//tr share a vertex, inside
CGAL::intersection(tet, Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0)));
//tr edge adjacent to a vertex
CGAL::intersection(tet, Tr(P(-1,1,0), P(3,1,0), P(0,3,0)));
//tr vertex adjacent to a vertex
CGAL::intersection(tet, Tr(P(0,1,0), P(3,1,0), P(0,3,0)));
typedef typename CGAL::Intersection_traits<K,
typename K::Tetrahedron_3,
typename K::Triangle_3>::result_type Res;
//traversing triangles
Tr tr(P(-2, 0.5, 0.25),
P(-2, 0.75, 0.6),
P(1.5, 0.5, 0.25));
Res res = CGAL::intersection(tet, tr);
//tr share a vertex, through
tr = Tr(P(0,1,0), P(0.1,0.1,0), P(0.9,0.1,0));
res = CGAL::intersection(tet, tr);
}
}
void Pl_Cub(bool is_exact)
{
std::cout << "Plane_3 - Cuboid_3\n";
Cub cub(P(1,1,1), P(2,2,2));
if(is_exact)
{
check_no_intersection (cub, Pl(P(3,0,0),
P(3,1,0),
P(3,0,1)));
//edge
check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)),
S(P(1,2,1), P(1,1,1)));
//face
typedef typename CGAL::Intersection_traits<K,
typename K::Plane_3,
typename K::Iso_cuboid_3>::result_type Res;
Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2)));
const std::vector<P>* poly = boost::get<std::vector<P> >(&*res);
CGAL_assertion(poly != nullptr);
CGAL_assertion(poly->size() == 4);
for(auto p : *poly)
{
CGAL_assertion(p.x() == 1);
}
res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2)));
poly = boost::get<std::vector<P> >(&*res);
CGAL_assertion(poly != nullptr);
CGAL_assertion(poly->size() == 4);
for(auto p : *poly)
{
CGAL_assertion(cub.has_on_boundary(p));
}
//vertex
check_intersection (cub, Pl(0.5, -0.5, -0.5, 0),
P(2,1,1));
//triangle
check_intersection (cub, Pl(P(2, 1.66, 2),
P(1.66,2,2),
P(2,2,1.66)),
Tr(P(2, 1.66, 2),
P(1.66,2,2),
P(2,2,1.66)));
//random
Pl pl(0.265189, 0.902464, 0.33946, -2.47551);
res = CGAL::intersection(cub, pl);
poly = boost::get<std::vector<P> >(&*res);
CGAL_assertion(poly != nullptr);
CGAL_assertion(poly->size() == 5);
for(auto p : *poly)
{
CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p));
}
}
else
{
CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)));
//face
typedef typename CGAL::Intersection_traits<K,
typename K::Plane_3,
typename K::Iso_cuboid_3>::result_type Res;
Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2)));
res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2)));
CGAL::intersection (cub, Pl(0.5, -0.5, -0.5, 0));
CGAL::intersection (cub, Pl(P(2, 1.66, 2),
P(1.66,2,2),
P(2,2,1.66)));
Pl pl(0.265189, 0.902464, 0.33946, -2.47551);
res = CGAL::intersection(cub, pl);
}
}
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();
@ -658,12 +972,15 @@ struct Test {
R_L();
R_S();
R_R();*/
if(is_exact){
Tet_L();
Tet_S();
Tet_R();
Tet_Pl();
}
//If not exact, only check that it doesn't crash{
//Tet_L(is_exact);
//Tet_S(is_exact);
//Tet_R(is_exact);
//Tet_Pl(is_exact);
Tet_Tr(is_exact);
// Pl_Cub(is_exact);
//}
/*
Bbox_L();
Bbox_R();
@ -678,6 +995,6 @@ int main()
Test< CGAL::Simple_cartesian<double> >().run();
Test< CGAL::Homogeneous<CGAL::MP_Float> >().run();
Test< CGAL::Epeck >().run(true);
// TODO : test more kernels.
// TODO : test more kernels.
}