Add a lot more testing to Intersections_3

This commit is contained in:
Mael Rouxel-Labbé 2021-06-23 17:39:52 +02:00
parent 9ed943e92f
commit d1b456cd70
17 changed files with 3229 additions and 1905 deletions

View File

@ -1,30 +1,16 @@
#include <CGAL/use.h> #include <CGAL/use.h>
#include <CGAL/Cartesian.h> #include <CGAL/Cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/intersections.h>
// This just tests if every call we promise is actually available // This just tests if every call we promise is actually available
typedef CGAL::Exact_predicates_exact_constructions_kernel Epic;
typedef CGAL::Cartesian<double> Cartesian;
typedef Epic K;
typedef CGAL::Point_3< K > P;
typedef CGAL::Segment_3< K > S;
typedef CGAL::Line_3< K > L;
typedef CGAL::Plane_3< K > Pl;
typedef CGAL::Triangle_3< K > Tr;
typedef CGAL::Ray_3< K > R;
typedef CGAL::Iso_cuboid_3< K > Cub;
typedef CGAL::Sphere_3< K > Sph;
typedef CGAL::Circle_3< K > C;
typedef CGAL::Tetrahedron_3< K > T;
typedef CGAL::Bbox_3 Bbox_3;
template<class A, class B> template<class A, class B>
void call_intersection_global(const A& a, const B& b) { void call_intersection_global(const A& a, const B& b)
{
const auto x = CGAL::intersection(a, b); const auto x = CGAL::intersection(a, b);
const auto y = CGAL::intersection(b, a); const auto y = CGAL::intersection(b, a);
const auto z = CGAL::intersection(b, a); const auto z = CGAL::intersection(b, a);
@ -34,188 +20,349 @@ void call_intersection_global(const A& a, const B& b) {
} }
template<class A, class B> template<class A, class B>
void call_do_intersect_global(const A& a, const B& b) { void call_do_intersect_global(const A& a, const B& b)
CGAL::do_intersect(a, b);
CGAL::do_intersect(b, a);
}
template<class A, class B, class K>
void call_intersection_with_kernel(const A& a, const B& b, const K&) {
typedef typename K::Intersect_3 Intersect;
const auto x = Intersect()(a, b);
const auto y = Intersect()(b, a);
}
template<class A, class B, class K>
void call_do_intersect_with_kernel(const A& a, const B& b, const K&) {
typedef typename K::Do_intersect_3 Do_inter;
Do_inter()(a, b);
Do_inter()(b, a);
}
int main(int argc, char**)
{ {
CGAL::Interval_nt_advanced::Protector p; const auto x = CGAL::do_intersect(a, b);
CGAL_USE(p); const auto y = CGAL::do_intersect(b, a);
//we only want to check compilation CGAL_USE(x);
if(argc > 666 ) CGAL_USE(y);
{ }
call_intersection_global(S(), S());
call_intersection_global(S(), L());
call_intersection_global(S(), Pl());
call_intersection_global(S(), Tr());
call_intersection_global(S(), R());
call_intersection_global(S(), Cub());
call_intersection_global(L(), S()); template<class A, class B, class K>
void call_intersection_with_kernel(const A& a, const B& b, const K& k)
{
typename K::Intersect_3 intersect = k.intersect_3_object();
const auto x = intersect(a, b);
const auto y = intersect(b, a);
CGAL_USE(x);
CGAL_USE(y);
}
template<class A, class B, class K>
void call_do_intersect_with_kernel(const A& a, const B& b, const K& k)
{
typename K::Do_intersect_3 do_intersect = k.do_intersect_3_object();
const bool x = do_intersect(a, b);
const bool y = do_intersect(b, a);
CGAL_USE(x);
CGAL_USE(y);
}
template <typename K>
void test(const int argc)
{
typedef CGAL::Iso_cuboid_3< K > Cub;
typedef CGAL::Line_3< K > L;
typedef CGAL::Plane_3< K > Pl;
typedef CGAL::Point_3< K > P;
typedef CGAL::Ray_3< K > R;
typedef CGAL::Segment_3< K > S;
typedef CGAL::Sphere_3< K > Sph;
typedef CGAL::Triangle_3< K > Tr;
typedef CGAL::Tetrahedron_3< K > T;
typedef CGAL::Bbox_3 Bbox_3;
//we only want to check compilation
if(argc > 0)
{
// ---------------------------------------------------------------------------------------------
// INTERSECTION
// ---------------------------------------------------------------------------------------------
call_intersection_global(Cub(), Bbox_3());
call_intersection_global(Cub(), Cub());
call_intersection_global(Cub(), L());
call_intersection_global(Cub(), Pl());
call_intersection_global(Cub(), P());
call_intersection_global(Cub(), R());
call_intersection_global(Cub(), S());
call_intersection_global(Cub(), Tr());
call_intersection_global(L(), Bbox_3());
call_intersection_global(L(), Cub());
call_intersection_global(L(), L()); call_intersection_global(L(), L());
call_intersection_global(L(), Pl()); call_intersection_global(L(), Pl());
call_intersection_global(L(), Tr()); call_intersection_global(L(), P());
call_intersection_global(L(), R()); call_intersection_global(L(), R());
call_intersection_global(L(), Cub()); call_intersection_global(L(), S());
call_intersection_global(L(), T());
call_intersection_global(L(), Tr());
call_intersection_global(Pl(), S()); call_intersection_global(Pl(), Bbox_3());
call_intersection_global(Pl(), Cub());
call_intersection_global(Pl(), L()); call_intersection_global(Pl(), L());
call_intersection_global(Pl(), Pl()); call_intersection_global(Pl(), Pl());
call_intersection_global(Pl(), Tr()); call_intersection_global(Pl(), P());
call_intersection_global(Pl(), R()); call_intersection_global(Pl(), R());
// call_intersection_global(Pl(), Cub()); call_intersection_global(Pl(), S());
call_intersection_global(Pl(), Sph());
call_intersection_global(Pl(), Tr());
call_intersection_global(Pl(), T());
// special auto plplpl = CGAL::intersection(Pl(), Pl(), Pl());
const auto plplpl = CGAL::intersection(Pl(), Pl(), Pl()); CGAL_USE(plplpl);
call_intersection_global(Tr(), S()); call_intersection_global(P(), Bbox_3());
call_intersection_global(Tr(), L()); call_intersection_global(P(), Cub());
call_intersection_global(Tr(), Pl()); call_intersection_global(P(), L());
call_intersection_global(Tr(), Tr()); call_intersection_global(P(), Pl());
call_intersection_global(Tr(), R()); call_intersection_global(P(), P());
// call_intersection_global(Tr(), Cub()); call_intersection_global(P(), R());
call_intersection_global(P(), S());
call_intersection_global(P(), Sph());
call_intersection_global(P(), Tr());
call_intersection_global(P(), T());
call_intersection_global(R(), S()); call_intersection_global(R(), Bbox_3());
call_intersection_global(R(), Cub());
call_intersection_global(R(), L()); call_intersection_global(R(), L());
call_intersection_global(R(), Pl()); call_intersection_global(R(), Pl());
call_intersection_global(R(), Tr()); call_intersection_global(R(), P());
call_intersection_global(R(), R()); call_intersection_global(R(), R());
call_intersection_global(R(), Cub()); call_intersection_global(R(), S());
call_intersection_global(R(), Tr());
call_intersection_global(R(), T());
call_intersection_global(Cub(), S()); call_intersection_global(S(), Bbox_3());
call_intersection_global(Cub(), L()); call_intersection_global(S(), Cub());
// call_intersection_global(Cub(), Pl()); call_intersection_global(S(), L());
// call_intersection_global(Cub(), Tr()); call_intersection_global(S(), Pl());
call_intersection_global(Cub(), R()); call_intersection_global(S(), P());
call_intersection_global(Cub(), Cub()); call_intersection_global(S(), R());
// call_intersection_global(Cub(), Bbox_3()); call_intersection_global(S(), S());
call_intersection_global(S(), T());
call_intersection_global(S(), Tr());
call_intersection_global(Sph(), Pl());
call_intersection_global(Sph(), P());
call_intersection_global(Sph(), Sph());
call_intersection_global(Tr(), Bbox_3());
call_intersection_global(Tr(), Cub());
call_intersection_global(Tr(), L());
call_intersection_global(Tr(), Pl());
call_intersection_global(Tr(), P());
call_intersection_global(Tr(), R());
call_intersection_global(Tr(), S());
call_intersection_global(Tr(), Tr());
call_intersection_global(Tr(), T());
call_intersection_global(T(), L());
call_intersection_global(T(), Pl());
call_intersection_global(T(), P());
call_intersection_global(T(), R());
call_intersection_global(T(), S());
call_intersection_global(T(), Tr());
const auto bbbb = CGAL::intersection(Bbox_3(), Bbox_3());
CGAL_USE(bbbb);
call_intersection_global(Bbox_3(), L());
call_intersection_global(Bbox_3(), S());
call_intersection_global(Bbox_3(), R());
call_intersection_global(Bbox_3(), Cub()); call_intersection_global(Bbox_3(), Cub());
CGAL::intersection(Bbox_3(), Bbox_3()); call_intersection_global(Bbox_3(), L());
call_intersection_global(Bbox_3(), Pl());
call_intersection_global(Bbox_3(), P());
call_intersection_global(Bbox_3(), R());
call_intersection_global(Bbox_3(), S());
call_intersection_global(Bbox_3(), Tr());
call_intersection_global(T(), L()); call_intersection_global(T(), L());
// with kernel // with kernel
call_intersection_with_kernel(Cub(), Bbox_3(), K());
call_intersection_with_kernel(Cub(), Cub(), K());
call_intersection_with_kernel(Cub(), L(), K());
call_intersection_with_kernel(Cub(), Pl(), K());
call_intersection_with_kernel(Cub(), P(), K());
call_intersection_with_kernel(Cub(), R(), K());
call_intersection_with_kernel(Cub(), S(), K());
call_intersection_with_kernel(Cub(), Tr(), K());
call_intersection_with_kernel(S(), S(), K()); call_intersection_with_kernel(L(), Bbox_3(), K());
call_intersection_with_kernel(S(), L(), K()); call_intersection_with_kernel(L(), Cub(), K());
call_intersection_with_kernel(S(), Pl(), K());
call_intersection_with_kernel(S(), Tr(), K());
call_intersection_with_kernel(S(), R(), K());
call_intersection_with_kernel(S(), Cub(), K());
call_intersection_with_kernel(L(), S(), K());
call_intersection_with_kernel(L(), L(), K()); call_intersection_with_kernel(L(), L(), K());
call_intersection_with_kernel(L(), Pl(), K()); call_intersection_with_kernel(L(), Pl(), K());
call_intersection_with_kernel(L(), Tr(), K()); call_intersection_with_kernel(L(), P(), K());
call_intersection_with_kernel(L(), R(), K()); call_intersection_with_kernel(L(), R(), K());
call_intersection_with_kernel(L(), Cub(), K()); call_intersection_with_kernel(L(), S(), K());
call_intersection_with_kernel(L(), Tr(), K());
call_intersection_with_kernel(L(), T(), K());
call_intersection_with_kernel(Pl(), S(), K()); call_intersection_with_kernel(Pl(), Bbox_3(), K());
call_intersection_with_kernel(Pl(), Cub(), K());
call_intersection_with_kernel(Pl(), L(), K()); call_intersection_with_kernel(Pl(), L(), K());
call_intersection_with_kernel(Pl(), Pl(), K()); call_intersection_with_kernel(Pl(), Pl(), K());
call_intersection_with_kernel(Pl(), Tr(), K()); call_intersection_with_kernel(Pl(), P(), K());
call_intersection_with_kernel(Pl(), R(), K()); call_intersection_with_kernel(Pl(), R(), K());
// call_intersection_with_kernel(Pl(), Cub(), K()); call_intersection_with_kernel(Pl(), S(), K());
call_intersection_with_kernel(Pl(), Tr(), K());
call_intersection_with_kernel(Pl(), T(), K());
//special //special
K::Intersect_3()(Pl(), Pl(), Pl()); plplpl = K().intersect_3_object()(Pl(), Pl(), Pl());
CGAL_USE(plplpl);
call_intersection_with_kernel(Tr(), S(), K()); call_intersection_with_kernel(P(), Bbox_3(), K());
call_intersection_with_kernel(Tr(), L(), K()); call_intersection_with_kernel(P(), Cub(), K());
call_intersection_with_kernel(Tr(), Pl(), K()); call_intersection_with_kernel(P(), L(), K());
call_intersection_with_kernel(Tr(), Tr(), K()); call_intersection_with_kernel(P(), Pl(), K());
call_intersection_with_kernel(Tr(), R(), K()); call_intersection_with_kernel(P(), P(), K());
// call_intersection_with_kernel(Tr(), Cub(), K()); call_intersection_with_kernel(P(), R(), K());
call_intersection_with_kernel(P(), S(), K());
call_intersection_with_kernel(P(), Sph(), K());
call_intersection_with_kernel(P(), Tr(), K());
call_intersection_with_kernel(P(), T(), K());
call_intersection_with_kernel(R(), S(), K()); call_intersection_with_kernel(R(), Bbox_3(), K());
call_intersection_with_kernel(R(), Cub(), K());
call_intersection_with_kernel(R(), L(), K()); call_intersection_with_kernel(R(), L(), K());
call_intersection_with_kernel(R(), Pl(), K()); call_intersection_with_kernel(R(), Pl(), K());
call_intersection_with_kernel(R(), Tr(), K()); call_intersection_with_kernel(R(), P(), K());
call_intersection_with_kernel(R(), R(), K()); call_intersection_with_kernel(R(), R(), K());
call_intersection_with_kernel(R(), Cub(), K()); call_intersection_with_kernel(R(), S(), K());
call_intersection_with_kernel(R(), Tr(), K());
call_intersection_with_kernel(R(), T(), K());
call_intersection_with_kernel(Cub(), S(), K()); call_intersection_with_kernel(S(), Bbox_3(), K());
call_intersection_with_kernel(Cub(), L(), K()); call_intersection_with_kernel(S(), Cub(), K());
// call_intersection_with_kernel(Cub(), Pl(), K()); call_intersection_with_kernel(S(), L(), K());
// call_intersection_with_kernel(Cub(), Tr(), K()); call_intersection_with_kernel(S(), Pl(), K());
call_intersection_with_kernel(Cub(), R(), K()); call_intersection_with_kernel(S(), P(), K());
call_intersection_with_kernel(Cub(), Cub(), K()); call_intersection_with_kernel(S(), R(), K());
call_intersection_with_kernel(S(), S(), K());
call_intersection_with_kernel(S(), Tr(), K());
call_intersection_with_kernel(S(), T(), K());
call_intersection_with_kernel(Sph(), Pl(), K());
call_intersection_with_kernel(Sph(), P(), K());
call_intersection_with_kernel(Sph(), Sph(), K());
call_intersection_with_kernel(Tr(), Bbox_3(), K());
call_intersection_with_kernel(Tr(), Cub(), K());
call_intersection_with_kernel(Tr(), L(), K());
call_intersection_with_kernel(Tr(), Pl(), K());
call_intersection_with_kernel(Tr(), P(), K());
call_intersection_with_kernel(Tr(), R(), K());
call_intersection_with_kernel(Tr(), S(), K());
call_intersection_with_kernel(Tr(), Tr(), K());
call_intersection_with_kernel(Tr(), T(), K());
call_intersection_with_kernel(T(), L(), K());
call_intersection_with_kernel(T(), Pl(), K());
call_intersection_with_kernel(T(), P(), K());
call_intersection_with_kernel(T(), R(), K());
call_intersection_with_kernel(T(), S(), K());
call_intersection_with_kernel(T(), Tr(), K());
call_intersection_with_kernel(Bbox_3(), Cub(), K());
call_intersection_with_kernel(Bbox_3(), L(), K()); call_intersection_with_kernel(Bbox_3(), L(), K());
call_intersection_with_kernel(Bbox_3(), S(), K()); call_intersection_with_kernel(Bbox_3(), Pl(), K());
call_intersection_with_kernel(Bbox_3(), P(), K());
call_intersection_with_kernel(Bbox_3(), R(), K()); call_intersection_with_kernel(Bbox_3(), R(), K());
call_intersection_with_kernel(Bbox_3(), S(), K());
call_intersection_with_kernel(Bbox_3(), Tr(), K());
// The doc defines calls to do_intersect for these objects // ---------------------------------------------------------------------------------------------
// DO INTERSECT
// ---------------------------------------------------------------------------------------------
// Plane_3<Kernel> call_do_intersect_global(L(), Cub());
// Line_3<Kernel> call_do_intersect_global(L(), Bbox_3());
// Ray_3<Kernel>
// Segment_3<Kernel>
// Triangle_3<Kernel>.
// Bbox_3.
call_do_intersect_global(Pl(), Pl());
call_do_intersect_global(Pl(), L());
call_do_intersect_global(Pl(), R());
call_do_intersect_global(Pl(), S());
call_do_intersect_global(Pl(), Tr());
call_do_intersect_global(Pl(), Bbox_3());
call_do_intersect_global(L(), Pl());
call_do_intersect_global(L(), L()); call_do_intersect_global(L(), L());
call_do_intersect_global(L(), Pl());
call_do_intersect_global(L(), P());
call_do_intersect_global(L(), R()); call_do_intersect_global(L(), R());
call_do_intersect_global(L(), S()); call_do_intersect_global(L(), S());
call_do_intersect_global(L(), Sph());
call_do_intersect_global(L(), Tr()); call_do_intersect_global(L(), Tr());
call_do_intersect_global(L(), Bbox_3()); call_do_intersect_global(L(), T());
call_do_intersect_global(R(), Pl()); call_do_intersect_global(Pl(), Bbox_3());
call_do_intersect_global(Pl(), Cub());
call_do_intersect_global(Pl(), L());
call_do_intersect_global(Pl(), Pl());
call_do_intersect_global(Pl(), P());
call_do_intersect_global(Pl(), R());
call_do_intersect_global(Pl(), S());
call_do_intersect_global(Pl(), Sph());
call_do_intersect_global(Pl(), Tr());
call_do_intersect_global(Pl(), T());
call_do_intersect_global(P(), Bbox_3());
call_do_intersect_global(P(), Cub());
call_do_intersect_global(P(), L());
call_do_intersect_global(P(), Pl());
call_do_intersect_global(P(), P());
call_do_intersect_global(P(), R());
call_do_intersect_global(P(), S());
call_do_intersect_global(P(), Sph());
call_do_intersect_global(P(), Tr());
call_do_intersect_global(P(), T());
call_do_intersect_global(R(), Bbox_3());
call_do_intersect_global(R(), Cub());
call_do_intersect_global(R(), L()); call_do_intersect_global(R(), L());
call_do_intersect_global(R(), Pl());
call_do_intersect_global(R(), P());
call_do_intersect_global(R(), R()); call_do_intersect_global(R(), R());
call_do_intersect_global(R(), S()); call_do_intersect_global(R(), S());
call_do_intersect_global(R(), Tr()); call_do_intersect_global(R(), Tr());
call_do_intersect_global(R(), Bbox_3()); call_do_intersect_global(R(), T());
call_do_intersect_global(S(), Bbox_3());
call_do_intersect_global(S(), Cub());
call_do_intersect_global(S(), Pl()); call_do_intersect_global(S(), Pl());
call_do_intersect_global(S(), P());
call_do_intersect_global(S(), L()); call_do_intersect_global(S(), L());
call_do_intersect_global(S(), R()); call_do_intersect_global(S(), R());
call_do_intersect_global(S(), S()); call_do_intersect_global(S(), S());
call_do_intersect_global(S(), Sph());
call_do_intersect_global(S(), Tr()); call_do_intersect_global(S(), Tr());
call_do_intersect_global(S(), Bbox_3()); call_do_intersect_global(S(), T());
call_do_intersect_global(Tr(), Pl()); call_do_intersect_global(Sph(), Bbox_3());
call_do_intersect_global(Sph(), Cub());
call_do_intersect_global(Sph(), Pl());
call_do_intersect_global(Sph(), P());
call_do_intersect_global(Sph(), L());
call_do_intersect_global(Sph(), R());
call_do_intersect_global(Sph(), S());
call_do_intersect_global(Sph(), Sph());
call_do_intersect_global(Sph(), Tr());
call_do_intersect_global(Sph(), T());
call_do_intersect_global(Tr(), Bbox_3());
call_do_intersect_global(Tr(), Cub());
call_do_intersect_global(Tr(), L()); call_do_intersect_global(Tr(), L());
call_do_intersect_global(Tr(), Pl());
call_do_intersect_global(Tr(), P());
call_do_intersect_global(Tr(), R()); call_do_intersect_global(Tr(), R());
call_do_intersect_global(Tr(), S()); call_do_intersect_global(Tr(), S());
call_do_intersect_global(Tr(), Sph());
call_do_intersect_global(Tr(), Tr()); call_do_intersect_global(Tr(), Tr());
call_do_intersect_global(Tr(), Bbox_3()); call_do_intersect_global(Tr(), T());
call_do_intersect_global(Tr(), Pl()); call_do_intersect_global(Tr(), Bbox_3());
call_do_intersect_global(Tr(), Cub());
call_do_intersect_global(Tr(), L()); call_do_intersect_global(Tr(), L());
call_do_intersect_global(Tr(), Pl());
call_do_intersect_global(Tr(), P());
call_do_intersect_global(Tr(), R()); call_do_intersect_global(Tr(), R());
call_do_intersect_global(Tr(), S()); call_do_intersect_global(Tr(), S());
call_do_intersect_global(Tr(), Sph());
call_do_intersect_global(Tr(), Tr()); call_do_intersect_global(Tr(), Tr());
call_do_intersect_global(Tr(), Bbox_3()); call_do_intersect_global(Tr(), T());
call_do_intersect_global(T(), Bbox_3());
call_do_intersect_global(T(), Cub());
call_do_intersect_global(T(), L());
call_do_intersect_global(T(), Pl());
call_do_intersect_global(T(), P());
call_do_intersect_global(T(), R());
call_do_intersect_global(T(), S());
call_do_intersect_global(T(), Sph());
call_do_intersect_global(T(), Tr());
call_do_intersect_global(T(), T());
call_do_intersect_global(Bbox_3(), Pl()); call_do_intersect_global(Bbox_3(), Pl());
call_do_intersect_global(Bbox_3(), L()); call_do_intersect_global(Bbox_3(), L());
@ -226,54 +373,97 @@ int main(int argc, char**)
call_do_intersect_global(Bbox_3(), Bbox_3()); call_do_intersect_global(Bbox_3(), Bbox_3());
// with_kernel // with_kernel
call_do_intersect_with_kernel(Pl(), Pl(), K()); call_do_intersect_with_kernel(L(), Bbox_3(), K());
call_do_intersect_with_kernel(Pl(), L(), K()); call_do_intersect_with_kernel(L(), Cub(), K());
call_do_intersect_with_kernel(Pl(), R(), K());
call_do_intersect_with_kernel(Pl(), S(), K());
call_do_intersect_with_kernel(Pl(), Tr(), K());
call_do_intersect_with_kernel(Pl(), Bbox_3(), K());
call_do_intersect_with_kernel(L(), Pl(), K());
call_do_intersect_with_kernel(L(), L(), K()); call_do_intersect_with_kernel(L(), L(), K());
call_do_intersect_with_kernel(L(), Pl(), K());
call_do_intersect_with_kernel(L(), P(), K());
call_do_intersect_with_kernel(L(), R(), K()); call_do_intersect_with_kernel(L(), R(), K());
call_do_intersect_with_kernel(L(), S(), K()); call_do_intersect_with_kernel(L(), S(), K());
call_do_intersect_with_kernel(L(), Sph(), K());
call_do_intersect_with_kernel(L(), Tr(), K()); call_do_intersect_with_kernel(L(), Tr(), K());
call_do_intersect_with_kernel(L(), Bbox_3(), K()); call_do_intersect_with_kernel(L(), T(), K());
call_do_intersect_with_kernel(R(), Pl(), K()); call_do_intersect_with_kernel(Pl(), Bbox_3(), K());
call_do_intersect_with_kernel(Pl(), Cub(), K());
call_do_intersect_with_kernel(Pl(), L(), K());
call_do_intersect_with_kernel(Pl(), Pl(), K());
call_do_intersect_with_kernel(Pl(), P(), K());
call_do_intersect_with_kernel(Pl(), R(), K());
call_do_intersect_with_kernel(Pl(), S(), K());
call_do_intersect_with_kernel(Pl(), Sph(), K());
call_do_intersect_with_kernel(Pl(), Tr(), K());
call_do_intersect_with_kernel(Pl(), T(), K());
call_do_intersect_with_kernel(P(), Bbox_3(), K());
call_do_intersect_with_kernel(P(), Cub(), K());
call_do_intersect_with_kernel(P(), L(), K());
call_do_intersect_with_kernel(P(), Pl(), K());
call_do_intersect_with_kernel(P(), P(), K());
call_do_intersect_with_kernel(P(), R(), K());
call_do_intersect_with_kernel(P(), S(), K());
call_do_intersect_with_kernel(P(), Sph(), K());
call_do_intersect_with_kernel(P(), Tr(), K());
call_do_intersect_with_kernel(P(), T(), K());
call_do_intersect_with_kernel(R(), Bbox_3(), K());
call_do_intersect_with_kernel(R(), Cub(), K());
call_do_intersect_with_kernel(R(), L(), K()); call_do_intersect_with_kernel(R(), L(), K());
call_do_intersect_with_kernel(R(), Pl(), K());
call_do_intersect_with_kernel(R(), P(), K());
call_do_intersect_with_kernel(R(), R(), K()); call_do_intersect_with_kernel(R(), R(), K());
call_do_intersect_with_kernel(R(), S(), K()); call_do_intersect_with_kernel(R(), S(), K());
call_do_intersect_with_kernel(R(), Sph(), K());
call_do_intersect_with_kernel(R(), Tr(), K()); call_do_intersect_with_kernel(R(), Tr(), K());
call_do_intersect_with_kernel(R(), Bbox_3(), K()); call_do_intersect_with_kernel(R(), T(), K());
call_do_intersect_with_kernel(S(), Pl(), K()); call_do_intersect_with_kernel(S(), Bbox_3(), K());
call_do_intersect_with_kernel(S(), Cub(), K());
call_do_intersect_with_kernel(S(), R(), K());
call_do_intersect_with_kernel(S(), L(), K()); call_do_intersect_with_kernel(S(), L(), K());
call_do_intersect_with_kernel(S(), P(), K());
call_do_intersect_with_kernel(S(), R(), K()); call_do_intersect_with_kernel(S(), R(), K());
call_do_intersect_with_kernel(S(), S(), K()); call_do_intersect_with_kernel(S(), S(), K());
call_do_intersect_with_kernel(S(), Sph(), K());
call_do_intersect_with_kernel(S(), Tr(), K()); call_do_intersect_with_kernel(S(), Tr(), K());
call_do_intersect_with_kernel(S(), Bbox_3(), K()); call_do_intersect_with_kernel(S(), T(), K());
call_do_intersect_with_kernel(Tr(), Pl(), K()); call_do_intersect_with_kernel(Tr(), Bbox_3(), K());
call_do_intersect_with_kernel(Tr(), Cub(), K());
call_do_intersect_with_kernel(Tr(), R(), K());
call_do_intersect_with_kernel(Tr(), L(), K()); call_do_intersect_with_kernel(Tr(), L(), K());
call_do_intersect_with_kernel(Tr(), P(), K());
call_do_intersect_with_kernel(Tr(), R(), K()); call_do_intersect_with_kernel(Tr(), R(), K());
call_do_intersect_with_kernel(Tr(), S(), K()); call_do_intersect_with_kernel(Tr(), S(), K());
call_do_intersect_with_kernel(Tr(), Tr(), K()); call_do_intersect_with_kernel(Tr(), Tr(), K());
call_do_intersect_with_kernel(Tr(), Bbox_3(), K()); call_do_intersect_with_kernel(Tr(), T(), K());
call_do_intersect_with_kernel(Tr(), Pl(), K()); call_do_intersect_with_kernel(T(), Bbox_3(), K());
call_do_intersect_with_kernel(Tr(), L(), K()); call_do_intersect_with_kernel(T(), Cub(), K());
call_do_intersect_with_kernel(Tr(), R(), K()); call_do_intersect_with_kernel(T(), R(), K());
call_do_intersect_with_kernel(Tr(), S(), K()); call_do_intersect_with_kernel(T(), L(), K());
call_do_intersect_with_kernel(Tr(), Tr(), K()); call_do_intersect_with_kernel(T(), P(), K());
call_do_intersect_with_kernel(Tr(), Bbox_3(), K()); call_do_intersect_with_kernel(T(), R(), K());
call_do_intersect_with_kernel(T(), S(), K());
call_do_intersect_with_kernel(T(), Tr(), K());
call_do_intersect_with_kernel(T(), T(), K());
call_do_intersect_with_kernel(Bbox_3(), Pl(), K()); call_do_intersect_with_kernel(Bbox_3(), Cub(), K());
call_do_intersect_with_kernel(Bbox_3(), L(), K()); call_do_intersect_with_kernel(Bbox_3(), L(), K());
call_do_intersect_with_kernel(Bbox_3(), Pl(), K());
call_do_intersect_with_kernel(Bbox_3(), P(), K());
call_do_intersect_with_kernel(Bbox_3(), R(), K()); call_do_intersect_with_kernel(Bbox_3(), R(), K());
call_do_intersect_with_kernel(Bbox_3(), S(), K()); call_do_intersect_with_kernel(Bbox_3(), S(), K());
call_do_intersect_with_kernel(Bbox_3(), Sph(), K()); call_do_intersect_with_kernel(Bbox_3(), Sph(), K());
call_do_intersect_with_kernel(Bbox_3(), Tr(), K()); call_do_intersect_with_kernel(Bbox_3(), Tr(), K());
} }
}
int main(int argc, char**)
{
test<CGAL::Cartesian<double> >(argc);
test<CGAL::Exact_predicates_inexact_constructions_kernel>(argc);
test<CGAL::Exact_predicates_exact_constructions_kernel>(argc);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -4,21 +4,22 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK;
typedef EPICK::Point_3 Point; typedef EPICK::Point_3 Point;
int main() int main(int, char**)
{ {
EPICK::Plane_3 pl(Point(0, 0, 0), Point(1, 0, 0), Point(0, 1, 0));
std::vector<Point> pts; std::vector<Point> pts;
pts.push_back(Point(-10,-10,-10)); pts.emplace_back(-10,-10,-10);
pts.push_back(Point(10,10,10)); pts.emplace_back(10,10,10);
EPICK::Plane_3 pl(Point(0, 0, 0), Point(1, 0, 0), Point(0, 1, 0));
CGAL::Bbox_3 cub = CGAL::bbox_3(pts.begin(), pts.end()); CGAL::Bbox_3 cub = CGAL::bbox_3(pts.begin(), pts.end());
auto result = intersection(cub,pl); auto result = intersection(cub, pl);
const std::vector<Point>* res = boost::get <std::vector<Point> >(&*result); const std::vector<Point>* res = boost::get <std::vector<Point> >(&*result);
for (Point p : *res) { for(const Point& p : *res)
std::cout << p << std::endl; std::cout << p << std::endl;
}
assert(res->size() == 4);
return 0; return 0;
} }

View File

@ -1,80 +0,0 @@
#include <CGAL/Cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Quotient.h>
#include <cassert>
typedef CGAL::Quotient< CGAL::MP_Float > FT;
typedef CGAL::Cartesian<FT> K;
// The construction test has to be working
// The equal test has to be working
template <class K>
void _test_intersection_construct(K k)
{
typedef typename K::FT FT;
typedef typename K::Point_3 Point_3;
typedef typename K::Line_3 Line_3;
typedef typename K::Intersect_3 Intersect_3;
typedef typename K::Construct_line_3 Construct_line_3;
Intersect_3 theIntersect_3 = k.intersect_3_object();
Construct_line_3 theConstruct_line_3 = k.construct_line_3_object();
std::cout << "Testing intersection(Line, Line)..." << std::endl;
// Testing the case where it overlaps, or do not intersect
for(int vx=0;vx<4;vx++) {
for(int vy=1;vy<4;vy++) {
for(int vz=0;vz<4;vz++) {
if(vx == 0 && vy == 0 && vz == 0) continue;
const FT a = FT(vx);
const FT b = FT(vy);
const FT c = FT(vz);
Line_3 l = theConstruct_line_3(Point_3(0,0,0), Point_3(a,b,c));
Line_3 l_1 = theConstruct_line_3(Point_3(0,0,0), Point_3(-a,-b,-c));
Line_3 l_2 = theConstruct_line_3(Point_3(0,0,0), Point_3(-a,-b,7));
Line_3 l_3 = theConstruct_line_3(Point_3(1,0,0), Point_3(a,b,c));
Line_3 l_4 = theConstruct_line_3(Point_3(1,0,0), Point_3(a+1,b,c));
CGAL::Object obj1 = theIntersect_3(l, l_1);
CGAL::Object obj2 = theIntersect_3(l, l_2);
CGAL::Object obj3 = theIntersect_3(l, l_3);
CGAL::Object obj4 = theIntersect_3(l, l_4);
CGAL::Object obj1l = CGAL::intersection(l, l_1);
CGAL::Object obj2l = CGAL::intersection(l, l_2);
CGAL::Object obj3l = CGAL::intersection(l, l_3);
CGAL::Object obj4l = CGAL::intersection(l, l_4);
assert(CGAL::do_intersect(l, l_1));
assert(CGAL::do_intersect(l, l_2));
assert(CGAL::do_intersect(l, l_3));
assert(!CGAL::do_intersect(l, l_4));
Point_3 interp2, interp3;
Line_3 interl1;
assert(assign(interl1, obj1));
assert(assign(interp2, obj2));
assert(assign(interp3, obj3));
assert(obj4.is_empty());
assert(interp2 == Point_3(0,0,0));
assert(interp3 == Point_3(a,b,c));
Point_3 interp5, interp6;
Line_3 interl2;
assert(assign(interl2, obj1l));
assert(assign(interp5, obj2l));
assert(assign(interp6, obj3l));
assert(obj4l.is_empty());
assert(interp5 == Point_3(0,0,0));
assert(interp6 == Point_3(a,b,c));
}
}
}
std::cout << "OK!" << std::endl;
}
int main()
{
K k;
_test_intersection_construct(k);
return 0;
}

View File

@ -1,101 +0,0 @@
#if TESTR == 1
#include <CGAL/Cartesian.h>
inline double to_nt(int d)
{
return (double) d;
}
#endif
#if TESTR == 2
# include <CGAL/Homogeneous.h>
inline long to_nt(int d)
{
return d;
}
#endif
#if TESTR == 3
#include <CGAL/Cartesian.h>
#include <CGAL/test_types.h>
inline CGAL::TestfieldC to_nt(int d)
{
unsigned char dummy1 = 'a';
signed char dummy2 = 'a';
return CGAL::TestfieldC(dummy1, dummy2, (double)d);
}
#endif
#if TESTR == 4
#include <CGAL/Homogeneous.h>
#include <CGAL/test_types.h>
inline CGAL::TestrepH to_nt(int d)
{
unsigned char dummy1 = 'a';
signed char dummy2 = 'a';
return CGAL::TestrepH(dummy1, dummy2, d);
}
#endif
#if TESTR == 5
# include <CGAL/Homogeneous.h>
inline double to_nt(int d)
{
return d;
}
#endif
#if TESTR == 6
# include <CGAL/Homogeneous.h>
# include <CGAL/Checked_long.h>
inline CGAL::Checked_long to_nt(int d)
{
return CGAL::Checked_long(long(d));
}
#endif
struct randomint {
randomint() ;
int get() const { return sequence[cur]; }
int next() { cur = (cur+1)%11; return get();}
private:
int sequence[11];
int cur;
};
inline randomint::randomint()
{
cur = 0;
sequence[0] = 19;
sequence[1] = 5;
sequence[2] = 17;
sequence[3] = 13;
sequence[4] = 29;
sequence[5] = 2;
sequence[6] = 23;
sequence[7] = 31;
sequence[8] = 3;
sequence[9] = 37;
sequence[10] = 11;
}

View File

@ -1,46 +0,0 @@
#if TESTR == 1
typedef double testnt;
typedef CGAL::Cartesian<testnt> TestR;
#endif
#if TESTR == 2
typedef long testnt;
typedef CGAL::Homogeneous<testnt> TestR;
#endif
#if TESTR == 3
typedef CGAL::TestfieldC testnt;
typedef CGAL::Cartesian<testnt> TestR;
#endif
#if TESTR == 4
typedef CGAL::TestrepH testnt;
typedef CGAL::Homogeneous<testnt> TestR;
#endif
#if TESTR == 5
#include <CGAL/MP_Float.h>
//typedef double testnt; // some tests trigger a degenerate case
typedef CGAL::MP_Float testnt;
typedef CGAL::Homogeneous<testnt> TestR;
#endif
#if TESTR == 6
typedef CGAL::Checked_long testnt;
typedef CGAL::Homogeneous<testnt> TestR;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,714 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Iso_cuboid_3_X with X < Iso_cuboid (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Iso_cuboid_3_Iso_cuboid_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Line_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Plane_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Point_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Ray_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Segment_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Sphere_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h>
#include <CGAL/squared_distance_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/number_utils.h>
#include <cassert>
#include <iostream>
template <typename K>
struct Iso_cuboid_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
typedef std::vector<P> Pol;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Iso_cuboid_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void Cub_Cub()
{
std::cout << "Iso_cuboid - Iso_cuboid\n";
// No intersection
check_no_intersection(Cub(p(0,1,2), p(0,1,2)), Cub(p(4,8,6), p(5,9,7))); // degenerate cuboids
check_no_intersection(Cub(p(4,8,6), p(5,9,7)), Cub(p(0,4,1), p(0,4,1)));
check_no_intersection(Cub(p(4,8,6), p(4,8,6)), Cub(p(0,4,1), p(0,4,1)));
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)));
// Sharing a point
check_intersection (Cub(p(0,1,2), p(7,6,4)), Cub(p(7,1,4), p(7,1,4)), // degenerate cuboids
Cub(p(7,1,4), p(7,1,4)));
check_intersection (Cub(p(0,1,2), p(7,8,9)), Cub(p(5,1,2), p(5,1,2)), // degenerate cuboids
Cub(p(5,1,2), p(5,1,2)));
check_intersection (Cub(p(0,1,2), p(0,1,2)), Cub(p(0,1,2), p(0,1,2)), // degenerate cuboids
Cub(p(0,1,2), p(0,1,2)));
check_intersection (Cub(p(1,3,2), p(4,8,6)), Cub(p(4,8,6), p(5,9,7)),
Cub(p(4,8,6), p(4,8,6)));
check_intersection (Cub(p(1,3,2), p(4,8,6)), Cub(p(-3,-6,-4), p(1,3,2)),
Cub(p(1,3,2), p(1,3,2)));
check_intersection (Cub(p(1,3,2), p(4,8,6)), Cub(p(4,0,0), p(6,3,2)),
Cub(p(4,3,2), p(4,3,2)));
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(4,8,1), p(9,10,2)),
Cub(p(4,8,2), p(4,8,2)));
// Sharing an edge
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(4,3,0), p(7,8,2)),
Cub(p(4,3,2), p(4,8,2)));
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(4,4,0), p(7,6,2)),
Cub(p(4,4,2), p(4,6,2)));
// Sharing a face
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(2,4,0), p(3,6,2)), // face within a face
Cub(p(2,4,2), p(3,6,2)));
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(2,4,0), p(4,8,2)), // face within a face
Cub(p(2,4,2), p(4,8,2)));
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(1,8,2), p(4,8,5)), // full face
Cub(p(1,8,2), p(4,8,5)));
check_intersection (Cub(p(1,3,2), p(4,8,5)), Cub(p(1,8,2), p(10,12,8)), // full face
Cub(p(1,8,2), p(4,8,5)));
// Proper intersection
check_intersection (Cub(p(-7, 6, 1), p(7092, 71, 58)), Cub(p(758, 50, 43), p(758, 50, 43)), // degenerate cuboids
Cub(p(758, 50, 43), p(758, 50, 43)));
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)));
}
void Cub_L()
{
std::cout << "Iso_cuboid - Line\n";
// No intersection
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)));
// through vertex
check_intersection (Cub(p(-7, -8, -9), p(-1, 2, -4)), L(p(-8,1,-9), p(-6, 3, -9)),
p(-7,2,-9));
// Segment
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), L(p(0, 0, 3), p(1, 2, 3)),
S(P(1, 2, 3), P(2.5, 5, 3)));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), L(p(1, 0, 0), p(1, 2, 3)),
S(P(1, 1, 1.5), P(1, 5, 7.5)));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), L(p(0, 0, 0), p(1, 2, 3)),
S(P(1, 2, 3), P(2.5, 5, 7.5)));
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub cub(mp, Mp);
P q1 = p(this->r.get_int(mx - this->M, mx), this->r.get_int(my, My), this->r.get_int(mz, Mz)),
q2 = p(this->r.get_int(Mx, Mx + this->M), this->r.get_int(my, My), this->r.get_int(mz, Mz));
assert(!cub.has_on_bounded_side(q1) && !cub.has_on_bounded_side(q2));
L l(q1, q2);
Base::template check_intersection<S>(cub, l);
Base::template check_intersection<S>(cub, l, S(q1, q2), cub);
q1 = p(this->r.get_int(mx, Mx), this->r.get_int(my - this->M, my), this->r.get_int(mz, Mz)),
q2 = p(this->r.get_int(mx, Mx), this->r.get_int(my + (My - my) / 2, My), this->r.get_int(mz, Mz));
assert(!cub.has_on_bounded_side(q1) && !cub.has_on_unbounded_side(q2));
l = L(q1, q2);
Base::template check_intersection<S>(cub, l);
}
}
void Cub_Pl()
{
std::cout << "Iso_cuboid - Plane\n";
Cub cub(p(1,1,1), p(2,2,2));
// no intersection
check_no_intersection(cub, Pl(p(3,0,0), p(3,1,0), p(3,0,1)));
check_no_intersection(Cub(p(1,1,1), p(1,1,1)), Pl(p(3,0,0), p(3,1,0), p(3,0,1)));
// vertex
check_intersection(cub, Pl(0.5, -0.5, -0.5, 0),
p(2,1,1));
check_intersection(Cub(p(1, 2, 3), p(5,9,5)), Pl(p(4,-2,3), p(1,2,3), p(3,5,-8)),
p(1,2,3));
// edge
check_intersection(cub, Pl(p(1,1,1), p(1,2,1), P(1.5,0,0)),
S(p(1,1,1), p(1,2,1)));
if(this->has_exact_c)
{
// face
auto 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);
assert(poly != nullptr);
assert(poly->size() == 4);
for(const P& pt : *poly)
{
assert(pt.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);
assert(poly != nullptr);
assert(poly->size() == 4);
for(const P& pt : *poly) {
assert(cub.has_on_boundary(pt));
}
// other edge
Pl pln(p(1,1,1), p(1,2,1), P(1.5, 1, 2));
res = CGAL::intersection(cub, pln);
poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
for(const P& pt : *poly) {
assert(pln.has_on(pt) && cub.has_on_boundary(pt));
}
// triangle
check_intersection(cub, Pl(P(2, 1.66, 2),
P(1.66,2,2),
P(2,2,1.66)),
Tr(P(1.66,2,2),
P(2, 2, 1.66),
P(2,1.66,2)));
// random
pln = Pl(0.265189, 0.902464, 0.33946, -2.47551);
res = CGAL::intersection(cub, pln);
poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 5);
for(const P& pt : *poly) {
assert(pln.has_on(pt) && cub.has_on_boundary(pt));
}
}
else
{
// face
auto res = CGAL::intersection(cub, Pl(p(1,1,1), p(1,2,1), p(1,2,2)));
CGAL_USE(res);
res = CGAL::intersection(cub, Pl(p(1,1,1), p(1,2,1), p(2,2,2)));
CGAL_USE(res);
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 pln(0.265189, 0.902464, 0.33946, -2.47551);
res = CGAL::intersection(cub, pln);
CGAL_USE(res);
}
}
void Cub_P()
{
std::cout << "Iso_cuboid - Point\n";
// Outside
check_no_intersection(Cub(p(0,1,2), p(0,1,2)), p(4,8,6)); // degenerate
check_no_intersection(Cub(p(0,1,2), p(3,7,5)), p(4,8,6));
// On vertex
check_intersection(Cub(p(0,4,2), p(0,4,2)), p(0,4,2), p(0,4,2)); // degenerate
check_intersection(Cub(p(0,1,2), p(8,7,2)), p(8,7,2), p(8,7,2));
check_intersection(Cub(p(0,1,2), p(8,4,8)), p(8,1,8), p(8,1,8));
check_intersection(Cub(p(0,1,2), p(0,4,2)), p(0,4,2), p(0,4,2));
// On edge
check_intersection(Cub(p(6,3,-2), p(6,3,2)), p(6,3,2), p(6,3,2)); // degenerate
check_intersection(Cub(p(6,3,-2), p(6,3,2)), p(6,3,0), p(6,3,0)); // degenerate
check_intersection(Cub(p(0,1,2), p(0,4,5)), p(0,3,2), p(0,3,2));
check_intersection(Cub(p(0,1,2), p(0,4,5)), p(0,1,3), p(0,1,3));
// On face
check_intersection(Cub(p(0,1,2), p(0,4,5)), p(0,3,3), p(0,3,3)); // degenerate
check_intersection(Cub(p(0,1,2), p(3,4,5)), p(2,4,4), p(2,4,4));
// Within
check_intersection(Cub(p(0,1,2), p(10,11,12)), p(4,8,6), p(4,8,6));
}
void Cub_R()
{
std::cout << "Iso_cuboid - Ray\n";
check_no_intersection (Cub(p(2,1,1), p(3,5,8)), R(p(0,0,0), p(1,0,3)));
check_no_intersection (Cub(p(2,1,1), p(3,5,8)), R(p(4,0,0), p(4,1,3)));
// point
check_intersection (Cub(p(-7, -8, -9), p(-1, 2, -4)), R(p(-7, 2, -4), p(-9, -3, 0)),
p(-7,2,-4));
// segment
check_intersection (Cub(p(1, 4, 8), p(2, 9, 10)), R(p(-1, -6, 4), p(0, -1, 6)),
S(p(1, 4, 8), P(2,9,10)));
check_intersection (Cub(p(-7, -8, -9), p(-1, 2, -4)), R(p(-3, 1, -5), p(-2, -5, -7)),
S(p(-3, 1, -5), P(-1.5, -8, -8)));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), R(p(0, 0, 3), p(1, 2, 3)),
S(p(1, 2, 3), P(2.5, 5, 3)));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), R(p(1, 0, 0), p(1, 2, 3)),
S(P(1, 1,1.5), P(1, 5,7.5)));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), R(p(0, 0, 0), p(1, 2, 3)),
S(p(1, 2, 3), P(2.5, 5, 7.5)));
Base::template check_intersection<S>(Cub(p(2, 1, 1), p(3, 5, 8)), R(p(0, 2, 0), p(1, 2, 3)));
}
void Cub_S()
{
std::cout << "Segment - Iso_cuboid\n";
// no intersection
check_no_intersection (Cub(p(2, 1, 1), p(3, 5, 8)), S(p(0, 2, 0), p(1, 2, 3)));
check_no_intersection (Cub(p(2, 1, 1), p(3, 5, 8)), S(p(0, 0, 0), p(1, 0, 3)));
check_no_intersection (Cub(p(2, 1, 1), p(3, 5, 8)), S(p(4, 0, 0), p(4, 1, 3)));
// point
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), S(p(0, 0, 3), p(1, 2, 3)),
p(1, 2, 3));
check_intersection (Cub(p(1, 1, 1), p(3, 5, 8)), S(p(0, 0, 0), p(1, 2, 3)),
p(1, 2, 3));
// segment
check_intersection (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 (Cub(p(1, 1, 1), p(3, 5, 8)), S(p(1, 0, 0), p(1, 2, 3)),
S(P(1, 1, 1.5), p(1, 2, 3)));
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub cub(mp, Mp);
P s0 = p(this->r.get_int(mx, Mx), this->r.get_int(my - this->M, my), this->r.get_int(mz, Mz)),
s1 = p(this->r.get_int(mx, Mx), this->r.get_int(My, My + this->M), this->r.get_int(mz, Mz));
assert(!cub.has_on_bounded_side(s0) && !cub.has_on_bounded_side(s1));
if(CGAL::do_intersect(cub, S(s0, s1)))
{
std::cout << "yo" << std::endl;
std::cin.get();
check_intersection(cub, S(s0, s1), L(s0, s1), cub);
check_intersection(cub, S(s0, s1), R(s0, s1), cub);
}
s1 = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz));
assert(!cub.has_on_unbounded_side(s1));
check_do_intersect(cub, S(s0, s1));
check_intersection(cub, S(s1, s0), R(s1, s0), cub);
}
}
void Cub_Sph()
{
std::cout << "Iso_cuboid - Sphere\n";
// no intersection
check_do_not_intersect(Cub(p(0,0,0), p(0,0,0)), Sph(p(1,0,0), 0));
// degenerate
check_do_intersect(Cub(p(0,0,0), p(0,0,0)), Sph(p(0,0,0), 0));
check_do_intersect(Cub(p(0,0,0), p(0,0,0)), Sph(p(0,0,0), 1));
check_do_intersect(Cub(p(0,0,0), p(1,1,1)), Sph(p(0,0,0), 0));
// tangent
check_do_intersect(Cub(p(0,0,0), p(0,0,0)), Sph(p(1,0,0), 1)); // at vertex
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Sph(p(1,-1,0), 1)); // at edge
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Sph(p(1,1,-1), 1)); // at face
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub cub(mp, Mp);
P c = p(this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M));
// smallest distance to the iso cuboid, manually...
FT sq_r = CGAL::squared_distance(c, Tr(p(mx, my, mz), p(Mx, my, mz), p(mx, my, Mz)));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(Mx, my, mz), p(Mx, my, Mz), p(mx, my, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(Mx, my, mz), p(Mx, my, Mz), p(Mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(Mx, my, mz), p(Mx, My, mz), p(Mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, my, mz), p(Mx, my, mz), p(Mx, My, mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, my, mz), p(Mx, My, mz), p(mx, My, mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, my, mz), p(mx, My, mz), p(mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, my, mz), p(mx, my, Mz), p(mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, my, Mz), p(Mx, my, Mz), p(mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, My, Mz), p(Mx, My, Mz), p(Mx, my, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, My, mz), p(mx, My, Mz), p(Mx, My, Mz))));
sq_r = (std::min)(sq_r, CGAL::squared_distance(c, Tr(p(mx, My, mz), p(Mx, My, mz), p(Mx, My, Mz))));
check_do_intersect(cub, Sph(c, sq_r));
}
// generic inside
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub cub(mp, Mp);
P c = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz));
int ms = (std::min)((std::min)(Mx - mx, My - my), Mz - mz) + 1;
check_do_intersect(cub, Sph(c, CGAL::square(ms)));
}
}
void Cub_Tet()
{
std::cout << "Iso_cuboid - Sphere\n";
// no intersection
check_do_not_intersect(Cub(p(0,0,0), p(1,1,1)), Tet(p(2,4,1), p(1, 2, 0), p(2,3,1), p(4,5,6)));
// point
check_do_intersect(Cub(p(0,0,0), p(1,1,1)), Tet(p(2,4,1), p(1,1,0), p(2,3,1), p(4,5,6))
/*p(1,1,1)*/); // shared vertex
check_do_intersect(Cub(p(0,0,0), p(2,1,1)), Tet(p(2,4,1), p(1,1,0), p(2,3,1), p(4,5,6))
/*p(1,1,1)*/); // on edge
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Tet(p(2,4,1), p(1,2,1), p(2,3,1), p(4,5,6))
/*p(1,1,2)*/); // on face
// edge
check_do_intersect(Cub(p(0,0,0), p(1,1,1)), Tet(p(0,1,0), p(1,1,0), p(2,3,1), p(4,5,6))
/*S(p(0,1,0), p(1,1,0))*/);
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Tet(p(0,2,0), p(1,2,0), p(2,3,1), p(4,5,6))
/*S(p(0,1,0), p(1,1,0))*/);
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Tet(p(0,2,0), p(2,2,2), p(2,3,1), p(4,5,6))
/*S(p(0,2,0), p(2,2,0))*/);
check_do_intersect(Cub(p(0,0,0), p(2,2,2)), Tet(p(-1,2,-1), p(3,2,3), p(2,3,1), p(4,5,6))
/*S(p(0,2,0), p(2,2,0))*/);
// face
check_do_intersect(Cub(p(0,0,0), p(1,1,1)), Tet(p(0,1,0), p(1,1,0), p(1,1,1), p(4,5,6))
/*Tr(p(0,1,0), p(1,1,0), p(1,1,1))*/);
check_do_intersect(Cub(p(0,0,0), p(1,1,1)), Tet(p(0,1,0), p(1,1,0), p(4,5,6), p(1,1,1))
/*Tr(p(0,1,0), p(1,1,0), p(1,1,1))*/);
// generic inside
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub cub(mp, Mp);
P c = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz));
P q1 = p(this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M)),
q2 = p(this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M)),
q3 = p(this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M), this->r.get_int(this->m, this->M));
Tet tet(c, q1, q2, q3);
if(!tet.is_degenerate())
check_do_intersect(cub, tet);
int id = this->r.get_int(0, 8);
Tet teti(q1, cub[id], q2, q3);
if(!teti.is_degenerate())
check_do_intersect(cub, teti);
int jd = this->r.get_int(0, 8);
Tet tetj(q1, q2, cub[id], cub[jd]);
if(!tetj.is_degenerate())
check_do_intersect(cub, tetj);
}
}
void Cub_Tr()
{
typedef typename CGAL::Intersection_traits<K, Tr, Cub>::result_type Res;
std::cout << "Iso_cuboid - Triangle\n";
// no intersection
Cub cub(p(1,1,1), p(2,2,2));
check_no_intersection(cub, Tr(P(1.1,2,0), p(2,3,1), p(4,5,6)));
// tr adj to a cuboid vertex
check_intersection(cub, Tr(P(1, 0.5, 0.5), p(3, 2, 1), p(3, 1, 2)), p(2,1,1));
// tr adj to a point on a cuboid edge
check_intersection(cub, Tr(P(1, 0.5, 0.5), p(3, 2, 1), p(3, 1, 2)), p(2,1,1));
// tr adj to a point on a cuboid face
check_intersection(cub, Tr(P(1, 1.5, 1.5), p(0, 0, 0), p(-4, 3, 1)), P(1, 1.5, 1.5));
// tr adj to an edge
check_intersection(cub, Tr(P(2, 1.5, 2), p(5, 6, 7), p(4, 7, 6)), P(2, 1.5, 2));
// tr sharing an edge
check_intersection(cub, Tr(P(2, 1.5, 2), P(2, 2.5, 2), p(4, 7, 6)),
S(P(2, 1.5, 2), p(2, 2, 2)));
// tr sharing part of an edge
check_intersection(cub, Tr(P(2, 1.5, 2), p(5, 6, 7), p(4, 7, 6)), P(2, 1.5, 2));
// tr in a face
check_intersection(cub, Tr(P(1, 1.1, 1), P(1, 1.5, 1), P(1, 1, 1.1)),
Tr(P(1, 1.1, 1), P(1, 1.5, 1), P(1, 1, 1.1)));
// face in a tr
Tr tr(p(-3, -3, 1), p(3, -3, 1), P(1.5, 6, 1));
Res res = CGAL::intersection(cub, tr);
Pol* poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
if(this->has_exact_c)
{
for(const P& pt : *poly)
assert(tr.has_on(pt) && cub.has_on_boundary(pt));
}
// tr inside
check_intersection(cub, Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1)),
Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1)));
for(int i=0; i<N; ++i)
{
int mx = this->r.get_int(this->m, this->M);
int my = this->r.get_int(this->m, this->M);
int mz = this->r.get_int(this->m, this->M);
int Mx = this->r.get_int(this->m, this->M);
int My = this->r.get_int(this->m, this->M);
int Mz = this->r.get_int(this->m, this->M);
if(mx == Mx) ++Mx;
if(my == My) ++My;
if(mz == Mz) ++Mz;
if(mx > Mx) std::swap(mx, Mx);
if(my > My) std::swap(my, My);
if(mz > Mz) std::swap(mz, Mz);
P mp = p(mx, my, mz), Mp = p(Mx, My, Mz);
Cub rcub(mp, Mp);
P q1 = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz)),
q2 = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz)),
q3 = p(this->r.get_int(mx, Mx), this->r.get_int(my, My), this->r.get_int(mz, Mz));
Tr rtr(q1, q2, q3);
check_intersection(rcub, rtr, rtr);
}
// tr through
tr = Tr(p(2, 4, 2), P(1, 3.5, -0.5), p(1, -1, 1));
res = CGAL::intersection(cub, tr);
poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
if(this->has_exact_c)
{
for(const P& pt : *poly) {
assert(tr.has_on(pt) && cub.has_on_boundary(pt));
}
}
// cutting in half along diagonal (intersection == triangle)
check_intersection(cub, Tr(p(1, 1, 1), p(2, 2, 2), p(2, 2, 1)),
Tr(p(1, 1, 1), p(2, 2, 2), p(2, 2, 1)));
// cutting in half along diagonal (intersection included in triangle)
tr = Tr(p(1, 1, 10), p(10, 10, 1), p(1, 1, 1));
res = CGAL::intersection(cub, tr);
poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
if(this->has_exact_c)
{
for(const P& pt : *poly)
assert(tr.has_on(pt) && cub.has_on_boundary(pt));
}
// 6 points intersection
tr = Tr(P(18.66, -5.4, -11.33), P(-2.41, -7.33, 19.75), P(-10.29, 20.15, -10.33));
res = CGAL::intersection(cub, tr);
poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 6);
if(this->has_exact_c)
{
for(const P& pt : *poly)
assert(tr.has_on(pt) && cub.has_on_boundary(pt));
}
// triangle clipping a cuboid corner
tr = Tr(P(1.02, 1.33, 0.62), P(1.95, 2.54, 0.95), P(0.79, 2.36, 1.92));
res = CGAL::intersection(cub, tr);
Tr* tr_res = boost::get<Tr>(&*res);
assert(tr_res != nullptr);
if(this->has_exact_c)
{
assert(cub.has_on_boundary((*tr_res)[0]));
assert(cub.has_on_boundary((*tr_res)[1]));
assert(cub.has_on_boundary((*tr_res)[2]));
}
}
void run()
{
std::cout << "3D Line Intersection tests\n";
Cub_Cub();
// Cub_L(); // @fixme bugged in random cases
Cub_Pl();
Cub_P();
Cub_R();
// Cub_S(); // @fixme bugged in random cases
Cub_Sph();
Cub_Tet();
Cub_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Iso_cuboid_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Iso_cuboid_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Iso_cuboid_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Iso_cuboid_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Iso_cuboid_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,435 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Line_3_X with X < Line (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Line_3_Line_3.h>
#include <CGAL/Intersections_3/Line_3_Plane_3.h>
#include <CGAL/Intersections_3/Line_3_Point_3.h>
#include <CGAL/Intersections_3/Line_3_Ray_3.h>
#include <CGAL/Intersections_3/Line_3_Segment_3.h>
#include <CGAL/Intersections_3/Line_3_Sphere_3.h>
#include <CGAL/Intersections_3/Line_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Line_3_Triangle_3.h>
// just to cross verify
#include <CGAL/Intersections_3/Plane_3_Segment_3.h>
#include <CGAL/Intersections_3/Plane_3_Ray_3.h>
#include <CGAL/Intersections_3/Segment_3_Segment_3.h>
#include <CGAL/Intersections_3/Segment_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Segment_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Line_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Line_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void L_L()
{
std::cout << "Line - Line\n";
for(int vx=0; vx<4; ++vx)
{
for(int vy=1; vy<4; ++vy)
{
for(int vz=0; vz<4; ++vz)
{
if(vx == 0 && vy == 0 && vz == 0)
continue;
const int a = vx;
const int b = vy;
const int c = vz;
const L l = L(p(0,0,0), p( a, b, c));
const L l_1 = L(p(0,0,0), p(-a, -b,-c));
const L l_2 = L(p(0,0,0), p(-a, -b, 7));
const L l_3 = L(p(1,0,0), p( a, b, c));
const L l_4 = L(p(1,0,0), p( a+1,b, c));
const CGAL::Object obj1 = CGAL::intersection(l, l_1);
const CGAL::Object obj2 = CGAL::intersection(l, l_2);
const CGAL::Object obj3 = CGAL::intersection(l, l_3);
const CGAL::Object obj4 = CGAL::intersection(l, l_4);
check_do_intersect(l, l_1);
check_do_intersect(l, l_2);
check_do_intersect(l, l_3);
check_do_not_intersect(l, l_4);
Base::template check_intersection<L>(l, l_1);
L interl1;
assert(assign(interl1, obj1));
check_intersection(l, l_2, P(0,0,0));
P interp2;
assert(assign(interp2, obj2));
assert(interp2 == P(0,0,0));
check_intersection(l, l_3, P(a,b,c));
P interp3;
assert(assign(interp3, obj3));
assert(interp3 == P(a,b,c));
check_no_intersection(l, l_4);
assert(obj4.is_empty());
}
}
}
}
void L_Pl()
{
std::cout << "Line - Plane\n";
// No intersection
check_no_intersection (pl(0, 0, 1,-2), L(p(1,1,1), p(2,3,1)));
// Point intersection
check_intersection (L(p(1,1,1), p(2,3,4)), pl(1, 1, 1, 0),
P(0.5, 0, -0.5));
check_intersection (L(p(1,1,1), p(2,3,-1)), pl(1, 0, 1, 3),
P(6,11,-9));
Base::template check_intersection<P>(L(p(1,1,1), p(2,3,4)), pl(1, 2, 4, 7));
Base::template check_intersection<P>(L(p(-1,-1,-1), p(2,3,4)), pl(1, 2, 4, 7),
pl(1, 2, 4, 7), S(p(-1,-1,-1), p(2,3,4)));
Base::template check_intersection<P>(L(p(2,3,4), p(-1,-1,-1)), pl(1, 2, 4, 7),
pl(1, 2, 4, 7), S(p(-1,-1,-1), p(2,3,4)));
if(this->has_exact_c) // because Plane and Line inner coeffs are actually constructions...
{
for(int i=0; i<N; ++i)
{
P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
P l0 = random_point(), l1 = random_point();
Pl pl(pl0, pl1, pl2);
P pl3 = pl0 + FT(this->r.get_double()) * V(pl1 - pl0) + FT(this->r.get_double()) * V(pl1 - pl0);
if(pl.has_on(l1))
Base::template check_intersection(L(pl3, l1), pl, L(pl3, l1)); // both points on the plane
else
Base::template check_intersection(L(pl3, l1), pl, pl3); // single point on the plane
if(pl.oriented_side(l0) != pl.oriented_side(l1)) // l0 xor l1 on pl is fine
{
Base::template check_intersection<P>(L(l0, l1), pl, pl, S(l0, l1));
Base::template check_intersection<P>(L(l0, l1), pl, pl, R(l0, l1));
}
}
}
// Line intersection
Base::template check_intersection<L>(L(p(1,1,1), p(2,3,1)), pl(0, 0, 1,-1));
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
Pl pl(pl0, pl1, pl2);
L l(pl0 + (pl2 - pl1), pl0 + (pl1 - pl2));
check_intersection(l, pl, l);
}
}
}
void L_P()
{
std::cout << "Line - Point\n";
// No intersection
check_no_intersection(L(p(1,1,1), p(2,3,4)), p(0,0,0));
check_no_intersection(L(p(1,1,1), p(2,3,4)), P(3,5,7+1e-8));
check_no_intersection(L(p(2,3,4), p(1,1,1)), P(3,5,7+1e-8));
// Extremity
check_intersection (L(p(1,1,1), p(2,3,4)), p(1,1,1), p(1,1,1));
check_intersection (L(p(1,1,1), p(2,3,4)), p(2,3,4), p(2,3,4));
// Point on the line
check_intersection (L(p(1,1,1), p(2,3,4)), p(3,5,7), p(3,5,7));
check_intersection (L(p(1,1,1), p(2,3,4)), P(1.5,2,2.5), P(1.5,2,2.5));
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
P l0 = random_point(), l1 = random_point();
if(l0 == l1)
continue;
L l(l0, l1);
P pt = l.point(double(i)/N);
check_intersection(l, pt, pt);
P pt2 = random_point();
if(CGAL::collinear(l.point(0), l.point(1), pt2))
check_intersection(l, pt2, pt2);
else
check_no_intersection(l, pt2);
}
}
}
void L_R()
{
std::cout << "Line - Ray\n";
// No intersection
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(3,0,1),p(6,0,1)));
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(0,2,0),p(0,4,0)));
check_no_intersection(L(p(0,0,0),p(1,0,0)), R(p(6,2,0),p(5,4,0)));
// Point intersection
check_intersection (L(p(0,0,0),p(1,0,0)), R(p(3,0,0),p(6,4,0)),
P(3,0,0));
check_intersection (L(p(0,0,0),p(1,0,0)), R(p(5,-2,0),p(5,-1,0)),
P(5,0,0));
check_intersection (L(p(0,0,0),p(1,0,0)), R(p(0,-2,0),p(0,-1,0)),
P(0,0,0));
// Ray Intersection
check_intersection (L(p(0,0,0),p(1,0,0)), R(p(3,0,0),p(6,0,0)),
R(P(3,0,0),P(6,0,0)));
}
void L_S()
{
std::cout << "Line - Segment\n";
// No intersection
check_no_intersection(L(p(0,1,0),p(0,-1,0)), S(p(4,2,-1),p(8,4,3)));
check_no_intersection(L(p(3,1,9),p(7,-1,2)), S(p(4,2,-1),p(8,4,3)));
// Point
check_intersection(L(p(0,1,0),p(0,-1,0)), S(p(0,1,0),p(1,-5,-1)),
P(0,1,0));
check_intersection(L(p(0,1,0),p(0,-1,0)), S(p(0,0,0),p(12,0,0)),
P(0,0,0));
check_intersection(L(p(0,1,0),p(0,-1,0)), S(p(-4,3,0),p(4,-3,0)),
P(0,0,0));
// Segment
check_intersection(L(p(0,0,0),p(1,3,7)), S(p(3,9,21),p(6,18,42)),
S(p(3,9,21),p(6,18,42)));
check_intersection(L(p(0,0,0),p(1,0,0)), S(p(0,0,0),p(-9,0,0)),
S(P(0,0,0),P(-9,0,0)));
for(int i=0; i<N; ++i)
{
P l0 = random_point(), l1 = random_point();
P m = CGAL::midpoint(l0, l1);
P s0 = m + V(CGAL::ORIGIN, P(1e-5, 1e-5, 1e-5)), s1 = m + (random_point() - s0);
if(l0 == l1 || s0 == s1)
continue;
if(CGAL::do_intersect(S(l0, l1), S(s0, s1)))
check_intersection(L(l0, l1), S(s0, s1), S(l0, l1), S(s0, s1));
}
}
void L_Sph()
{
std::cout << "Line - Sphere\n";
// No intersection
check_do_not_intersect(L(p(10,4,9), p(9,-4,8)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
check_do_not_intersect(L(p(-1,10,-3), p(-1,-4,5)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
check_do_not_intersect(L(p(-1,-2,-3), p(5,1,8)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
// Point
check_do_intersect(L(p(-1,8,-10), p(-1,-4,5)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
check_do_intersect(L(p(-8,4,9), p(19,-8,-18)), Sph(p(10,4,9), p(0,1,0), p(0,0,1), p(-1,0,0)));
// Two points
check_do_intersect(L(p(-7,8,0), p(3,-4,1)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
check_do_intersect(L(p(-1,-2,-3), p(2,1,3)), Sph(p(1,0,0), p(0,1,0), p(0,0,1), p(-1,0,0)));
}
void L_Tet()
{
std::cout << "Line - Tetrahedron\n";
Tet tet(p(0,0,0), p(0,1,0), p(1,0,0), p(0,0,1));
check_no_intersection(L(p(5,0,0), p(5,1,0)), tet);
// on edge
check_intersection(L(p(0,2,0), p(0,3,0)), tet,
S(p(0,0,0), p(0,1,0)));
// through vertex and out from face
check_intersection(L(p(0,1,0), P(0.25,0,0.25)), tet,
S(P(0,1,0), P(0.25,0,0.25)));
// through a vertex only
check_intersection(L(p(1,1,0), p(-1,1,0)), tet,
P(0,1,0));
// through 2 faces
check_intersection(L(P(0.25,0.25,0), P(0.25,0,0.25)), tet,
S(P(0.25,0,0.25), P(0.25,0.25,0)));
// through one edge
check_intersection(L(P(0.5,-0.5,0.5), P(0.5,0.5,0.5)), tet,
P(0.5,0,0.5));
// in a single face through 2 edges
check_intersection(L(P(0,0.5,0), P(0.5,0.5,0)), tet,
S(P(0,0.5,0), P(0.5, 0.5, 0)));
// in a single face through 1 vertex and 1 edge
check_intersection(L(p(-1,1,0), p(1,0,0)), tet,
S(P(0,0.5,0), P(1, 0, 0)));
for(int i=0; i<N; ++i)
{
P tet0 = random_point(), tet1 = random_point(), tet2 = random_point(), tet3 = random_point();
if(std::set<P>({{tet0, tet1, tet2, tet3}}).size() != 4)
continue;
P l0 = tet0 + CGAL::cross_product(V(tet0, tet1), V(tet0, tet2));
P l1 = tet2 + CGAL::cross_product(V(tet2, tet1), V(tet2, tet0));
Tet tet(tet0, tet1, tet2, tet3);
assert(tet.has_on_unbounded_side(l0) && tet.has_on_unbounded_side(l1));
if(CGAL::do_intersect(S(l0, l1), tet))
check_intersection(L(l0, l1), tet, tet, S(l0, l1));
}
}
void L_Tr()
{
std::cout << "Line - Triangle\n";
// No intersection
Tr tr(p(0,0,0), p(1,0,1), p(1,1,0));
check_no_intersection(L(p(5,0,0), p(5,1,0)), tr);
// on edge
check_intersection(L(p(-1,0,-1), p(3,0,3)), tr,
S(p(0,0,0), p(1,0,1)));
// through a vertex only
check_intersection(L(p(-2,-1,0), p(4,2,0)), tr,
P(0,0,0));
// through vertex and out from face
Base::template check_intersection<S>(L(p(-3,-3,0), p(-4,-4,0)), Tr(p(0,0,0), p(1,0,0), p(0,1,0)));
// through one edge
Base::template check_intersection<P>(L(p(0,1,0), p(1,0,0)), tr);
// within the face
Base::template check_intersection<S>(L(P(0.25,0.25,0), P(0.3,0.5,0)), Tr(p(0,0,0), p(1,0,0), p(0,1,0)));
for(int i=0; i<N; ++i)
{
P tr0 = random_point(), tr1 = random_point(), tr2 = random_point();
if(tr0 == tr1 || tr1 == tr2 || tr0 == tr2)
continue;
P l0 = tr0 + CGAL::cross_product(V(tr0, tr1), V(tr0, tr2));
P l1 = tr2 + CGAL::cross_product(V(tr2, tr1), V(tr2, tr0));
if(CGAL::do_intersect(S(l0, l1), Tr(tr0, tr1, tr2)))
check_intersection(L(l0, l1), Tr(tr0, tr1, tr2), Tr(tr0, tr1, tr2), S(l0, l1));
}
}
void run()
{
std::cout << "3D Line Intersection tests\n";
L_L();
L_Pl();
L_P();
L_R();
L_S();
L_Sph();
L_Tet();
L_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Line_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Line_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Line_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Line_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Line_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,446 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Plane_3_X with X < Plane (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Plane_3_Plane_3.h>
#include <CGAL/Intersections_3/Plane_3_Point_3.h>
#include <CGAL/Intersections_3/Plane_3_Ray_3.h>
#include <CGAL/Intersections_3/Plane_3_Segment_3.h>
#include <CGAL/Intersections_3/Plane_3_Sphere_3.h>
#include <CGAL/Intersections_3/Plane_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Plane_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Plane_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Circle_3<K> C;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Plane_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void Pl_Pl()
{
std::cout << "Plane - Plane\n";
// No intersection
check_no_intersection(pl(2,1,3,4), pl(6,3,9,3));
// Self
check_intersection(pl(2,1,3,4), pl(2,1,3,4), pl(2,1,3,4));
Base::template check_intersection<Pl>(Pl(p(0,1,8), p(4,3,7), p(2,9,1)), Pl(p(4,3,7), p(0,1,8), p(2,9,1)));
// Line (directed...)
check_intersection(pl(0,0,1,0), pl(0,1,0,0), L(P(0,0,0), P(-1,0,0)), false /*do_opposite*/);
check_intersection(pl(0,1,0,0), pl(0,0,1,0), L(P(-85,0,0), P(0,0,0)), false /*do_opposite*/);
check_intersection(pl(2,3,7,5), pl(9,7,1,3), L(P(2,-3,0), P(-3908,5182,-1105)), false /*do_opposite*/);
check_intersection(pl(9,7,1,3), pl(2,3,7,5), L(P(-3908,5182,-1105), P(2,-3,0)), false /*do_opposite*/);
// generic
for(int i=0; i<N; ++i)
{
P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
Pl pln(pl0, pl1, pl2);
P q = random_point();
Pl pln2(q,pl2,pl1);
if(pln.has_on(q))
{
check_intersection(pln, pln2, pln, false /*do_opposite*/);
}
else
{
auto res = CGAL::intersection(pln, pln2);
assert(res);
L l;
assert(assign(l, res));
if(this->has_exact_c)
{
assert(l.has_on(pl1));
assert(l.has_on(pl2));
}
}
}
// Plane
Base::template check_intersection<Pl>(pl(0,0,1,1), pl(0,0,3,3));
Base::template check_intersection<Pl>(pl(2,1,3,4), pl(6,3,9,12));
}
void Pl_P()
{
std::cout << "Plane - Point\n";
// no intersection
check_no_intersection(Pl(p(5,3,2), p(1,1,1), p(0,0,0)), P(99,98,99));
check_intersection(Pl(p(5,3,2), p(1,1,1), p(0,0,0)), P(99,99,99),
P(99,99,99));
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
const P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
const Pl pln(pl0, pl1, pl2);
const P& plnpt = pln.point();
check_intersection(pln, plnpt, plnpt);
const P q = random_point();
const P pq = pln.projection(q);
check_intersection(pln, pq, pq);
if(q != pq)
check_no_intersection(pln, q);
}
}
}
void Pl_R()
{
std::cout << "Plane - Ray\n";
// No intersection
check_no_intersection (pl(1,1,1,0), R(p(1,1,1), p(2,3,4)));
check_no_intersection (pl(0,0,1,-2), R(p(1,1,1), p(2,3,1)));
check_no_intersection (pl(1,2,4,7), R(p(1,1,1), p(2,3,4)));
// Point
check_intersection (pl(1,0,1,3), R(p(1,1,1), p(2,3,-1)),
p(6,11,-9));
check_intersection (pl(0,0,1,0), R(p(1,1,-1), p(-1,-1,1)),
P(0,0,0));
check_intersection (pl(0,0,1,0), R(p(7,1,0), p(83,1,-4)),
p(7,1,0));
check_intersection (pl(0,0,1,0), R(p(12,6,-4), p(7,25,0)),
P(7,25,0));
// Ray
Base::template check_intersection<R> (pl(0,0,1,-1), R(p(1,1,1), p(2,3,1)));
check_intersection(pl(0,0,1,-1), R(p(1,1,1), p(2,3,1)), R(p(1,1,1), p(2,3,1)));
}
void Pl_S()
{
std::cout << "Plane - Segment\n";
// No intersection
check_no_intersection (pl(1,1,1,0), S(p(1,1,1), p(2,3,4)));
check_no_intersection (pl(0,0,1,-2), S(p(1,1,1), p(2,3,1)));
check_no_intersection (pl(1,0,1,3), S(p(1,1,1), p(2,3,-1)));
check_no_intersection (pl(1,2,4,7), S(p(1,1,1), p(2,3,4)));
// Point
check_intersection (pl(0,0,1,0), S(p(1,1,-1), p(-1,-1,1)),
P(0,0,0));
check_intersection (pl(0,0,1,0), S(p(7,1,0), p(83,1,-4)),
p(7,1,0));
check_intersection (pl(0,0,1,0), S(p(12,6,-4), p(7,25,0)),
p(7,25,0));
// Segment
Base::template check_intersection<S>(pl(0,0,1,-1), S(p(1,1,1), p(2,3,1)));
}
// see also circle_other.cpp
void Pl_Sph()
{
std::cout << "Plane - Sphere\n";
// No intersection
check_no_intersection(pl(1,1,1,0), Sph(p(4,3,1), 1));
// Point
check_intersection (pl(0,10,0,0), Sph(p(4,-2,1), 4), p(4,0,1));
check_intersection (pl(1,1,0,0), Sph(p(4,4,-10), 32), p(0,0,-10));
// generic
check_intersection (pl(0,0,1,-1), Sph(p(0,0,2), 4), C(pl(0,0,1,-1), Sph(p(0,0,2), 4)));
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
const P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
const Pl pln(pl0, pl1, pl2);
const P sph4 = random_point();
if(pln.has_on(sph4))
continue;
Sph sph(pl0, pl1, pl2, sph4);
check_intersection(pln, sph, C(pln, sph));
const P sph5 = random_point();
if(pln.has_on(sph5))
continue;
sph = Sph(pl0, pl1, sph5, sph4);
check_intersection(pln, sph, C(pln, sph));
const P sph6 = random_point();
if(pln.has_on(sph6))
continue;
sph = Sph(pl0, sph6, sph5, sph4);
check_intersection(pln, sph, C(pln, sph));
}
}
}
void Pl_Tet()
{
std::cout << "Plane - Tetrahedron\n";
Tet tet(p(0,0,0), p(0,1,0), p(1,0,0), p(0,0,1));
// No intersection
check_no_intersection(tet, Pl(p(2,0,0),
p(2,1,0),
p(2,0,1)));
// Point
check_intersection(tet, Pl(p(-1,1,12), p(0,1,-50), P(0.5,1,-0.5)),
p(0,1,0));
// Segment
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)));
// Triangle
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)));
if(this->has_exact_c)
{
check_intersection(tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)),
Tr(P(0,0.5,0), P(0.5,0.5,0), P(0,0.5,0.5)));
Pl pln(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06));
// Don't have the right values to test further.
auto res = CGAL::intersection(tet, pln);
const std::vector<P>* poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
}
for(int i=0; i<N; ++i)
{
const P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
Pl pln(pl0, pl1, pl2);
const P tet0 = random_point(), tet1 = random_point(), tet2 = random_point(), tet3 = random_point();
Tet t(tet0, tet1, tet2, tet3);
if(t.is_degenerate())
continue;
std::set<CGAL::Orientation> os;
os.insert(pln.oriented_side(tet0));
os.insert(pln.oriented_side(tet1));
os.insert(pln.oriented_side(tet2));
os.insert(pln.oriented_side(tet3));
if(os.size() == 1 && (*os.begin() != CGAL::ZERO))
check_no_intersection(pln, t);
else
check_do_intersect(pln, t);
}
}
void Pl_Tr()
{
std::cout << "Plane - Triangle\n";
// No intersection
// Point
check_intersection(Pl(p(0,0,0), p(12,0,0), p(0,11,0)), Tr(p(0,0,0), p(1,0,1), p(0,1,1)),
p(0,0,0));
// Segment
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)));
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)));
// Triangle
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,0)),
Tr(p(0,0,0), p(1,0,0), p(0,1,0)));
for(int i=0; i<N; ++i)
{
const P pl0 = random_point(), pl1 = random_point(), pl2 = random_point();
if(CGAL::collinear(pl0, pl1, pl2))
continue;
Pl pln(pl0, pl1, pl2);
Tr tr(pl1, pl0, pl2);
check_intersection(pln, tr, tr);
const P pl3 = random_point(), pl4 = random_point();
if(CGAL::collinear(pl0, pl1, pl3))
continue;
tr = Tr(pl0, pl1, pl3);
if(pln.has_on(pl3))
{
check_intersection(pln, tr, tr);
}
else
{
check_intersection(pln, tr, S(pl0, pl1));
if(CGAL::collinear(pl0, pl3, pl4))
continue;
if(pln.oriented_side(pl3) == pln.oriented_side(pl4))
check_intersection(pln, Tr(pl0, pl3, pl4), pl0);
else
Base::template check_intersection<S>(pln, Tr(pl0, pl3, pl4));
}
}
}
void Pl_Pl_Pl()
{
std::cout << "Plane - Plane - Plane\n";
Pl pl1(1,0,0,0);
Pl pl2(0,1,0,0);
Pl pl3(0,0,1,0);
Pl pl4(1,0,0,1); // pl4 is parallel to pl1.
// No intersection
check_no_intersection(pl1, pl2, pl4);
check_no_intersection(pl1, pl4, pl2);
check_no_intersection(pl4, pl2, pl1);
check_no_intersection(Pl(p(0,0,0),p(1,1,1),p(1,1,0)),
Pl(p(0,0,0),p(1,-1,1),p(1,-1,-2)),
Pl(1,0,0,-5));
// Intersection in a line.
Pl pl5(1,1,0,0); // pl1, pl2, pl5 intersect in the line l.
L l;
assert(CGAL::do_intersect(pl1, pl2, pl5));
CGAL::Object o4 = CGAL::intersection(pl1, pl2, pl5);
assert(assign(l, o4));
assert(l == L(P(0,0,0), P(0,0,1)));
// Intersection in a plane.
assert(CGAL::do_intersect(pl1, pl1, pl1));
CGAL::Object o5 = CGAL::intersection(pl1, pl1, pl1);
Pl pln;
assert(assign(pln, o5));
assert(pln == pl1);
// Generic intersection.
assert(CGAL::do_intersect(pl1, pl2, pl3));
CGAL::Object o = CGAL::intersection(pl1, pl2, pl3);
P pt;
assert(assign(pt, o));
assert(pt == P(0,0,0));
}
void run()
{
std::cout << "3D Plane Intersection tests\n";
Pl_Pl();
Pl_P();
Pl_R();
Pl_S();
Pl_Sph();
Pl_Tet();
Pl_Tr();
Pl_Pl_Pl();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Plane_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
// Homogenous is broken for projection and Pln-Sphere
// std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
// Plane_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Plane_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Plane_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
// FIXME BROKEN PROJECTION, BROKEN PLN-SPHERE
// std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
// Plane_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,261 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Point_3_X with X < Point (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Point_3_Point_3.h>
#include <CGAL/Intersections_3/Point_3_Ray_3.h>
#include <CGAL/Intersections_3/Point_3_Segment_3.h>
#include <CGAL/Intersections_3/Point_3_Sphere_3.h>
#include <CGAL/Intersections_3/Point_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Point_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Point_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Point_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void P_P()
{
std::cout << "Point - Point\n";
P p(0.99,0.99,0.99);
check_intersection(p,p,p);
P q = random_point();
check_no_intersection(p,q);
}
void P_R()
{
std::cout << "Point - Ray\n";
P pt(1,1,1);
R ray(p(-1,-1,-1), p(3,3,3));
check_intersection(ray, pt, pt);
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
P rp0 = random_point(), rp1 = random_point();
if(rp0 != rp1)
{
R r(rp0, rp1);
L l(rp0, rp1);
P q = random_point(), pq = l.projection(q);
assert(CGAL::collinear(rp0, rp1, pq));
if(!CGAL::collinear_are_ordered_along_line(pq, rp0, rp1))
check_intersection(r, pq, pq);
else
check_no_intersection(r, pq);
}
}
}
}
void P_S()
{
std::cout << "Point - Segment\n";
P pt(1,1,1);
S s(p(-1,-1,-1), p(3,3,3));
check_intersection(s, pt, pt);
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
P rp0 = random_point(), rp1 = random_point();
if(rp0 != rp1)
{
s = S(rp0, rp1);
L l(rp0, rp1);
P q = random_point(), pq = l.projection(q);
assert(CGAL::collinear(rp0, rp1, pq));
if(CGAL::collinear_are_ordered_along_line(rp0, pq, rp1))
check_intersection(s, pq, pq);
else
check_no_intersection(s, pq);
}
}
}
}
void P_Sph()
{
std::cout << "Point - Segment\n";
P pt(1,1,1);
Sph sph(p(0,0,0), 3);
check_no_intersection(p(0,0,0), sph);
check_intersection(pt, sph, pt);
for(int i=0; i<N; ++i)
{
P c = random_point(), q = random_point();
if(c != q)
{
sph = Sph(c, CGAL::squared_distance(c, q));
check_intersection(sph, q, q);
}
}
}
void P_Tet()
{
std::cout << "Point - Tetrahedron\n";
Tet t(p(0,0,0), p(10,0,0),p(10,10,0),p(0,0,10));
P q0 = p(1, 1, 1), q1 = p(11,11,11);
check_no_intersection(t, q1);
for(int i=0;i<4;++i)
check_intersection(t[i], t, t[i]);
check_intersection(q0, t, q0);
for(int i=0; i<N; ++i)
{
P tet0 = random_point(), tet1 = random_point(), tet2 = random_point(), tet3 = random_point();
Tet tet(tet0, tet1, tet2, tet3);
if(tet.is_degenerate())
continue;
if(tet.orientation() == CGAL::NEGATIVE)
tet = Tet(tet1, tet0, tet2, tet3);
P q = random_point();
// not using bounded_side intentionally, otherwise it's a tautology
if(Pl(tet[0], tet[1], tet[2]).oriented_side(q) != CGAL::NEGATIVE &&
Pl(tet[0], tet[3], tet[1]).oriented_side(q) != CGAL::NEGATIVE &&
Pl(tet[2], tet[1], tet[3]).oriented_side(q) != CGAL::NEGATIVE &&
Pl(tet[0], tet[2], tet[3]).oriented_side(q) != CGAL::NEGATIVE)
check_intersection(tet, q, q);
else
check_no_intersection(tet, q);
}
}
void P_Tr()
{
std::cout << "Point - Triangle\n";
check_no_intersection(Tr(p(0,0,0), p(1,0,0), p(0,1,0)), p(0,0,1));
check_intersection(Tr(p(0,0,0), p(2,0,0), p(0,2,0)), p(1,0,0), p(1,0,0));
check_intersection(Tr(p(0,0,0), p(2,0,0), p(0,2,0)), p(1,1,0), p(1,1,0));
check_intersection(Tr(p(0,0,0), p(4,0,0), p(0,4,0)), p(1,1,0), p(1,1,0));
if(this->has_exact_c)
{
for(int i=0; i<N; ++i)
{
P tr0 = random_point(), tr1 = random_point(), tr2 = random_point();
if(CGAL::collinear(tr0, tr1, tr2))
continue;
Tr tr(tr0, tr1, tr2);
Pl pln(tr0, tr1, tr2);
P q = random_point(), pq = pln.projection(q);
if(tr.has_on(pq))
check_intersection(tr, pq, pq);
else
check_no_intersection(tr, pq);
}
}
}
void run()
{
std::cout << "3D Point Intersection tests\n";
P_P();
P_R();
P_S();
P_Sph();
P_Tet();
P_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Point_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Point_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Point_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Point_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Point_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,283 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Sphere_3_X with X < Sphere (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Ray_3_Ray_3.h>
#include <CGAL/Intersections_3/Ray_3_Segment_3.h>
#include <CGAL/Intersections_3/Ray_3_Sphere_3.h>
#include <CGAL/Intersections_3/Ray_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Ray_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Ray_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Ray_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void R_R()
{
std::cout << "Ray - Ray\n";
// No intersection
check_no_intersection (R(p(0,0,0), p(1,0,0)), R(p(-2,0,0), p(-3,0,0)));
check_no_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,-1,0), p(1,-2,0)));
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)));
// Point
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(0,0,0), p(-1,0,0)),
p(0,0,0));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(0,0,0), p(0,1,0)),
p(0,0,0));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(5,0,0), p(5,1,0)),
p(5,0,0));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,0,0), p(1,1,0)),
p(1,0,0));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,-1,0), p(1,1,0)),
p(1,0,0));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(1,-2,0), p(1,-1,0)),
p(1,0,0));
// Segment
// @fixme
// check_intersection (R(p(0,0,0), p(1,0,0)), R(p(2,0,0), p(-3,0,0)),
// S(p(0,0,0), p(2,0,0)));
// check_intersection (R(p(2,0,0), p(-3,0,0)), R(p(0,0,0), p(1,0,0)),
// S(p(2,0,0), p(0,0,0)));
// Ray
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(-1,0,0), p(3,0,0)),
R(p(0,0,0), p(1,0,0)));
check_intersection (R(p(0,0,0), p(1,0,0)), R(p(2,0,0), p(3,0,0)),
R(p(2,0,0), p(6,0,0)));
}
void R_S()
{
std::cout << "Ray - Segment\n";
// No intersection
check_no_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,-1,0), p(0,-2,0)));
check_no_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,-1,0), p(-3,-2,0)));
check_no_intersection (S(p(-3,0,0), p(3,0,0)), R(p(3,-1,0), p(3,-2,0)));
check_no_intersection (S(p(-3,0,0), p(3,0,0)), R(p(4,0,0), p(5,0,0)));
check_no_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-5,0,0), p(-8,0,0)));
// Point
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,-2,0), p(0,-1,0)),
p(0,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,-2,0), p(-3,-1,0)),
p(-3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(3,-2,0), p(3,-1,0)),
p(3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,0,0), p(0,-1,0)),
p(0,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,0,0), p(-3,-1,0)),
p(-3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(3,0,0), p(3,-1,0)),
p(3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,-2,0), p(0,0,0)),
p(0,0,0));
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_intersection (S(p(-3,0,0), p(3,0,0)), R(p(3,-2,0), p(3,0,0)),
p(3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,0,0), p(-4,0,0)),
p(-3,0,0));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(3,0,0), p(4,0,0)),
p(3,0,0));
// Segment
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-4,0,0), p(-2,0,0)),
S(p(-3,0,0), p(3,0,0)));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-4,0,0), p(7,0,0)),
S(p(-3,0,0), p(3,0,0)));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,0,0), p(-2,0,0)),
S(p(-3,0,0), p(3,0,0)));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(-3,0,0), p(7,0,0)),
S(p(-3,0,0), p(3,0,0)));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,0,0), p(-2,0,0)),
S(p(0,0,0), p(-3,0,0)));
check_intersection (S(p(-3,0,0), p(3,0,0)), R(p(0,0,0), p(2,0,0)),
S(p(0,0,0), p(3,0,0)));
}
void R_Sph()
{
std::cout << "Ray - Sphere\n";
// No intersection
check_do_not_intersect(R(p(0,1,7), p(1,2,1)), Sph(p(0,8,4), 4));
for(int i=0; i<N; ++i)
{
P c = random_point(), q = random_point();
Sph sph(c, CGAL::squared_distance(c, q));
// single point
if(this->has_exact_c)
{
Pl pln(q, V(c, q)); // plane tangent to the sphere at q
V v1 = pln.base1();
check_do_intersect(R(q, q + v1), sph);
}
// maybe two points
P r = random_point();
if(q == r)
continue;
check_do_intersect(R(q, r), sph);
}
}
void R_Tet()
{
std::cout << "Ray - Tetrahedron\n";
Tet tet(p(0,0,0), p(0,1,0), p(1,0,0), p(0,0,1));
check_no_intersection (R(p(5,0,0), p(5,1,0)), tet);
check_intersection (R(p(0,2,0), p(0,-2,0)), tet,
S(p(0,1,0), p(0,0,0)));
check_intersection (R(p(0,1,0), P(0.25,0,0.25)), tet,
S(p(0,1,0), P(0.25,0,0.25)));
check_intersection (R(p(2,1,0), p(-2,1,0)), tet,
p(0,1,0));
typename K::FT third = FT(1)/FT(3);
typename K::FT fifth = FT(1)/FT(5);
typename K::FT tenth = FT(1)/FT(10);
if(this->has_exact_c)
{
check_intersection (tet, R(P(tenth,tenth,tenth), P(fifth,fifth,fifth)),
S(P(tenth,tenth,tenth), P(third, third, third)));
check_intersection (tet, R(P(0.25,0.25,0.25), p(2,2,2)),
S(P(0.25,0.25,0.25), P(third, third, third)));
}
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(tenth,tenth,tenth), P(fifth,fifth,fifth)));
CGAL::intersection(tet, R(P(0.25,0.25,0.25), p(2,2,2)));
}
}
void R_Tr()
{
std::cout << "Ray - Triangle\n";
check_no_intersection(R(p(0,0,0), p(1,1,1)), Tr(p(-4, 2, 2), p(3, 7, -1), p(0, 9, -4)));
check_no_intersection(R(p(0,0,0), p(1,1,1)), Tr(p(-1, -1, -1), p(3, 7, -1), p(0, 9, -4)));
// Point
check_intersection(R(p(0,0,0), p(1,1,1)), Tr(p(0, 0, 0), p(3, 7, -1), p(0, 9, -4)),
p(0, 0, 0));
check_intersection(R(p(0,0,0), p(1,1,1)), Tr(p(2, 2, 2), p(3, 7, -1), p(0, 9, -4)),
p(2, 2, 2));
check_intersection(R(p(0,0,0), p(4,-2,6)), Tr(p(2, -1, 3), p(3, 7, -1), p(0, 9, -4)),
p(2, -1, 3));
check_intersection(R(p(0,0,0), p(2,-1,3)), Tr(p(4, -2, 6), p(3, 7, -2), p(0, 8, -4)),
p(4, -2, 6));
Base::template check_intersection<P>(R(p(0,0,0), p(1,1,1)), Tr(p(2, 4, 2), p(5, -7, -1), p(0, -9, 4)));
// Segment
check_intersection(R(p(0,0,1), p(1,1,1)), Tr(p(3, 3, 1), p(7, 7, 1), p(0, -9, -4)),
S(p(3, 3, 1), p(7,7,1)));
check_intersection(R(p(0,0,1), p(1,1,1)), Tr(p(7, 7, 1), p(3, 3, 1), p(0, -9, -4)),
S(p(3, 3, 1), p(7,7,1)));
check_intersection(R(p(3,3,1), p(7,7,1)), Tr(p(4, 4, 1), p(2, 2, 1), p(0, -9, -4)),
S(p(3, 3, 1), p(4,4,1)));
}
void run()
{
std::cout << "3D Ray Intersection tests\n";
R_R();
R_S();
R_Sph();
R_Tet();
R_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Ray_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Ray_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Ray_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Ray_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Ray_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,215 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Sphere_3_X with X < Sphere (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Segment_3_Segment_3.h>
#include <CGAL/Intersections_3/Segment_3_Sphere_3.h>
#include <CGAL/Intersections_3/Segment_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Segment_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Segment_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Segment_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void S_S()
{
// see segment_segment.cpp
}
// @fixme EPICK
void S_Sph()
{
std::cout << "Segment - Sphere\n";
// No intersection
check_do_not_intersect(S(p(4,1,9), p(4,6,-1)), Sph(p(9,2,4), 1));
check_do_not_intersect(S(p(-2,3,4), p(1,2,-1)), Sph(p(9,2,4), 10000));
check_do_intersect(S(p(-2,3,4), p(1,2,-1)), Sph(p(9,2,4), 100));
for(int i=0; i<N; ++i)
{
P s0 = random_point(), s1 = random_point();
P c = random_point();
if(s0 == s1 || c == s0 || c == s1)
continue;
check_do_intersect(S(s0, s1), Sph(c, CGAL::squared_distance(c, s1)));
FT sqr = this->r.get_int(this->m + 1, this->M);
Sph sph(c, sqr);
if(sph.oriented_side(s0) != sph.oriented_side(s1))
check_do_intersect(sph, S(s0, s1));
else
check_do_not_intersect(sph, S(s0, s1));
}
}
void S_Tet()
{
std::cout << "Segment - Tetrahedron\n";
Tet tet(p(0,0,0), p(0,1,0), p(1,0,0), p(0,0,1));
// No intersection
check_no_intersection(S(p(5,0,0), p(5,1,0)), tet);
// Point
check_intersection(S(p(0,1,7), p(-7,-1,0)), Tet(p(0,1,7), p(9,4,-2), p(3,-7,2), p(7,-8,1)),
p(0,1,7));
check_intersection(S(p(4,3,2), p(-7,-1,0)), Tet(p(0,1,6), p(8,5,-2), p(3,-7,2), p(7,-8,1)),
p(4,3,2));
check_intersection(S(p(3,2,2), p(-7,-1,3)), Tet(p(4,1,6), p(2,-1,-2), p(3,6,2), p(7,-8,1)),
p(3,2,2));
// Segment
check_intersection(S(p(0,1,7), p(-7,-1,0)), Tet(p(0,1,7), p(-7,-1,0), p(3,-7,2), p(7,-8,1)),
S(p(0,1,7), p(-7,-1,0)));
check_intersection(S(p(0,1,7), p(-8,-1,1)), Tet(p(0,1,7), p(-4,0,4), p(3,-7,2), p(7,-8,1)),
S(p(0,1,7), p(-4,0,4)));
check_intersection(S(p(0,1,7), p(3,-7,2)), Tet(p(0,1,7), p(-4,0,4), p(3,-7,2), p(7,-8,1)),
S(p(0,1,7), p(3,-7,2)));
FT fourth = FT(1)/FT(4);
FT fifth = FT(1)/FT(5);
FT tenth = FT(1)/FT(10);
if(this->has_exact_c)
{
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(fourth,0,fourth)),
S(p(0,1,0), P(fourth,0,fourth)));
check_intersection(tet, S(p(2,1,0), p(-2,1,0)), p(0,1,0));
check_intersection(tet, S(P(tenth,tenth,tenth), P(fifth,fifth,fifth)),
S(P(tenth,tenth,tenth), P(fifth,fifth,fifth)));
typename K::FT third = FT(1)/FT(3);
check_intersection(tet, S(P(fourth,fourth,fourth), p(2,2,2)),
S(P(fourth,fourth,fourth), P(third, third, third)));
}
else
{
CGAL::intersection(tet, S(p(0,2,0), p(0,-2,0)));
CGAL::intersection(tet, S(p(0,1,0), P(fourth,0,fourth)));
CGAL::intersection(tet, S(p(2,1,0), p(-2,1,0)));
CGAL::intersection(tet, S(P(tenth,tenth,tenth), P(fifth,fifth,fifth)));
CGAL::intersection(tet, S(P(fourth,fourth,fourth), p(2,2,2)));
}
}
void S_Tr()
{
std::cout << "Segment - Triangle\n";
// No intersection
check_no_intersection(S(p(1,4,7), p(2,3,9)), Tr(p(-1,9,8), p(-5,3,4), p(-0,8,9)));
// Point
check_intersection(S(p(4,2,7), p(1,3,7)), Tr(p(1,3,7), p(3,9,-1), p(-7,6,3)),
p(1,3,7));
check_intersection(S(p(1,3,9), p(5,1,7)), Tr(p(3,2,8), p(-1,9,7), p(-2,2,8)),
p(3,2,8));
// Segment
check_intersection(S(p(3,2,7), p(1,-2,-9)), Tr(p(3,2,7), p(1,-2,-9), p(4,3,9)),
S(p(3,2,7), p(1,-2,-9)));
check_intersection(S(p(3,2,7), p(1,-2,-9)), Tr(p(5,6,23), p(1,-2,-9), p(4,3,9)),
S(p(3,2,7), p(1,-2,-9)));
check_intersection(S(p(3,2,7), p(1,-2,-9)), Tr(p(5,6,23), p(-1,-6,-25), p(4,3,9)),
S(p(3,2,7), p(1,-2,-9)));
check_intersection(S(p(1,3,9), p(5,1,7)), Tr(p(4,0,6), p(2,4,10), p(-2,2,8)),
S(p(1,3,9), p(3,2,8)));
Base::template check_intersection<S>(S(p(1,3,7), p(5,1,7)), Tr(p(4,0,7), p(2,4,7), p(-2,2,7)));
Base::template check_intersection<S>(S(p(1,3,7), p(5,1,7)), Tr(p(4,0,7), p(2,4,7), p(1,2,7)));
}
void run()
{
std::cout << "3D Segment Intersection tests\n";
S_S();
// S_Sph(); // @fixme
S_Tet();
S_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Segment_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Segment_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Segment_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Segment_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Segment_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,188 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Sphere_3_X with X < Sphere (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Sphere_3_Sphere_3.h>
#include <CGAL/Intersections_3/Sphere_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Sphere_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Sphere_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Sphere_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void Sph_Sph()
{
std::cout << "Sphere - Sphere\n";
// No intersection
check_no_intersection(Sph(p(0,0,0), 4), Sph(p(6,3,8), 9));
for(int i=0; i<N; ++i)
{
P c0 = random_point(), c1 = random_point();
const FT r0 = this->r.get_int(this->m + 1, this->M), r1 = this->r.get_int(this->m + 1, this->M);
if(r0 == r1)
check_intersection(Sph(c0, r0), Sph(c0, r1), Sph(c0, r0));
else
check_no_intersection(Sph(c0, r0), Sph(c0, r1));
const FT sqd = CGAL::squared_distance(c0, c1);
if(sqd <= 8)
continue;
const int r = int(CGAL::to_double((sqd / 4)) - 1);
check_no_intersection(Sph(c0, r), Sph(c1, r));
}
}
void Sph_Tet()
{
std::cout << "Sphere - Tetrahedron\n";
// No intersection
check_do_not_intersect(Sph(p(0,0,0), 3), Tet(p(6,3,8), p(7,2,8), p(1,9,7), p(2,3,4)));
check_do_not_intersect(Sph(p(0,0,0), 10000), Tet(p(6,3,8), p(7,2,8), p(1,9,7), p(2,3,4)));
// Point
check_do_intersect(Sph(p(0,0,0), 4), Tet(p(2,0,0), p(9,3,7), p(4,9,7), p(8,-3,4))); // vertex
check_do_intersect(Sph(p(0,0,0), 4), Tet(p(2,2,0), p(2,-2,0), p(4,9,7), p(8,-3,4))); // edge
check_do_intersect(Sph(p(0,0,0), 4), Tet(p(2,2,3), p(2,-2,-3), p(4,2,-3), p(8,-3,4))); // face
for(int i=0; i<N; ++i)
{
P tet0 = random_point(), tet1 = random_point(), tet2 = random_point(), tet3 = random_point();
Tet tet(tet0, tet1, tet2, tet3);
if(tet.is_degenerate())
continue;
P c = random_point();
FT sqm, sqM;
sqm = (std::min)((std::min)(CGAL::squared_distance(c, tet[0]), CGAL::squared_distance(c, tet[1])),
(std::min)(CGAL::squared_distance(c, tet[2]), CGAL::squared_distance(c, tet[3])));
sqM = (std::max)((std::max)(CGAL::squared_distance(c, tet[0]), CGAL::squared_distance(c, tet[1])),
(std::max)(CGAL::squared_distance(c, tet[2]), CGAL::squared_distance(c, tet[3])));
FT r = (sqm + sqM) / 2;
if(r == 0)
continue;
check_do_intersect(Sph(c, r), tet);
}
}
void Sph_Tr()
{
std::cout << "Sphere - Triangle\n";
// No intersection
check_do_not_intersect(Sph(p(0,0,0), 3), Tr(p(6,3,8), p(7,2,8), p(1,9,7)));
check_do_not_intersect(Sph(p(0,0,0), 10000), Tr(p(6,3,8), p(7,2,8), p(1,9,7)));
// Generic
for(int i=0; i<N; ++i)
{
P tr0 = random_point(), tr1 = random_point(), tr2 = random_point();
Tr tr(tr0, tr1, tr2);
if(tr.is_degenerate())
continue;
P c = random_point();
FT r = this->r.get_int(this->m + 1, this->M);
Sph sph(c, r);
if(sph.oriented_side(tr0) != sph.oriented_side(tr1) ||
sph.oriented_side(tr0) != sph.oriented_side(tr2) ||
sph.oriented_side(tr2) != sph.oriented_side(tr1))
check_do_intersect(sph, tr);
else
check_do_not_intersect(sph, tr);
}
}
void run()
{
std::cout << "3D Sphere Intersection tests\n";
Sph_Sph();
Sph_Tet();
Sph_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Sphere_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
// @fixme illegal Plane_3 constructor in Cartesian_kernel::Construct_radical_plane_3
// std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
// Sphere_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Sphere_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Sphere_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
// std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
// Sphere_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -0,0 +1,330 @@
// 3D intersection tests.
// We want to check that no division is performed for interface macro Do_intersect_3_RT
#define CGAL_NO_MPZF_DIVISION_OPERATOR
// Tetrahedron_3_X with X < Tetrahedron (lexicographically) are tested in other files
#include <CGAL/Intersections_3/Tetrahedron_3_Tetrahedron_3.h>
#include <CGAL/Intersections_3/Tetrahedron_3_Triangle_3.h>
#include <CGAL/Vector_3.h>
#include "intersection_test_helper.h"
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
#include <cassert>
template <typename K>
struct Tetrahedron_3_intersection_tester
: public Intersection_3_tester<K>
{
typedef Intersection_3_tester<K> Base;
typedef typename K::FT FT;
typedef CGAL::Iso_cuboid_3<K> Cub;
typedef CGAL::Line_3<K> L;
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
typedef CGAL::Ray_3<K> R;
typedef CGAL::Segment_3<K> S;
typedef CGAL::Sphere_3<K> Sph;
typedef CGAL::Tetrahedron_3<K> Tet;
typedef CGAL::Triangle_3<K> Tr;
typedef CGAL::Vector_3<K> V;
using Base::p;
using Base::pl;
using Base::random_point;
using Base::check_do_intersect;
using Base::check_do_not_intersect;
using Base::check_intersection;
using Base::check_no_intersection;
private:
int N = 1000;
public:
Tetrahedron_3_intersection_tester(CGAL::Random& r,
const bool has_exact_p = false,
const bool has_exact_c = false)
: Base(r, has_exact_p, has_exact_c)
{ }
public:
void Tet_Tet()
{
std::cout << "Tetrahedron - Tetrahedron\n";
for(int i=0; i<N; ++i)
{
P tet00 = random_point(), tet01 = random_point(), tet02 = random_point(), tet03 = random_point();
Tet tet0(tet00, tet01, tet02, tet03);
if(tet0.is_degenerate())
continue;
P tet10 = random_point(), tet11 = random_point(), tet12 = random_point(), tet13 = random_point();
// ---
Tet tet1(tet00, tet11, tet12, tet13);
if(tet1.is_degenerate())
continue;
check_do_intersect(tet0, tet1);
// ---
Tet tet2(tet00, tet11, tet02, tet13);
if(tet2.is_degenerate())
continue;
check_do_intersect(tet0, tet2);
// ---
Tet tet3(tet00, tet03, tet02, tet13);
if(tet3.is_degenerate())
continue;
check_do_intersect(tet0, tet3);
// ---
Tet tet4(tet10, tet13, tet12, tet13);
if(tet4.is_degenerate())
continue;
std::set<CGAL::Oriented_side> os;
os.insert(tet0.oriented_side(tet10));
os.insert(tet0.oriented_side(tet11));
os.insert(tet0.oriented_side(tet12));
os.insert(tet0.oriented_side(tet13));
if(os.size() == 1 && (*os.begin() == CGAL::ON_POSITIVE_SIDE))
check_do_not_intersect(tet0, tet4);
else
check_do_intersect(tet0, tet4);
}
}
void Tet_Tr()
{
Tet tet(p(0,0,0), p(0,1,0), p(1,0,0), p(0,0,1));
// 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)));
// only one edge intersecting
check_do_intersect(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
check_do_intersect(tet, Tr(p(0,1,0), p(1,0,0), P(0.5,0,-100)));
// shared edge, 3rd point inside
check_do_intersect(tet, Tr(p(0,1,0), p(1,0,0), P(0.25,0.25,0.25)));
// tr adjacent to a vertex, outside
check_do_intersect(tet, Tr(p(-1,1,12), p(0,1,-50), P(0.5,1,-0.5)));
// tr share a vertex, inside
check_do_intersect(tet, Tr(p(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0)));
// tr edge adjacent to a vertex
check_do_intersect(tet, Tr(p(-1,1,0), p(3,1,0), p(0,3,0)));
// tr vertex adjacent to a vertex
check_do_intersect(tet, Tr(p(0,1,0), p(3,1,0), p(0,3,0)));
// traversing triangles
Tr tr(P(-2, 0.5, 0.25), P(-2, 0.75, 0.6), P(1.5, 0.5, 0.25));
check_do_intersect(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));
check_do_intersect(tet, tr);
if(this->has_exact_c)
{
Tr tr(p(-2,2,0), p(2,2,0), P(0.25,0.25,0));
auto res = CGAL::intersection(tet, tr);
const std::vector<P>* poly = boost::get<std::vector<P> >(&*res);
assert(poly != nullptr);
assert(poly->size() == 4);
for(const P& pt : *poly)
{
assert(tet.has_on_boundary(pt) && tr.has_on(pt));
}
// 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);
assert(inter != nullptr);
assert(inter->size() == 4);
for(const P& pt : *inter) {
assert(tet.has_on_boundary(pt) && tr.has_on(pt));
}
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);
assert(inter != nullptr);
assert(inter->size() == 4);
for(const P& pt : *inter) {
assert(tet.has_on_boundary(pt) && tr.has_on(pt));
}
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);
assert(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);
assert(inter != nullptr);
assert(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);
assert(inter != nullptr);
assert(inter->size() == 4);
for(const P& pt : *inter) {
assert((tet.has_on_bounded_side(pt) || tet.has_on_boundary(pt)) && tr.has_on(pt));
}
// 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);
assert(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);
assert(inter != nullptr);
assert(inter->size() == 4);
}
for(int i=0; i<N; ++i)
{
P tet0 = random_point(), tet1 = random_point(), tet2 = random_point(), tet3 = random_point();
Tet tet(tet0, tet1, tet2, tet3);
if(tet.is_degenerate())
continue;
P tr0 = random_point(), tr1 = random_point(), tr2 = random_point();
// ---
Tr tr(tet0, tr1, tr2);
if(tr.is_degenerate())
continue;
check_do_intersect(tet, tr);
// ---
tr = Tr(tet0, tr1, tet2);
if(tr.is_degenerate())
continue;
check_do_intersect(tet, tr);
// ---
tr = Tr(tr0, tr1, tr2);
if(tr.is_degenerate())
continue;
std::set<CGAL::Oriented_side> os;
os.insert(tet.oriented_side(tr0));
os.insert(tet.oriented_side(tr1));
os.insert(tet.oriented_side(tr2));
std::cout << "Tet: " << tet << std::endl;
std::cout << "Tr: " << tr << std::endl;
if(os.size() == 1 && (*os.begin() == CGAL::ON_POSITIVE_SIDE))
check_do_not_intersect(tet, tr);
else
check_do_intersect(tet, tr);
}
}
void run()
{
std::cout << "3D Tetrahedron Intersection tests\n";
Tet_Tet();
Tet_Tr();
}
};
int main(int, char**)
{
std::cout.precision(17);
std::cerr.precision(17);
CGAL::Random r;
std::cout << "random seed = " << r.get_seed() << std::endl;
std::cout << " |||||||| Test Simple_cartesian<double> ||||||||" << std::endl;
Tetrahedron_3_intersection_tester< CGAL::Simple_cartesian<double> >(r).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::MP_Float> ||||||||" << std::endl;
Tetrahedron_3_intersection_tester< CGAL::Homogeneous<CGAL::MP_Float> >(r).run();
std::cout << " |||||||| Test EPICK ||||||||" << std::endl;
Tetrahedron_3_intersection_tester< CGAL::Epick >(r, true /*exact predicates*/).run();
std::cout << " |||||||| Test EPECK ||||||||" << std::endl;
Tetrahedron_3_intersection_tester< CGAL::Epeck >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << " |||||||| Test CGAL::Homogeneous<CGAL::Epeck_ft> ||||||||" << std::endl;
Tetrahedron_3_intersection_tester< CGAL::Homogeneous<CGAL::Epeck_ft> >(r, true /*exact predicates*/, true /*exact constructions*/).run();
std::cout << "OK!" << std::endl;
}

View File

@ -1,129 +0,0 @@
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick;
template<typename K>
void test_P_Cub()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Iso_cuboid_3<K> Cub;
P p(0.0,1.0,0.5);
Cub cub(P(-1.0,-1.0,-1.0), P(1.0,1.0,1.0));
assert(CGAL::do_intersect(p, cub));
CGAL::Object o = CGAL::intersection(p,cub);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_L()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Line_3<K> Line;
P p(0.99,0.99,0.99);
Line line(P(-1.0,-1.0,-1.0), P(1.0,1.0,1.0));
assert(CGAL::do_intersect(p, line));
CGAL::Object o = CGAL::intersection(p,line);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_R()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Ray_3<K> Ray;
P p(0.99,0.99,0.99);
Ray ray(P(-1.0,-1.0,-1.0), P(1.0,1.0,1.0));
assert(CGAL::do_intersect(p, ray));
CGAL::Object o = CGAL::intersection(p,ray);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_S()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Segment_3<K> S;
P p(0.99,0.99,0.99);
S s(P(-1.0,-1.0,-1.0), P(1.0,1.0,1.0));
assert(CGAL::do_intersect(p, s));
CGAL::Object o = CGAL::intersection(p,s);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_P()
{
typedef CGAL::Point_3<K> P;
P p(0.99,0.99,0.99);
assert(CGAL::do_intersect(p, p));
CGAL::Object o = CGAL::intersection(p,p);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_Pl()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Plane_3<K> Pl;
P p(0.99,0.99,0.99);
Pl pl(P(-1.0,-1.0,-1.0), P(1.0,1.0,1.0), P(0.0,0.0,0.0));
assert(CGAL::do_intersect(p, pl));
CGAL::Object o = CGAL::intersection(p,pl);
P res;
assert(assign(res, o));
assert(res == p);
}
template<typename K>
void test_P_Tet()
{
typedef CGAL::Point_3<K> P;
typedef CGAL::Tetrahedron_3<K> T;
P p(0,0,0), q(1,0,0), r(1,1,0), s(0,0,1);
T t(p,q,r,s);
P q0(0.1, 0.1, 0.1), q1(10,10,10);
assert(CGAL::do_intersect(p,t));
assert(CGAL::do_intersect(t,p));
assert(CGAL::do_intersect(q0,t));
assert(CGAL::do_intersect(t,q0));
assert(! CGAL::do_intersect(q1,t));
assert(! CGAL::do_intersect(t,q1));
}
int main()
{
test_P_Cub<Epick>();
test_P_Cub<Epeck>();
test_P_L<Epick>();
test_P_L<Epeck>();
test_P_R<Epick>();
test_P_R<Epeck>();
test_P_S<Epick>();
test_P_S<Epeck>();
test_P_P<Epick>();
test_P_P<Epeck>();
test_P_Pl<Epick>();
test_P_Pl<Epeck>();
test_P_Tet<Epick>();
test_P_Tet<Epeck>();
}
#include <iostream>

View File

@ -1,76 +0,0 @@
#include <cassert>
#include <CGAL/Cartesian.h>
typedef CGAL::Cartesian<double> K;
typedef K::Point_3 Point;
typedef K::Tetrahedron_3 Tetrahedron;
typedef K::Segment_3 Segment;
typedef K::Triangle_3 Triangle;
typedef K::Iso_cuboid_3 Iso_cuboid;
typedef K::Sphere_3 Sphere;
typedef K::Plane_3 Plane;
typedef K::Line_3 Line;
typedef K::Ray_3 Ray;
typedef CGAL::Bbox_3 Bbox;
int main()
{
Point p(0,0,0), q(10,0,0), r(10,10,0), s(0, 10,10);
Point p2(1,1,1), q2(20,20,20), r2(0,0,20);
Tetrahedron tet(p,q,r,s),
tet2(p, Point(9,0,0), Point(15, 15, 0), Point(0, 15, 10)),
v_v(p,Point(-10,0,0),Point(-10,-10,0), Point(0,-10,-10)),
v_e(Point(-10,0,0), Point(0,0,10), Point(0,0,-10), Point(-10,10,0)),
v_f(Point(-10,0,0), Point(0,-10,-10), Point(0,-10,10), Point(0,10,0)),
e_e(Point(-10,0,0), Point(-15,0,0), Point(0,5,10), Point(0,10,5)),
e_f(Point(0,15,15), Point(-15,0,0), Point(0,-11,10), Point(0,10,-11)),
f_f(Point(10,10,10), q, r, s),
tet3(Point(-1,0,0), Point(-10,0,0), Point(-10,-10,0), Point(0,-10,-10));
Sphere sp(p2,1.0);
CGAL::do_intersect(tet,Triangle(p2,q2,r2));
CGAL::do_intersect(tet,Segment(p2,q2));
CGAL::do_intersect(tet,Iso_cuboid(p2,q2));
CGAL::do_intersect(tet,sp);
CGAL::do_intersect(tet,Plane(p2,q2,r2));
CGAL::do_intersect(tet,Line(p2,q2));
CGAL::do_intersect(tet,Ray(p2,q2));
CGAL::do_intersect(tet,tet);
CGAL::do_intersect(tet,sp.bbox());
CGAL::do_intersect(sp, Line(p2,q2));
CGAL::do_intersect(sp, Ray(p2,q2));
CGAL::do_intersect(sp, Segment(p2,q2));
CGAL::do_intersect(Triangle(p2,q2,r2), tet);
CGAL::do_intersect(Segment(p2,q2), tet);
CGAL::do_intersect(Iso_cuboid(p2,q2), tet);
CGAL::do_intersect(sp, tet);
CGAL::do_intersect(Plane(p2,q2,r2), tet);
CGAL::do_intersect(Line(p2,q2), tet);
CGAL::do_intersect(Ray(p2,q2), tet);
CGAL::do_intersect(sp.bbox(), tet);
CGAL::do_intersect(Line(p2,q2), sp);
CGAL::do_intersect(Ray(p2,q2), sp);
CGAL::do_intersect(Segment(p2,q2), sp);
CGAL_assertion(CGAL::do_intersect(tet, v_e));
CGAL_assertion(CGAL::do_intersect(tet, v_f));
CGAL_assertion(CGAL::do_intersect(tet, v_v));
CGAL_assertion(CGAL::do_intersect(tet, tet2));
CGAL_assertion(CGAL::do_intersect(tet, e_e));
CGAL_assertion(CGAL::do_intersect(tet, e_f));
CGAL_assertion(CGAL::do_intersect(tet, f_f));
CGAL_assertion(!CGAL::do_intersect(tet, tet3));
return 0;
}

View File

@ -633,13 +633,13 @@ int main()
random_test<Sc_f>(); random_test<Sc_f>();
std::cout << "\tTesting with Simple_cartesian<double>..." << std::endl ; std::cout << "\tTesting with Simple_cartesian<double>..." << std::endl ;
random_test<Sc_d>(); random_test<Sc_d>();
std::cout << "\tTesting with Cartesian<float>..." << std::endl ; std::cout << "\tTesting with Cartesian<float>..." << std::endl ;
random_test<C_f>(); random_test<C_f>();
std::cout << "\tTesting with Cartesian<double>..." << std::endl ; std::cout << "\tTesting with Cartesian<double>..." << std::endl ;
random_test<C_d>(); random_test<C_d>();
std::cout << "\tTesting with Exact_predicates_inexact_constructions_kernel..." << std::endl ; std::cout << "\tTesting with Exact_predicates_inexact_constructions_kernel..." << std::endl ;
random_test<Epic>(); random_test<Epic>();