diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h index ae3fc8f8ef3..20c27711e82 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2.h @@ -32,8 +32,9 @@ #include -#include #include +#include +#include #include diff --git a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h index 1e1352c4014..de42a0980ea 100644 --- a/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h +++ b/Apollonius_graph_2/include/CGAL/Apollonius_graph_2/Apollonius_graph_2_impl.h @@ -817,69 +817,85 @@ check_edge_for_hidden_sites(const Face_handle& f, int i, template void Apollonius_graph_2:: -expand_conflict_region(const Face_handle& f, const Site_2& p, - List& l, Face_map& fm, Vertex_map& vm, - std::vector* fe) +expand_conflict_region(const Face_handle& in_f, + const Site_2& p, + List& l, + Face_map& fm, + Vertex_map& vm, + std::vector* fe) { - // setting fm[f] to true means that the face has been reached and - // that the face is available for recycling. If we do not want the - // face to be available for recycling we must set this flag to - // false. - fm[f] = true; + std::stack face_stack; + face_stack.push(in_f); - // CGAL_assertion( fm.find(f) != fm.end() ); - for (int i = 0; i < 3; i++) { - bool hidden_found = - check_edge_for_hidden_sites(f, i, p, vm); + while(!face_stack.empty()) + { + const Face_handle curr_f = face_stack.top(); + face_stack.pop(); - Face_handle n = f->neighbor(i); + // setting fm[curr_f] to true means that the face has been reached and + // that the face is available for recycling. If we do not want the + // face to be available for recycling we must set this flag to false. + fm[curr_f] = true; - if ( !hidden_found ) { - Sign s = incircle(n, p); - if ( s != NEGATIVE ) { continue; } + // CGAL_assertion( fm.find(curr_f) != fm.end() ); + for (int i = 0; i < 3; ++i) + { + bool hidden_found = check_edge_for_hidden_sites(curr_f, i, p, vm); - bool interior_in_conflict = edge_interior(f, i, p, true); + Face_handle n = curr_f->neighbor(i); - if ( !interior_in_conflict ) { continue; } - } + if ( !hidden_found ) + { + Sign s = incircle(n, p); + if ( s != NEGATIVE ) + continue; - if ( fm.find(n) != fm.end() ) { - Edge e = sym_edge(f, i); - if ( l.is_in_list(e) || - l.is_in_list(sym_edge(e)) ) { - l.remove(e); - l.remove(sym_edge(e)); + bool interior_in_conflict = edge_interior(curr_f, i, p, true); + if ( !interior_in_conflict ) + continue; } - continue; - } - Edge e = sym_edge(f, i); + if ( fm.find(n) != fm.end() ) + { + Edge e = sym_edge(curr_f, i); + if ( l.is_in_list(e) ) + l.remove(e); - CGAL_assertion( l.is_in_list(e) ); - int j = tds().mirror_index(f, i); - Edge e_before = sym_edge(n, ccw(j)); - Edge e_after = sym_edge(n, cw(j)); - if ( !l.is_in_list(e_before) ) { - l.insert_before(e, e_before); - } - if ( !l.is_in_list(e_after) ) { - l.insert_after(e, e_after); - } - l.remove(e); + if( l.is_in_list(sym_edge(e)) ) + l.remove(sym_edge(e)); - if ( fe != nullptr ) { - Vh_triple* vhq = new Vh_triple[1]; + continue; + } - (*vhq)[0] = Vertex_handle(); - (*vhq)[1] = n->vertex( j ); - (*vhq)[2] = n->vertex( ccw(j) ); + Edge e = sym_edge(curr_f, i); + CGAL_assertion( l.is_in_list(e) ); - fe->push_back(vhq); - } + int j = tds().mirror_index(curr_f, i); + Edge e_before = sym_edge(n, ccw(j)); + Edge e_after = sym_edge(n, cw(j)); + if ( !l.is_in_list(e_before) ) + l.insert_before(e, e_before); - expand_conflict_region(n, p, l, fm, vm, fe); - } // for-loop + if ( !l.is_in_list(e_after) ) + l.insert_after(e, e_after); + + l.remove(e); + + if ( fe != nullptr ) + { + Vh_triple* vhq = new Vh_triple[1]; + + (*vhq)[0] = Vertex_handle(); + (*vhq)[1] = n->vertex( j ); + (*vhq)[2] = n->vertex( ccw(j) ); + + fe->push_back(vhq); + } + + face_stack.push(n); + } // neighbor for-loop + } } diff --git a/Convex_hull_3/doc/Convex_hull_3/CGAL/Convex_hull_traits_3.h b/Convex_hull_3/doc/Convex_hull_3/CGAL/Convex_hull_traits_3.h index 1c8b0619343..ee7e28c9b7e 100644 --- a/Convex_hull_3/doc/Convex_hull_3/CGAL/Convex_hull_traits_3.h +++ b/Convex_hull_3/doc/Convex_hull_3/CGAL/Convex_hull_traits_3.h @@ -13,6 +13,13 @@ function when `R` is a kernel with exact predicates but inexact constructions \cgalModels `IsStronglyConvexTraits_3` \attention The user must include the header file of the polygon mesh type, even for the default type. + +\cgalAdvancedBegin +This class has a fourth undocumented template argument. Passing `CGAL::Tag_false` +switches off a caching of a plane with coordinates with interval arithmetic. +Instead an orientation test of four points is performed. +\cgalAdvancedEnd + */ template< typename R, typename PolygonMesh = Polyhedron_3 > class Convex_hull_traits_3 { diff --git a/Convex_hull_3/doc/Convex_hull_3/CGAL/convex_hull_3.h b/Convex_hull_3/doc/Convex_hull_3/CGAL/convex_hull_3.h index 6227b56d944..bc83e1d13a0 100644 --- a/Convex_hull_3/doc/Convex_hull_3/CGAL/convex_hull_3.h +++ b/Convex_hull_3/doc/Convex_hull_3/CGAL/convex_hull_3.h @@ -4,7 +4,7 @@ namespace CGAL { \ingroup PkgConvexHull3Functions \brief computes the convex hull of the set of points in the range -[`first`, `last`). The polyhedron `pm` is cleared, then +[`first`, `last`). The polygon mesh `pm` is cleared, then the convex hull is stored in `pm`. Note that the convex hull will be triangulated, that is `pm` will contain only triangular facets. if the convex hull is a point or a segment, endpoints will be added in `pm` as isolated vertices. @@ -39,9 +39,9 @@ void convex_hull_3(InputIterator first, InputIterator last, PolygonMesh& pm, con \brief computes the convex hull of the set of points in the range [`first`, `last`). The result, which may be a point, a segment, -a triangle, or a polyhedron, is stored in `ch_object`. -In the case the result is a polyhedron, the convex hull will be triangulated, -that is the polyhedron will contain only triangular facets. +a triangle, or a polygon mesh, is stored in `ch_object`. +In the case the result is a polygon mesh, the convex hull will be triangulated, +that is the polygon mesh will contain only triangular facets. \tparam InputIterator must be an input iterator with a value type equivalent to `Traits::Point_3`. \tparam Traits must be model of the concept `ConvexHullTraits_3`. diff --git a/Convex_hull_3/doc/Convex_hull_3/Convex_hull_3.txt b/Convex_hull_3/doc/Convex_hull_3/Convex_hull_3.txt index 74ef744c7b3..b7d25b6b505 100644 --- a/Convex_hull_3/doc/Convex_hull_3/Convex_hull_3.txt +++ b/Convex_hull_3/doc/Convex_hull_3/Convex_hull_3.txt @@ -49,11 +49,19 @@ computing the hull. The function `convex_hull_3()` is parameterized by a traits class, which specifies the types and geometric primitives to be used in the -computation. If input points from a kernel with exact predicates +computation. As the function constructs 3D planes from three input +points, we cannot simply pass a kernel with inexact constructions as +optional argument for the traits class. + +If input points from a kernel with exact predicates and non-exact constructions are used, and a certified result is expected, -the traits `Convex_hull_traits_3` should be used -(`R` being the input kernel). Note that the default traits class takes this into -account. +the class `Convex_hull_traits_3` should be used +(`R` being the input kernel). +If the constructions from a kernel are exact this kernel can be used +directly as a traits class. + +Note that the default traits class takes this into account, that is the +above considerations are only important for custom traits classes. \subsubsection Convex_hull_3Example Example diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index 14ddc9354ef..87de0bf0782 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -236,17 +237,23 @@ public: //and in case of failure, exact arithmetic is used. template class Is_on_positive_side_of_plane_3, boost::true_type >{ - typedef Simple_cartesian::Type> PK; - typedef Simple_cartesian CK; + typedef Simple_cartesian::Type> Exact_K; + typedef Simple_cartesian Approx_K; typedef Convex_hull_traits_3 Traits; typedef typename Traits::Point_3 Point_3; - Cartesian_converter to_CK; - Cartesian_converter to_PK; + Cartesian_converter to_AK; + Cartesian_converter to_EK; + + template + struct Vector_plus_point { + typename K::Vector_3 vector; + typename K::Point_3 point; + }; const Point_3& p,q,r; - mutable typename CK::Plane_3* ck_plane; - mutable typename PK::Plane_3* pk_plane; + mutable Vector_plus_point ak_plane; + mutable Vector_plus_point* ek_plane_ptr; double m10,m20,m21,Maxx,Maxy,Maxz; @@ -292,8 +299,13 @@ public: typedef typename Interval_nt_advanced::Protector Protector; Is_on_positive_side_of_plane_3(const Traits&,const Point_3& p_,const Point_3& q_,const Point_3& r_) - :p(p_),q(q_),r(r_),ck_plane(nullptr),pk_plane(nullptr) + : p(p_),q(q_),r(r_) + , ak_plane() + , ek_plane_ptr(nullptr) { + ak_plane.vector = + typename Approx_K::Vector_3(Interval_nt_advanced(0., std::numeric_limits::infinity()), + 0., 0.); double pqx = q.x() - p.x(); double pqy = q.y() - p.y(); double pqz = q.z() - p.z(); @@ -319,8 +331,7 @@ public: } ~Is_on_positive_side_of_plane_3(){ - if (ck_plane!=nullptr) delete ck_plane; - if (pk_plane!=nullptr) delete pk_plane; + if (ek_plane_ptr!=nullptr) delete ek_plane_ptr; } bool operator() (const Point_3& s) const @@ -334,15 +345,29 @@ public: return static_res == 1; try{ - if (ck_plane==nullptr) - ck_plane=new typename CK::Plane_3(to_CK(p),to_CK(q),to_CK(r)); - return ck_plane->has_on_positive_side(to_CK(s)); + // infinity() is the sentinel for uninitialized `ak_plane` + if (ak_plane.vector.x().sup() == std::numeric_limits::infinity()) + { + const typename Approx_K::Point_3 ap = to_AK(p); + ak_plane.vector = cross_product(to_AK(q)-ap, to_AK(r)-ap); + ak_plane.point = ap; + } + Uncertain res = + sign(scalar_product(to_AK(s) - ak_plane.point, + ak_plane.vector)); + if(is_certain(res)) { + return (get_certain(res) == POSITIVE); + } } - catch (Uncertain_conversion_exception&){ - if (pk_plane==nullptr) - pk_plane=new typename PK::Plane_3(to_PK(p),to_PK(q),to_PK(r)); - return pk_plane->has_on_positive_side(to_PK(s)); + catch (Uncertain_conversion_exception&){} + if (ek_plane_ptr==nullptr) { + const typename Exact_K::Point_3 ep = to_EK(p); + ek_plane_ptr = new Vector_plus_point; + ek_plane_ptr->vector = cross_product(to_EK(q)-ep, to_EK(r)-ep); + ek_plane_ptr->point = ep; } + return sign(scalar_product(to_EK(s) - ek_plane_ptr->point, + ek_plane_ptr->vector)) == POSITIVE; } }; diff --git a/Convex_hull_3/test/Convex_hull_3/test_extreme_points.cpp b/Convex_hull_3/test/Convex_hull_3/test_extreme_points.cpp index 9b9ee278cbb..0d09b2b6243 100644 --- a/Convex_hull_3/test/Convex_hull_3/test_extreme_points.cpp +++ b/Convex_hull_3/test/Convex_hull_3/test_extreme_points.cpp @@ -14,7 +14,7 @@ #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Epick_without_intervals K; typedef CGAL::Polyhedron_3 Polyhedron_3; typedef K::Point_3 Point_3; diff --git a/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp b/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp index 385236066d9..623dec0cc25 100644 --- a/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp +++ b/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp @@ -81,4 +81,6 @@ int main() test >(); test >(); test >(); + test >(); } diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h index aaa9f323f1c..88f342201ac 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h @@ -26,21 +26,46 @@ #include #include -#include +#include namespace CGAL { +namespace Intersections { +namespace internal { + +template +bool do_intersect(const CGAL::Bbox_2& bbox, + const typename K::Circle_2& circle, + const K&) +{ + return do_intersect_circle_iso_rectangle_2(circle, bbox, K()); +} + + +template +bool do_intersect(const typename K::Circle_2& circle, + const CGAL::Bbox_2& bbox, + const K&) +{ + return do_intersect_circle_iso_rectangle_2(circle, bbox, K()); +} + +} // namespace internal +} // namespace Intersections template bool do_intersect(const CGAL::Bbox_2& a, - const Circle_2& b) { + const Circle_2& b) +{ return K().do_intersect_2_object()(a, b); } template bool do_intersect(const Circle_2& a, - const CGAL::Bbox_2& b) { + const CGAL::Bbox_2& b) +{ return K().do_intersect_2_object()(a, b); } -} +} // namespace CGAL + #endif // CGAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h index c5804de228c..a68eaa2a9a0 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h @@ -23,80 +23,50 @@ // // Author(s) : Geert-Jan Giezeman - #ifndef CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H #define CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H #include #include -#include -#include + +#include namespace CGAL { +namespace Intersections { +namespace internal { -class Bbox_2_Line_2_pair_impl; - -class CGAL_EXPORT Bbox_2_Line_2_pair { -public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; - Bbox_2_Line_2_pair() ; - Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &); - Bbox_2_Line_2_pair(Bbox_2 const &bbox, - double line_a, double line_b, double line_c); - ~Bbox_2_Line_2_pair() ; - Bbox_2_Line_2_pair &operator=(Bbox_2_Line_2_pair const &o); - // set_bbox(Bbox_2 const &bbox); - // set_line(double line_a, double line_b, double line_c); - Intersection_results intersection_type() const; - bool intersection(double &x, double &y) const; - bool intersection(double &x1, double &y1, double &x2, double &y2) const; -protected: - Bbox_2_Line_2_pair_impl *pimpl; -}; - -template -Bbox_2_Line_2_pair intersection_computer_line_2( - Bbox_2 const &bbox, Line const &line) +template +bool do_intersect(const typename K::Line_2& line, + const CGAL::Bbox_2& bbox, + const K& k) { - return Bbox_2_Line_2_pair(bbox, to_double(line->a()), - to_double(line->b()), to_double(line->c())); + typedef typename K::Iso_rectangle_2 Iso_rectangle_2; + return Intersections::internal::do_intersect(line, Iso_rectangle_2(bbox), k); } -inline bool do_intersect_line_2( - const Bbox_2 &box, double line_a, double line_b, double line_c) +template +bool do_intersect(const CGAL::Bbox_2& bbox, + const typename K::Line_2& line, + const K& k) { - Bbox_2_Line_2_pair pair(box, line_a, line_b, line_c); - return pair.intersection_type() != Bbox_2_Line_2_pair::NO_INTERSECTION; + return Intersections::internal::do_intersect(line, bbox, k); } -template -bool do_intersect_line_2( - Bbox_2 const &bbox, Line const &line) +} // namespace internal +} // namespace Intersections + +template +bool do_intersect(const CGAL::Bbox_2& bbox, const Line_2& line) { - return do_intersect_line_2(bbox, to_double(line->a()), - to_double(line->b()), to_double(line->c())); + return K().do_intersect_2_object()(bbox, line); } -template -bool do_intersect_line_2( - Line const &line, Bbox_2 const &bbox) +template +bool do_intersect(const Line_2& line, const CGAL::Bbox_2& bbox) { - return do_intersect_line_2(bbox, to_double(line->a()), - to_double(line->b()), to_double(line->c())); + return K().do_intersect_2_object()(line, bbox); } -template -inline bool do_intersect( - const Line_2 &line, - const Bbox_2 &box) -{ - return do_intersect(box, line); -} +} // namespace CGAL -} //namespace CGAL - -#ifdef CGAL_HEADER_ONLY -#include -#endif // CGAL_HEADER_ONLY - -#endif +#endif // CGAL_INTERSECTIONS_2_BBOX_2_LINE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h index 5df79996e48..c047a36474c 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h @@ -29,29 +29,29 @@ #include namespace CGAL { - -template -bool do_intersect(const CGAL::Bbox_2& a, - const Point_2& b) -{ - Point_2 bl(a.xmin(), a.ymin()), tr(a.xmax(), a.ymax()); - - Iso_rectangle_2 ic(bl,tr); - return K().do_intersect_2_object()(ic, b); -} - - -template -bool do_intersect(const Point_2& a, - const CGAL::Bbox_2& b) -{ - return do_intersect(b,a); -} - namespace Intersections { - namespace internal { +template +inline bool do_intersect(const Bbox_2 &bbox, + const Point_2 &pt, + const K& k) +{ + Point_2 bl(bbox.xmin(), bbox.ymin()), + tr(bbox.xmax(), bbox.ymax()); + Iso_rectangle_2 ic(bl,tr); + + return k.do_intersect_2_object()(ic, pt); +} + +template +inline bool do_intersect(const Point_2 &pt, + const Bbox_2& bbox, + const K& k) +{ + return do_intersect(bbox, pt, k); +} + template typename CGAL::Intersection_traits::result_type intersection(const Point_2& a, @@ -77,6 +77,20 @@ intersection(const CGAL::Bbox_2& b, } // namespace internal } // namespace Intersections +template +bool do_intersect(const CGAL::Bbox_2& a, + const Point_2& b) +{ + return Intersections::internal::do_intersect(a,b,K()); +} + +template +bool do_intersect(const Point_2& a, + const CGAL::Bbox_2& b) +{ + return Intersections::internal::do_intersect(b,a,K()); +} + template typename CGAL::Intersection_traits >::result_type intersection(const Bbox_2& b, @@ -92,6 +106,7 @@ typename CGAL::Intersection_traits >::result_type { return Intersections::internal::intersection(b,a,K()); } + } // namespace CGAL #endif // CGAL_INTERSECTIONS_2_BBOX_2_POINT_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h index 512f4779b2f..589283cc222 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h @@ -1,9 +1,9 @@ -// Copyright (c) 2000 +// Copyright (c) 2000 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. +// and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as @@ -19,65 +19,54 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0+ -// +// // // Author(s) : Geert-Jan Giezeman - -#ifndef CGAL_INTERSECTIONS_BBOX_2_RAY_2_H -#define CGAL_INTERSECTIONS_BBOX_2_RAY_2_H +#ifndef CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H +#define CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H #include #include -#include -#include + +#include namespace CGAL { +namespace Intersections { +namespace internal { -class Bbox_2_Ray_2_pair_impl; - -class CGAL_EXPORT Bbox_2_Ray_2_pair { -public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; - ~Bbox_2_Ray_2_pair() ; - Bbox_2_Ray_2_pair() ; - Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o) ; - Bbox_2_Ray_2_pair(Bbox_2 const &box, - double x, double y, double dx, double dy) ; - Bbox_2_Ray_2_pair& operator=(Bbox_2_Ray_2_pair const &o) ; - Intersection_results intersection_type() const; - bool intersection(double &x, double &y) const; - bool intersection(double &x1, double &y1, double &x2, double &y2) const; -protected: - Bbox_2_Ray_2_pair_impl *pimpl; -}; - -CGAL_EXPORT bool do_intersect_ray_2( - const Bbox_2 &box, double x, double y, double dx, double dy); - -template -bool do_intersect_ray_2( - const Bbox_2 &box, - const Ray &ray) +template +bool do_intersect(const typename K::Ray_2& ray, + const CGAL::Bbox_2& bbox, + const K& k) { - double startx = to_double(ray->start().x()); - double starty = to_double(ray->start().y()); - double dx = to_double(ray->direction().to_vector().x()); - double dy = to_double(ray->direction().to_vector().y()); - return do_intersect_ray_2(box, startx, starty, dx, dy); + typedef typename K::Iso_rectangle_2 Iso_rectangle_2; + return Intersections::internal::do_intersect(ray, Iso_rectangle_2(bbox), k); } -template -inline bool do_intersect_ray_2( - const Ray &ray, - const Bbox_2 &box) +template +bool do_intersect(const CGAL::Bbox_2& bbox, + const typename K::Ray_2& ray, + const K& k) { - return do_intersect_ray_2(box, ray); + return Intersections::internal::do_intersect(ray, bbox, k); } -} //namespace CGAL -#ifdef CGAL_HEADER_ONLY -#include -#endif // CGAL_HEADER_ONLY +} // namespace internal +} // namespace Intersections -#endif +template +bool do_intersect(const CGAL::Bbox_2& bbox, const Ray_2& ray) +{ + return K().do_intersect_2_object()(bbox, ray); +} + +template +bool do_intersect(const Ray_2& ray, const CGAL::Bbox_2& bbox) +{ + return K().do_intersect_2_object()(ray, bbox); +} + +} // namespace CGAL + +#endif // CGAL_INTERSECTIONS_2_BBOX_2_RAY_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h index 230d2e6791a..05c49b53a1a 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h @@ -23,47 +23,38 @@ // // Author(s) : Geert-Jan Giezeman - #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #include #include -namespace CGAL { - -namespace Intersections { +#include +namespace CGAL { +namespace Intersections { namespace internal { template -bool -do_intersect(const typename K::Circle_2 & circ1, - const typename K::Circle_2& circ2, - const K&) +bool do_intersect(const typename K::Circle_2 & circ1, + const typename K::Circle_2& circ2, + const K&) { - typedef typename K::FT FT; - FT sr1 = circ1.squared_radius(); - FT sr2 = circ2.squared_radius(); - FT squared_dist = squared_distance(circ1.center(), circ2.center()); - FT temp = sr1+sr2-squared_dist; - return !(FT(4)*sr1*sr2 < temp*temp); + typedef typename K::FT FT; + + FT sr1 = circ1.squared_radius(); + FT sr2 = circ2.squared_radius(); + FT squared_dist = squared_distance(circ1.center(), circ2.center()); + FT temp = sr1+sr2-squared_dist; + + return !(FT(4)*sr1*sr2 < temp*temp); } } // namespace internal } // namespace Intersections -template -inline -bool -do_intersect(const Circle_2 & circ1, - const Circle_2 & circ2) -{ - typedef typename K::Do_intersect_2 Do_intersect; - return Do_intersect()(circ1, circ2); -} +CGAL_DO_INTERSECT_FUNCTION_SELF(Circle_2, 2) - -} //namespace CGAL +} // namespace CGAL #endif diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h index 8aae18ec2d2..94193a52746 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Iso_rectangle_2.h @@ -23,13 +23,105 @@ #ifndef CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H -#include #include - -#include +#include +#include namespace CGAL { - CGAL_DO_INTERSECT_FUNCTION(Iso_rectangle_2, Circle_2, 2) +namespace Intersections { +namespace internal { + +// Circle_2 is not a disk, thus if the box is contained within the circle, there is no intersection. +template +bool do_intersect_circle_iso_rectangle_2(const typename K::Circle_2& circle, + const typename K::Iso_rectangle_2& rec, + const K&) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point; + + Point center = circle.center(); + + // Check that the minimum distance to the box is smaller than the radius, otherwise there is + // no intersection. + FT distance = FT(0); + if(center.x() < rec.xmin()) + { + FT d = rec.xmin() - center.x(); + distance += d * d; + } + else if(center.x() > rec.xmax()) + { + FT d = center.x() - rec.xmax(); + distance += d * d; + } + + if(center.y() < rec.ymin()) + { + FT d = rec.ymin() - center.y(); + distance += d * d; + } + else if(center.y() > rec.ymax()) + { + FT d = center.y() - rec.ymax(); + distance += d * d; + } + + // Note that with the way the distance above is computed, the distance is '0' if the box strictly + // contains the circle. But since we use '>', we don't exit + if(distance > circle.squared_radius()) + return false; + + // Check that the maximum distance between the center of the circle and the box is not (strictly) + // smaller than the radius of the center, otherwise the box is entirely contained. + distance = FT(0); + if(center.x() <= (rec.xmin() + rec.xmax()) / FT(2)) + { + FT d = rec.xmax() - center.x(); + distance += d * d; + } + else + { + FT d = center.x() - rec.xmin(); + distance += d * d; + } + + if(center.y() < (rec.ymin() + rec.ymax()) / FT(2)) + { + FT d = rec.ymax() - center.y(); + distance += d * d; + } + else + { + FT d = center.y() - rec.ymin(); + distance += d * d; + } + + return (distance >= circle.squared_radius()); +} + +template +bool do_intersect(const typename K::Iso_rectangle_2& rec, + const typename K::Circle_2& circle, + const K&) +{ + return do_intersect_circle_iso_rectangle_2(circle, rec, K()); +} + + +template +bool do_intersect(const typename K::Circle_2& circle, + const typename K::Iso_rectangle_2& rec, + const K&) +{ + return do_intersect_circle_iso_rectangle_2(circle, rec, K()); +} + +} // namespace internal +} // namespace Intersections + +CGAL_DO_INTERSECT_FUNCTION(Iso_rectangle_2, Circle_2, 2) + } #endif // CGAL_INTERSECTIONS_2_ISO_RECTANGLE_2_CIRCLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h index c678fa3b426..49e7e90183b 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace CGAL { namespace Intersections { @@ -38,45 +39,26 @@ namespace internal { template bool do_intersect(const typename K::Circle_2 & c, - const typename K::Line_2& l, - const K&) + const typename K::Line_2& l, + const K&) { - return squared_distance(c.center(), l) <= c.squared_radius(); + return squared_distance(c.center(), l) <= c.squared_radius(); } template bool do_intersect(const typename K::Line_2& l, - const typename K::Circle_2 & c, - const K&) + const typename K::Circle_2 & c, + const K&) { - return squared_distance(c.center(), l) <= c.squared_radius(); + return squared_distance(c.center(), l) <= c.squared_radius(); } } // namespace internal } // namespace Intersections - -template -inline -bool -do_intersect(const Circle_2 & c, - const Line_2 & l) -{ - typedef typename K::Do_intersect_2 Do_intersect; - return Do_intersect()(c, l); -} -template -inline -bool -do_intersect(const Line_2 & l, - const Circle_2 & c) -{ - typedef typename K::Do_intersect_2 Do_intersect; - return Do_intersect()(c, l); -} +CGAL_DO_INTERSECT_FUNCTION(Circle_2, Line_2, 2) - -} //namespace CGAL +} // namespace CGAL #endif diff --git a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Triangle_2.h index 58991d7dfde..77ba8ec266c 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Triangle_2.h @@ -272,7 +272,10 @@ namespace internal { //remove duplicated consecutive points typename std::vector::iterator last = std::unique(result.begin(),result.end()); result.erase(last,result.end()); - + + while(result.size() > 1 && result.back() == result.front()) + result.pop_back(); + switch(result.size()){ case 0: return intersection_return(); diff --git a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h index 650eb3ad0ab..06af94fd400 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h @@ -157,7 +157,7 @@ intersection(const typename K::Ray_2 &ray, default: return intersection_return(); case is_t::POINT: - return intersection_return(ispair.intersection_segment()); + return intersection_return(ispair.intersection_point()); case is_t::SEGMENT: return intersection_return(ispair.intersection_segment()); } diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Circle_2_do_intersect.h b/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Circle_2_do_intersect.h deleted file mode 100644 index 6306d383ef3..00000000000 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Circle_2_do_intersect.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2018 GeometryFactory (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Andreas Fabri - - -#ifndef CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H -#define CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H - -#include -#include - -#include - - -namespace CGAL { - -namespace Intersections { - -namespace internal { - -template -bool do_intersect_circle_box_2(const typename K::Circle_2& circle, - const Box3& bbox, - const K&) -{ - typedef typename K::FT FT; - typedef typename K::Point_2 Point; - FT d = FT(0); - FT distance = FT(0); - Point center = circle.center(); - - if(center.x() < FT(bbox.xmin())) - { - d = FT(bbox.xmin()) - center.x(); - distance += d * d; - } - else if(center.x() > FT(bbox.xmax())) - { - d = center.x() - FT(bbox.xmax()); - distance += d * d; - } - - if(center.y() < FT(bbox.ymin())) - { - d = FT(bbox.ymin()) - center.y(); - distance += d * d; - } - else if(center.y() > FT(bbox.ymax())) - { - d = center.y() - FT(bbox.ymax()); - distance += d * d; - } - - return distance <= circle.squared_radius(); -} - -template -bool do_intersect(const CGAL::Bbox_2& bbox, - const typename K::Circle_2& circle, - const K&) -{ - return do_intersect_circle_box_2(circle, bbox, K()); -} - - -template -bool do_intersect(const typename K::Circle_2& circle, - const CGAL::Bbox_2& bbox, - const K&) -{ - return do_intersect_circle_box_2(circle, bbox, K()); -} - -template -bool do_intersect(const typename K::Iso_rectangle_2& bbox, - const typename K::Circle_2& circle, - const K&) -{ - return do_intersect_circle_box_2(circle, bbox, K()); -} - - -template -bool do_intersect(const typename K::Circle_2& circle, - const typename K::Iso_rectangle_2& bbox, - const K&) -{ - return do_intersect_circle_box_2(circle, bbox, K()); -} - -} // namespace internal -} // namespace Intersections -} //namespace CGAL - -#endif // CGAL_INTERNAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_DO_INTERSECT_H diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Line_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Line_2_intersection_impl.h deleted file mode 100644 index 6ed36f37872..00000000000 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Bbox_2_Line_2_intersection_impl.h +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 2000 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Geert-Jan Giezeman - -#ifdef CGAL_HEADER_ONLY -#define CGAL_INLINE_FUNCTION inline -#else -#define CGAL_INLINE_FUNCTION -#endif - -#include -typedef CGAL::Simple_cartesian Lcart; - - -namespace CGAL { - -class Bbox_2_Line_2_pair_impl -{ -public: - Bbox_2_Line_2_pair_impl() {} - Bbox_2_Line_2_pair_impl(Bbox_2 const &bb, Lcart::Line_2 const &line) - : _bbox(bb), _line(line), _known(false) {} - Bbox_2 _bbox; - Lcart::Line_2 _line; - mutable bool _known; - mutable Bbox_2_Line_2_pair::Intersection_results _result; - mutable double _min, _max; -}; - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair::~Bbox_2_Line_2_pair() -{ - delete pimpl; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair::Bbox_2_Line_2_pair() -{ - pimpl = new Bbox_2_Line_2_pair_impl; - pimpl->_known = false; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &o) -{ - pimpl = new Bbox_2_Line_2_pair_impl(*o.pimpl); -} - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair::Bbox_2_Line_2_pair( - Bbox_2 const &bbox, double line_a, double line_b, double line_c) -{ - pimpl = new Bbox_2_Line_2_pair_impl(bbox, - Lcart::Line_2(line_a, line_b, line_c)); -} - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair & -Bbox_2_Line_2_pair::operator=(Bbox_2_Line_2_pair const &o) -{ - *pimpl = *o.pimpl; - return *this; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Line_2_pair::Intersection_results -Bbox_2_Line_2_pair::intersection_type() const -{ - if (pimpl->_known) - return pimpl->_result; - // The non const this pointer is used to cast away const. - pimpl->_known = true; - const Lcart::Point_2 &ref_point = pimpl->_line.point(); - const Lcart::Vector_2 &dir = - pimpl->_line.direction().to_vector(); - bool to_infinity = true; -// first on x value - if (dir.x() == 0.0) { - if (ref_point.x() < pimpl->_bbox.xmin()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - if (ref_point.x() > pimpl->_bbox.xmax()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } else { - double newmin, newmax; - if (dir.x() > 0.0) { - newmin = (pimpl->_bbox.xmin()-ref_point.x())/dir.x(); - newmax = (pimpl->_bbox.xmax()-ref_point.x())/dir.x(); - } else { - newmin = (pimpl->_bbox.xmax()-ref_point.x())/dir.x(); - newmax = (pimpl->_bbox.xmin()-ref_point.x())/dir.x(); - } - if (to_infinity) { - pimpl->_min = newmin; - pimpl->_max = newmax; - } else { - if (newmin > pimpl->_min) - pimpl->_min = newmin; - if (newmax < pimpl->_max) - pimpl->_max = newmax; - if (pimpl->_max < pimpl->_min) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } - to_infinity = false; - } -// now on y value - if (dir.y() == 0.0) { - if (ref_point.y() < pimpl->_bbox.ymin()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - if (ref_point.y() > pimpl->_bbox.ymax()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } else { - double newmin, newmax; - if (dir.y() > 0.0) { - newmin = (pimpl->_bbox.ymin()-ref_point.y())/dir.y(); - newmax = (pimpl->_bbox.ymax()-ref_point.y())/dir.y(); - } else { - newmin = (pimpl->_bbox.ymax()-ref_point.y())/dir.y(); - newmax = (pimpl->_bbox.ymin()-ref_point.y())/dir.y(); - } - if (to_infinity) { - pimpl->_min = newmin; - pimpl->_max = newmax; - } else { - if (newmin > pimpl->_min) - pimpl->_min = newmin; - if (newmax < pimpl->_max) - pimpl->_max = newmax; - if (pimpl->_max < pimpl->_min) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } - to_infinity = false; - } - CGAL_kernel_assertion(!to_infinity); - if (pimpl->_max == pimpl->_min) { - pimpl->_result = POINT; - return pimpl->_result; - } - pimpl->_result = SEGMENT; - return pimpl->_result; -} - -CGAL_INLINE_FUNCTION -bool -Bbox_2_Line_2_pair::intersection( - double &x1, double &y1, double &x2, double &y2) const -{ - if (!pimpl->_known) - intersection_type(); - if (pimpl->_result != SEGMENT) - return false; - Lcart::Point_2 p1(pimpl->_line.point() - + pimpl->_min*pimpl->_line.direction().to_vector()); - Lcart::Point_2 p2(pimpl->_line.point() - + pimpl->_max*pimpl->_line.direction().to_vector()); - x1 = p1.x(); - y1 = p1.y(); - x2 = p2.x(); - y2 = p2.y(); - return true; -} - -CGAL_INLINE_FUNCTION -bool -Bbox_2_Line_2_pair::intersection( - double &x, double &y) const -{ - if (!pimpl->_known) - intersection_type(); - if (pimpl->_result != POINT) - return false; - Lcart::Point_2 pt(pimpl->_line.point() - + pimpl->_min*pimpl->_line.direction().to_vector()); - x = pt.x(); - y = pt.y(); - return true; -} - -} //namespace CGAL diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Ray_2_Bbox_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Ray_2_Bbox_2_intersection_impl.h deleted file mode 100644 index 375fc396865..00000000000 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Ray_2_Bbox_2_intersection_impl.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2000 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Geert-Jan Giezeman - -#ifdef CGAL_HEADER_ONLY -#define CGAL_INLINE_FUNCTION inline -#else -#define CGAL_INLINE_FUNCTION -#endif - -#include -typedef CGAL::Simple_cartesian Rcart; - - -namespace CGAL { - -class Bbox_2_Ray_2_pair_impl -{ -public: - Bbox_2_Ray_2_pair_impl():_known(false) {} - Bbox_2_Ray_2_pair_impl(Bbox_2 const &bbox, Rcart::Point_2 const &pt, - Rcart::Vector_2 const &dir) - :_box(bbox), _known(false), _ref_point(pt), _dir(dir), _min(0.0) {} - Ray_2< Rcart > _ray; - Bbox_2 _box; - bool _known; - Bbox_2_Ray_2_pair::Intersection_results _result; - Rcart::Point_2 _ref_point; - Rcart::Vector_2 _dir; - double _min, _max; -}; - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair::~Bbox_2_Ray_2_pair() -{ - delete pimpl; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair() -{ - pimpl = new Bbox_2_Ray_2_pair_impl; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o) -{ - pimpl = new Bbox_2_Ray_2_pair_impl(*o.pimpl); -} - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair( - Bbox_2 const &bbox, double x, double y, double dx, double dy) -{ - pimpl = new Bbox_2_Ray_2_pair_impl(bbox, - Rcart::Point_2(x,y), Rcart::Vector_2(dx,dy)); -} - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair & -Bbox_2_Ray_2_pair::operator=(Bbox_2_Ray_2_pair const &o) -{ - *pimpl = *o.pimpl; - return *this; -} - -CGAL_INLINE_FUNCTION -Bbox_2_Ray_2_pair::Intersection_results -Bbox_2_Ray_2_pair::intersection_type() const -{ - if (pimpl->_known) - return pimpl->_result; - pimpl->_known = true; - bool to_infinity = true; -// first on x value - if (pimpl->_dir.x() == 0.0) { - if (pimpl->_ref_point.x() < pimpl->_box.xmin()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - if (pimpl->_ref_point.x() > pimpl->_box.xmax()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } else { - double newmin, newmax; - if (pimpl->_dir.x() > 0.0) { - newmin =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x(); - newmax =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x(); - } else { - newmin =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x(); - newmax =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x(); - } - if (newmin > pimpl->_min) - pimpl->_min = newmin; - if (to_infinity) { - pimpl->_max = newmax; - } else { - if (newmax < pimpl->_max) - pimpl->_max = newmax; - } - if (pimpl->_max < pimpl->_min){ - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - to_infinity = false; - } -// now on y value - if (pimpl->_dir.y() == 0.0) { - if (pimpl->_ref_point.y() < pimpl->_box.ymin()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - if (pimpl->_ref_point.y() > pimpl->_box.ymax()) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - } else { - double newmin, newmax; - if (pimpl->_dir.y() > 0.0) { - newmin =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y(); - newmax =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y(); - } else { - newmin =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y(); - newmax =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y(); - } - if (newmin > pimpl->_min) - pimpl->_min = newmin; - if (to_infinity) { - pimpl->_max = newmax; - } else { - if (newmax < pimpl->_max) - pimpl->_max = newmax; - } - if (pimpl->_max < pimpl->_min) { - pimpl->_result = NO_INTERSECTION; - return pimpl->_result; - } - to_infinity = false; - } - CGAL_kernel_assertion(!to_infinity); - if (pimpl->_max == pimpl->_min) { - pimpl->_result = POINT; - return pimpl->_result; - } - pimpl->_result = SEGMENT; - return pimpl->_result; -} - -CGAL_INLINE_FUNCTION -bool Bbox_2_Ray_2_pair:: -intersection(double &x1, double &y1, double &x2, double &y2) const -{ - if (!pimpl->_known) - intersection_type(); - if (pimpl->_result != SEGMENT) - return false; - Rcart::Point_2 p1(pimpl->_ref_point + pimpl->_min*pimpl->_dir); - Rcart::Point_2 p2(pimpl->_ref_point + pimpl->_max*pimpl->_dir); - x1 = p1.x(); - y1 = p1.y(); - x2 = p2.x(); - y2 = p2.y(); - return true; -} - -CGAL_INLINE_FUNCTION -bool Bbox_2_Ray_2_pair::intersection(double &x, double &y) const -{ - if (!pimpl->_known) - intersection_type(); - if (pimpl->_result != POINT) - return false; - Rcart::Point_2 pt = pimpl->_ref_point + pimpl->_min*pimpl->_dir; - x = pt.x(); - y = pt.y(); - return true; -} - -CGAL_INLINE_FUNCTION -bool do_intersect_ray_2( - const Bbox_2 &box, double x, double y, double dx, double dy) -{ - Bbox_2_Ray_2_pair pair(box, x, y, dx, dy); - return pair.intersection_type() != Bbox_2_Ray_2_pair::NO_INTERSECTION; -} - -} //namespace CGAL diff --git a/Intersections_2/include/CGAL/intersection_2.h b/Intersections_2/include/CGAL/intersection_2.h index d1672662b5b..188bdd4e553 100644 --- a/Intersections_2/include/CGAL/intersection_2.h +++ b/Intersections_2/include/CGAL/intersection_2.h @@ -29,10 +29,12 @@ #define CGAL_INTERSECTION_2_H #include +#include #include +#include -#include #include +#include #include #include @@ -49,9 +51,9 @@ #include #include +#include #include #include -#include #include #include @@ -63,5 +65,4 @@ #include - #endif // CGAL_INTERSECTION_2_H diff --git a/Intersections_2/src/CGAL/Bbox_2_intersections.cpp b/Intersections_2/src/CGAL/Bbox_2_intersections.cpp deleted file mode 100644 index 3e0edcecc58..00000000000 --- a/Intersections_2/src/CGAL/Bbox_2_intersections.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2000 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Geert-Jan Giezeman - -#ifndef CGAL_HEADER_ONLY - -#include -#include - -#include -#include - -#endif // CGAL_HEADER_ONLY diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 963beac1f15..f501bf75211 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -1,21 +1,14 @@ // 2D intersection tests. #include +#include #include +#include +#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include +#include +#include +#include #include #include @@ -23,7 +16,8 @@ const double epsilon = 0.001; -struct randomint { +struct randomint +{ randomint() ; int get() const { return sequence[cur]; } int next() { cur = (cur+1)%11; return get();} @@ -55,9 +49,9 @@ inline double to_nt(int d) return double(d); } -template < typename K > -struct Test { - +template +struct Test +{ typedef typename K::Point_2 P; typedef typename K::Line_2 L; typedef typename K::Segment_2 S; @@ -65,86 +59,114 @@ struct Test { typedef typename K::Triangle_2 T; typedef typename K::Iso_rectangle_2 Rec; typedef typename K::Circle_2 C; - typedef std::vector

Pol; + typedef CGAL::Bbox_2 B; + typedef std::vector

Pol; - template < typename Type > + Test(const K& k = K()) : kernel(k) { } + + template bool approx_equal_nt(const Type &t1, const Type &t2) { - if (t1 == t2) - return true; - if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) - return true; - std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; - return false; + if (t1 == t2) + return true; + + if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) + return true; + + std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "" << std::endl; + return false; } - template < typename Type > + template bool approx_equal(const Type&t1, const Type&t2) { - return t1 == t2; - // we need approx equal to check approx kernels, but maybe we should only test with exact kernels - // (approx kernels were useful before, when the text output was checked by diff ?) - // idea : test containment with intervals ? or use some "epsilon double"? - // I need to convert the text output to exact rationals in the source... - // Well, for now the current scheme works. + return t1 == t2; + // we need approx equal to check approx kernels, but maybe we should only test with exact kernels + // (approx kernels were useful before, when the text output was checked by diff ?) + // idea : test containment with intervals ? or use some "epsilon double"? + // I need to convert the text output to exact rationals in the source... + // Well, for now the current scheme works. } bool approx_equal(const P & p, const P & q) { - return approx_equal_nt(p.x(), q.x()) && approx_equal_nt(p.y(), q.y()); + return approx_equal_nt(p.x(), q.x()) && approx_equal_nt(p.y(), q.y()); } bool approx_equal(const Pol & p, const Pol & q) { - if (p.size() != q.size()) - return false; - for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) - if (!approx_equal(*itp, *itq)) - return false; - return true; + if (p.size() != q.size()) + return false; + + for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) + if (!approx_equal(*itp, *itq)) + return false; + + return true; } - template < typename O1, typename O2> + template + void check_no_do_intersect(const O1& o1, const O2& o2) + { + assert(!CGAL::do_intersect(o1, o2)); + assert(!CGAL::do_intersect(o2, o1)); + + typename K::Do_intersect_2 do_2 = kernel.do_intersect_2_object(); + assert(!do_2(o1, o2)); + assert(!do_2(o2, o1)); + } + + template void check_no_intersection(const O1& o1, const O2& o2) { - assert(!CGAL::do_intersect(o1, o2)); - assert(!CGAL::do_intersect(o2, o1)); - assert(!CGAL::intersection(o2, o1)); - - //check with the functors - typename CGAL::Kernel_traits::Kernel::Do_intersect_2 do_2; - typename CGAL::Kernel_traits::Kernel::Intersect_2 i_2; - assert(!do_2(o1, o2)); - assert(!i_2(o1, o2)); - assert(!do_2(o2, o1)); - assert(!i_2(o2, o1)); + check_no_do_intersect(o1, o2); + + assert(!CGAL::intersection(o2, o1)); + + typename K::Intersect_2 i_2 = kernel.intersect_2_object(); + assert(!i_2(o1, o2)); + assert(!i_2(o2, o1)); } - template < typename Res, typename O1, typename O2 > + template + void check_do_intersect(const O1& o1, const O2& o2) + { + assert(CGAL::do_intersect(o1, o2)); + assert(CGAL::do_intersect(o2, o1)); + } + + template void check_intersection(const O1& o1, const O2& o2) { - Res tmp; - assert(CGAL::do_intersect(o1, o2)); - assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); - assert(CGAL::do_intersect(o2, o1)); - assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); + check_do_intersect(o1, o2); + + Res tmp; + assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); + assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); } - template < typename Res, typename O1, typename O2 > + template void check_intersection(const O1& o1, const O2& o2, const Res& result, bool do_opposite=true) { - Res tmp; - assert(CGAL::do_intersect(o1, o2)); - assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); - assert(approx_equal(tmp, result)); - if (do_opposite) { - assert(CGAL::do_intersect(o2, o1)); - assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); - assert(approx_equal(tmp, result)); - } + check_do_intersect(o1, o2); + + Res tmp; + + assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); + assert(approx_equal(tmp, result)); + if (do_opposite) + { + assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); + assert(approx_equal(tmp, result)); + } } + template + void check_intersection(const O& o) + { + return check_intersection(o, o, o); + } P p(int x, int y) { @@ -152,92 +174,323 @@ struct Test { return P(to_nt(x*w), to_nt(y*w), to_nt(w)); } + void B_C() + { + std::cout << "Bbox - Circle" << std::endl; + + // no intersection + check_no_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p( 8, 9), 3)); + check_no_do_intersect (p(8, 9).bbox() + p( 9, 10).bbox(), C(p( 9, 9), 9)); // circle containing the bbox + + // point intersection + check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p(-1, 0), 1)); + check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p( 1, 1), 1)); + + // generic intersection + check_do_intersect (p(0, 0).bbox() + p( 2, 3).bbox(), C(p(-1, 0), 2)); + check_do_intersect (p(0, 0).bbox() + p( 2, 0).bbox(), C(p( 1, 0), 1)); + check_do_intersect (p(0, 0).bbox() + p(10, 10).bbox(), C(p( 3, 2), 3)); + } + + void B_L() + { + std::cout << "Bbox - Line" << std::endl; + + // no intersection + check_no_do_intersect (p(0,0).bbox() , L(p( 1,1), p( 0,1))); + check_no_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1,1), p(-1,5))); + + // point intersection + check_do_intersect (p( 0, 0).bbox() , L(p(-1,1), p( 1,-1))); + check_do_intersect (p(-1,-1).bbox() + p(4,2).bbox(), L(p( 1,5), p(-3,-1))); + + // segment intersection + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1, 5), p(7,5))); + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p(-1, 5), p(2,5))); + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), L(p( 4,-3), p(4,1))); + } + void B_P() { - CGAL::Bbox_2 bb(0,0,10,10); - P p(1,0), bl(0,0), tr(10,10); - C c(bl,1); - Rec r(bl,tr); - check_intersection(bb,p,p,true); - check_intersection(c,p,p,true); - assert(do_intersect(r,c)); + std::cout << "Bbox - Point" << std::endl; + + // no intersection + check_no_intersection (p(1,2).bbox() + p(4,6).bbox(), p(8,9)); // point is outside the bbox + + // point intersection + check_intersection (p(1,2).bbox() , p(1,2), p(1,2)); // degenerate bbox (0d) + check_intersection (p(1,2).bbox() + p(4,2).bbox(), p(2,2), p(2,2)); // degenerate bbox (1d) + check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(1,6), p(1,6)); // point is a bbox corner + check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(3,6), p(3,6)); // point is on a bbox edge + check_intersection (p(1,2).bbox() + p(4,6).bbox(), p(3,3), p(3,3)); // point is within the bbox } - + + void B_R() + { + std::cout << "Bbox - Ray" << std::endl; + + // no intersection + check_no_do_intersect (p(0,0).bbox() , R(p( 1,1), p( 0,1))); + check_no_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1,1), p(-1,5))); + + // point intersection + check_do_intersect (p( 0, 0).bbox() , R(p(-1,1), p( 1,-1))); + check_do_intersect (p(-1,-1).bbox() + p(4,2).bbox(), R(p( 1,5), p(-3,-1))); + + // segment intersection + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1, 5), p(7,5))); + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p(-1, 5), p(2,5))); + check_do_intersect (p(0,0).bbox() + p(4,5).bbox(), R(p( 4,-3), p(4,1))); + } + + void C_C() + { + std::cout << "Circle - Circle" << std::endl; + + // no intersection + check_no_do_intersect (C(p(13, 14), 5), C(p( 3, 2), 1)); + check_no_do_intersect (C(p( 2, 3), 9), C(p( 3, 4), 1)); // one contains the other + + // point intersection + check_do_intersect (C(p(-1, -4), 0), C(p(-1, -4), 0)); + check_do_intersect (C(p( 3, 4), 25), C(p( 6, 8), 0)); + check_do_intersect (C(p( 3, 4), 1), C(p( 3, 2), 1)); + + // more than point intersection + check_do_intersect (C(p( 2, 5), 9), C(p(-3, 2), 9)); + check_do_intersect (C(p( 1, 2), 1), C(p( 1, 2), 1)); // same cicle twice + } + + void C_Rec() + { + std::cout << "Circle - Iso_rectangle" << std::endl; + + // no intersection + check_no_do_intersect (C(p( 2, 1), 0), Rec(p( 3, 2), p( 4, 6))); + check_no_do_intersect (C(p(13, 14), 5), Rec(p( 3, 2), p( 4, 6))); + check_no_do_intersect (C(p(13, 14), 9), Rec(p(12, 13), p(14, 15))); // circle contains the box + + // point intersection + check_do_intersect (C(p(-3, -2), 0), Rec(p(-3, -2), p(14, 2))); // vertex of the rectangle + check_do_intersect (C(p( 0, 0), 4), Rec(p( 0, 2), p(12, 9))); // vertex of the rectangle + check_do_intersect (C(p(-4, 3), 0), Rec(p(-6, 2), p( 7, 3))); // point on an edge + check_do_intersect (C(p( 0, 0), 4), Rec(p(-2, 2), p(13, 4))); // point on an edge + + // more than point intersection + check_do_intersect (C(p( 5, 5), 4), Rec(p( 3, 3), p( 7, 7))); + check_do_intersect (C(p(10, 10), 2), Rec(p( 0, 0), p(10, 10))); + check_do_intersect (C(p(13, 14), 3), Rec(p( 1, 1), p(30, 32))); // rectangle contains the circle + check_do_intersect (C(p( 0, 0), 25), Rec(p(-3, -4), p( 3, 4))); // inscribed circle of the box + + // intersection with all vertices outside of the circle + check_do_intersect (C(p( 0, 0), 9), Rec(p(-10, 2), p(10, 13))); + } + + void C_L() + { + std::cout << "Circle - Line" << std::endl; + + // no intersection + check_no_do_intersect (C(p( 2, 8), 6), L(p(-3, -2), p( 2, 4))); + check_no_do_intersect (C(p( 2, 8), 6), L(p(-3, 22), p( 2, 14))); + + // point intersection + check_do_intersect (C(p( 3, 4), 0), L(p(-3, 8), p( 6, 2))); + check_do_intersect (C(p( 4, 3), 4), L(p( 6, -7), p( 6, -2))); + check_do_intersect (C(p( 4, 3), 4), L(p( 6, -7), p( 6, -9))); + + // two points intersection + check_do_intersect (C(p(-3, 1), 7), L(p(-1, -3), p(-6, 7))); + } + + void C_P() + { + std::cout << "Circle - Point" << std::endl; + + // no intersection + check_no_intersection (C(p(13, 14), 5) , p(13, 14)); + check_no_intersection (C(p( 2, 9), 4) , p(11, 12)); + + // point intersection + check_intersection (C(p( 3, 4), 16) , p( 7, 4), p(7, 4)); + check_intersection (C(p( 0, 5), p(5, 0), p(-5, 0)), p( 0, -5), p(0, -5)); +// check_intersection (C(p( 3, 4), p(2, 6), p( 1, 5)), p( 1, 5), p(1, 5)); + check_intersection

(C(p( 0, 0), 25) , p( 5, 0)); + } + void L_L() { - std::cout << "Line - Line\n"; - check_intersection (L(p(0, 0), p(10, 0)), L(p(1,7), p(1,-2)), P(1,0)); - check_intersection (L(p(0,-1), p(10, 0)), L(p(2,1), p(8,-6)), P(3.42105,-0.657895)); - check_intersection (L(p(0, 0), p(10, 0)), L(p(1,0), p(8, 0))); - -check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); - check_intersection (L(p(0, 0), p(10, 0)), L(p(8,0), p(1, 0))); + std::cout << "Line - Line" << std::endl; + + // no intersection + check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); + + // point intersection + check_intersection (L(p(0, 0), p(10, 0)), L(p( 1, 7), p( 1, -2)), P(1,0)); + check_intersection (L(p(0,-1), p(10, 0)), L(p( 2, 1), p( 8, -6)), P(3.42105,-0.657895)); + check_intersection

(L(p(0, 0), p( 0, 4)), L(p(-1,-3), p(-10, -10))); + + // line intersection + check_intersection (L(p( 1, 1), p( 5, 5))); + check_intersection (L(p( 1, 1), p( 5, 5)), L(p(3, 3), p( 7, 7))); // ps0 < ps1 < pt0 < pt1 + check_intersection (L(p( 5, 5), p( 1, 1)), L(p(3, 3), p( 7, 7))); // L0 & L1 have opposite directions + check_intersection (L(p( 0, 0), p(10, 0)), L(p(0, 0), p(10, 0))); // ps0 == ps1 < pt0 == pt1 + check_intersection (L(p(10, 0), p( 0, 0)), L(p(0, 0), p(10, 0))); // ps1 == pt0 < ps0 == pt1 + check_intersection (L(p( 0, 0), p(10, 0)), L(p(1, 0), p( 8, 0))); // ps0 < ps1 < pt1 < pt0 + check_intersection (L(p( 0, 0), p(10, 0)), L(p(8, 0), p( 1, 0))); // L0 & L1 have opposite directions + } + + void L_P() + { + std::cout << "Line - Point" << std::endl; + + // no intersection + check_no_intersection (L(p(-3, 0), p( 7, 10)), p(9, 11)); + + // point intersection + check_intersection (L(p(-3, 0), p(-3, 10)), p(-3, 2), p(-3, 2)); + check_intersection (L(p(-3, 10), p(-3, 7)), p(-3, 4), p(-3, 4)); + check_intersection (L(p(-3, 4), p( 6, 4)), p( 7, 4), p( 7, 4)); + check_intersection (L(p(-3, 4), p(-6, 4)), p( 9, 4), p( 9, 4)); + check_intersection (L(p( 3, -1), p( 6, 1)), p(12, 5), p(12, 5)); } void S_S() { - std::cout << "Segment - Segment\n"; + std::cout << "Segment - Segment" << std::endl; + + // no intersection check_no_intersection (S(p(29, 16), p( 28, 9)), S(p( 30, 12), p( 29, 6))); + check_no_intersection (S(p( 0, 0), p(103567,9826)), S(p(10000,3782), p(76250,83736))); + + // point intersection + check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (S(p( 0, -1), p( 10, 0)), S(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); + check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 0, 0), p( 4, -7)), P(0, 0)); // meeting at an extremity + + // segment intersection + check_intersection (S(p( 0, 0), p( 10, 0))); + check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0))); check_intersection (S(p(68, 106), p(192, 106)), S(p(150, 106), p(255, 106)), S(P(150, 106), P(192, 106))); check_intersection (S(p( 1, 10), p( 1, 2)), S(p( 1, 7), p( 1, 3)), S(P( 1, 3), P( 1, 7))); - check_no_intersection (S(p( 0, 0), p(103567,9826)), S(p(10000,3782), p(76250,83736))); - check_intersection (S(p( 0, -1), p( 10, 0)), S(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); - check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 0), p( 8, 0)), S(P( 1, 0), P( 8, 0))); - check_intersection (S(p( 0, 0), p( 10, 0)), S(p( 1, 6), p( 1, -3)), P(1, 0)); } void R_R() { - std::cout << "Ray - Ray\n"; + std::cout << "Ray - Ray" << std::endl; + + // no intersection + check_no_intersection (R(p( 3, 4), p( 5, 7)), R(p( 2, 0), p( 2, 4))); + + // point intersection check_intersection (R(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3)); check_intersection (R(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 15, 0), p( 18, 30)), P(15, 0)); // R1's source on R0's path + check_intersection (R(p( 0, 0), p( 10, 0)), R(p( 0, 0), p( -3, 4)), P(0, 0)); // same source but different directions + + // segment intersection (same supporting line, different directions) + check_intersection (R(p( 2, 4), p( 6, 1)), R(p( 14, -5), p(10, -2))); + check_intersection (R(p( 2, 4), p( 10, -2)), R(p( 6, 1), p(-2, 7))); + + // ray intersection + check_intersection (R(p( 0, 0), p( 10, 0))); + check_intersection (R(p( 0, 0), p( 10, 0)), R(p( -1, 0), p(0, 0))); // R0 'runs' into R1's source } - void S_R() + void R_S() { - std::cout << "Segment - Ray\n"; + std::cout << "Ray - Segment" << std::endl; + + // no intersection check_no_intersection (S(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3))); + + // point intersection check_intersection (S(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 0, 0), p(-10, 4)), P(0, 0)); // start of ray is exactly on the segment + check_intersection (S(p( 0, 0), p( 10, 0)), R(p( 4, 0), p(-10, 4)), P(4, 0)); // start of ray is a segment extremity + + // segment intersection + check_intersection (S(p( 0, 0), p( 1, 0)), R(p( 0, 0), p( 10, 0)), S(P(0, 0), P(1,0))); + check_intersection (S(p( 3, 7), p( 2, 5)), R(p( 1, 3), p( 4, 9))); } void L_R() { - std::cout << "Line - Ray\n"; + std::cout << "Line - Ray" << std::endl; + + // no intersection + check_no_intersection (L(p( 2, -1), p( 2, 1)), R(p( 1, -3), p( 1, 3))); + + // point intersection check_intersection (L(p( 2, -1), p( 2, 1)), R(p( 1, 3), p( 2, 3)), P(2, 3)); check_intersection (L(p( 0, -1), p( 10, 0)), R(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (L(p( 0, 0), p( 10, 0)), R(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (L(p( 0, 0), p( 4, 5)), R(p( 1, 8), p( 7, 2)), P(4, 5)); // ray starts on the line + + // ray intersection + check_intersection (L(p( 2, -1), p( 2, 1)), R(p( 2, -3), p( 2, 3))); + check_intersection (L(p( 2, -1), p( 2, 1)), R(p( 2, 3), p( 2, -3))); // opposite direction } - void S_L() + void L_S() { - std::cout << "Segment - Line\n"; + std::cout << "Line - Segment" << std::endl; + + // no intersection check_no_intersection (S(p( 2, -1), p( 2, 1)), L(p( 1, 3), p( 2, 3))); + + // point intersection check_intersection (S(p( 0, -1), p( 10, 0)), L(p( 2, 1), p( 8, -6)), P(3.42105, -0.657895)); check_intersection (S(p( 0, 0), p( 10, 0)), L(p( 1, 6), p( 1, -3)), P(1, 0)); + check_intersection (S(p( 0, 0), p( 10, 0)), L(p( 1, 6), p( 2, 12)), P(0, 0)); + + // segment intersection + check_intersection (S(p(-3, 5), p( 12, 1)), L(p( 12, 1), p( 27, -3))); + check_intersection (S(p(-3, 5), p( 12, 1)), L(p(-18, 9), p( 27, -3))); + check_intersection (S(p(-3, 5), p( 12, 1)), L(p( 27, -3), p(-18, 9))); } void T_T() { - std::cout << "Triangle - Triangle\n"; + std::cout << "Triangle - Triangle" << std::endl; + + // no intersection + check_no_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 90, -10), p(100, 10), p(120, -5))); + + // point intersection + check_intersection (T(p( -10, 0), p( 10, 0), p(0, 3)), T(p( -12, 3), p( 12, 3), p(1, 5)), P(0, 3)); // intersection on an edge + check_intersection (T(p( -25, -4), p( 13, -18), p(0, 3)), T(p( -12, 5), p( 12, 5), p(0, 3)), P(0, 3)); // intersection at a vertex + + // segment intersection check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 12, 0), p(1, 5))); check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -8, 0), p( 8, 0), p(1, 5))); + check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -10, 0), p( 10, 0), p(1, 5))); + check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( 10, 0), p(-10, 0), p(1, 5))); + check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -10, 0), p( 10, 0), p(1, 5))); check_intersection (T(p( -10, 0), p( 10, 0), p(0, -3)), T(p( -12, 0), p( 12, 0), p(1, 5))); - check_intersection (T(p( -10, 0), p( 10, 0), p(0, 3)), T(p( -12, 3), p( 12, 3), p(1, 5)), P(0, 3)); + + // triangle intersection + check_intersection (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( -10, -10), p( 0, 10), p( 20, -5))); + check_intersection (T(p( -12, 1), p( 5, 3), p( -7, -15)), T(p( 29, -2), p( 0, -13), p(1, 21))); + + // polygon intersection Pol pol0; pol0.push_back(P(-6, -4)); pol0.push_back(P( -5.11111, -0.222222 )); pol0.push_back(P( 0, 10 )); pol0.push_back(P( 8, 4 )); check_intersection (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol0, false); - check_intersection (T(p( -12, 1), p( 5, 3), p( -7, -15)), T(p( 29, -2), p( 0, -13), p(1, 21))); + Pol pol1; pol1.push_back(P( 8, 4)); pol1.push_back(P( 0, 10 )); pol1.push_back(P( -5.11111, -0.222222 )); pol1.push_back(P(-6, -4)); check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol1, false); + Pol pol2; pol2.push_back(P( 10.2222, 2.33333 )); pol2.push_back(P( 1.96923, 8.52308 )); @@ -246,17 +499,24 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); pol2.push_back(P( -3.96178, -8.99363 )); pol2.push_back(P( 3.5, -7.75 )); check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( -9, 9), p( 14, 8), p(-2, -16)), pol2, false); - check_no_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 90, -10), p(100, 10), p(120, -5))); } void L_T() { - std::cout << "Line - Triangle\n"; + std::cout << "Line - Triangle" << std::endl; + + // no intersection + check_no_intersection (L(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); + + // point intersection + check_intersection

(L(p( -8, 30), p( 8, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2))); + check_intersection

(L(p( -8, 30), p( -7, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2))); + + // segment intersection check_intersection (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); check_intersection (L(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection (L(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection (L(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); - check_no_intersection (L(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); check_intersection (L(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection (L(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection (L(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); @@ -265,12 +525,22 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); void R_T() { - std::cout << "Ray - Triangle\n"; + std::cout << "Ray - Triangle" << std::endl; + + // no intersection + check_no_intersection (R(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); + + // point intersection + check_intersection

(R(p(-2, -16), p( 4, -20)), T(p( -9, 9), p( 14, 8), p(-2, -16))); + check_intersection

(R(p(-8, -1), p( -8, -12)), T(p( -12, 2), p( 10, 3), p(-4, -4))); + check_intersection

(R(p(-8, 30), p( 4, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2))); + check_intersection

(R(p(-8, 30), p( -7, 30)), T(p( 2, 30), p( 14, 2), p(-7, -2))); + + // segment intersection check_intersection (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); check_intersection (R(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection (R(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection (R(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); - check_no_intersection (R(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); check_intersection (R(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection (R(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection (R(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); @@ -279,13 +549,23 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); void S_T() { - std::cout << "Segment - Triangle\n"; - check_intersection (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); + std::cout << "Segment - Triangle" << std::endl; + + // no intersection check_no_intersection (S(p(-10, -10), p( 0, 10)), T(p( 90, -10), p( 100, 10), p(120, -5))); + check_no_intersection (S(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); + + // point intersection + check_intersection

(S(p(-2, -16), p( 4, -20)), T(p( -9, 9), p( 14, 8), p(-2, -16))); + check_intersection

(S(p(-8, -1), p( -8, -12)), T(p( -12, 2), p( 10, 3), p(-4, -4))); + check_intersection

(S(p(-8, -12), p( -8, -1)), T(p( -12, 2), p( 10, 3), p(-4, -4))); + check_intersection

(S(p(-8, 30), p( 1, 30)), T(p( -2, 30), p( 14, 2), p(-7, -2))); + + // segment intersection + check_intersection (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 10, 0), p(0, -4))); check_intersection (S(p( -1, -1), p( 0, -1)), T(p( -10, 0), p( 15, 2), p(0, -4))); check_intersection (S(p(-10, 0), p( 10, 0)), T(p( -8, 0), p( 8, 0), p(1, 5))); check_intersection (S(p(-10, 0), p( 10, 0)), T(p( -12, 0), p( 12, 0), p(1, 5))); - check_no_intersection (S(p(-10, 0), p( 10, 0)), T(p( -12, 3), p( 12, 3), p(1, 5))); check_intersection (S(p( 0, 10), p(-10, -10)), T(p( 2, 30), p( -6, -4), p(15, 8))); check_intersection (S(p(-12, 1), p( 5, 3)), T(p( 29, -2), p( 0, -13), p( 1, 21))); check_intersection (S(p(-10, -10), p( 0, 10)), T(p( 2, 30), p( -6, -4), p(15, 8))); @@ -294,85 +574,233 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); void P_P() { - std::cout << "Point - Point\n"; - check_no_intersection

(p( 8, 4), p(-4, 8)); - check_intersection

(p( 8, 4), p( 8, 4)); + std::cout << "Point - Point" << std::endl; + + check_no_intersection

(p(8, 4), p(-4, 8)); + check_intersection

(p(8, 4), p( 8, 4)); + } + + void P_R() + { + std::cout << "Point - Ray" << std::endl; + + // no intersection + check_no_intersection (R(p(-1, -1), p(0, 12)), p( 9, -1)); + + // point intersection + check_intersection (R(p(-3, 0), p(7, 10)), p(-3, 0), p(-3, 0)); // origin of the ray + check_intersection (R(p(-3, 0), p(7, 10)), p( 9, 12), p( 9, 12)); + } + + void P_S() + { + std::cout << "Point - Segment" << std::endl; + + // no intersection + check_no_intersection (S(p(-1, -1), p( 0, 12)), p( 9, -1)); + check_no_intersection (S(p(-2, -3), p( 0, 4)), p( 4, 18)); + + // point intersection + check_intersection (S(p(-2, -3), p( 4, 18)), p( 0, 4), p( 0, 4)); + check_intersection (S(p(-3, 0), p( 7, 10)), p(-3, 0), p(-3, 0)); + check_intersection (S(p( 3, 2), p(-2, 11)), p(-2, 11), p(-2, 11)); } void P_T() { - std::cout << "Point - Triangle\n"; + std::cout << "Point - Triangle" << std::endl; + + // no intersection + check_no_intersection (p( 8, 6), T(p( 4, 0), p( 12, 4), p(-4, 8))); + + // point intersection check_intersection

(p( 8, 4), T(p( 4, 0), p( 12, 4), p(-4, 8))); check_intersection

(p( 8, 5), T(p( 4, 0), p( 12, 4), p(-4, 8))); - check_no_intersection (p( 8, 6), T(p( 4, 0), p( 12, 4), p(-4, 8))); + check_intersection

(p( 4, 0), T(p( 4, 0), p( 12, 4), p(-4, 8))); + check_intersection

(p( 12, 4), T(p( 4, 0), p( 12, 4), p(-4, 8))); + check_intersection

(p( -4, 8), T(p( 4, 0), p( 12, 4), p(-4, 8))); } - void L_Rec() + void Rec_L() { - std::cout << "Line - Iso_rectangle\n"; - check_intersection (L(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + std::cout << "Iso_rectangle - Line" << std::endl; + + // no intersection + check_no_intersection (L(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3))); + + // point intersection + check_intersection (L(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1)); + check_intersection

(L(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14))); + + // segment intersection + check_intersection (L(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3))); + check_intersection (L(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3))); + check_intersection (L(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3))); + check_intersection (L(p( 6, 1), p( 6, 2)), Rec(p( 2, 0), p(6, 3))); + check_intersection (L(p(-1, 3), p(-2, 3)), Rec(p( 2, 0), p(6, 3))); } - void R_Rec() + void Rec_P() { - std::cout << "Ray - Iso_rectangle\n"; - check_intersection (R(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + std::cout << "Iso_rectangle - Point" << std::endl; + + // no intersection + check_no_intersection (Rec(p(-2, -6), p( 6, 3)), p( 7, 2)); + check_no_intersection (Rec(p(-2, -6), p( 6, 3)), p(-2, -7)); + + // point intersection + check_intersection (Rec(p(-1, 4), p(-1, 4)), p(-1, 4), p(-1, 4)); // degenerate rectange (0d) + check_intersection (Rec(p(-2, 4), p(-2, 7)), p(-2, 6), p(-2, 6)); // degenerate rectange (1d) + check_intersection (Rec(p(-2, 4), p(-2, 7)), p(-2, 7), p(-2, 7)); // degenerate rectange (1d) + check_intersection (Rec(p(-3, 0), p( 4, 2)), p(-3, 2), p(-3, 2)); // on vertex + check_intersection (Rec(p( 7, 8), p( 9, 9)), p( 8, 9), p( 8, 9)); // on edge + check_intersection (Rec(p(-2, 0), p( 6, 7)), p( 1, 1), p( 1, 1)); // within } - void S_Rec() + void Rec_R() { - std::cout << "Segment - Iso_rectangle\n"; - check_intersection (S(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + std::cout << "Iso_rectangle - Ray" << std::endl; + + // no intersection + check_no_intersection (R(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3))); + + // point intersection + check_intersection (R(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1)); + check_intersection (R(p( 0, 2), p(-4, 14)), Rec(p( 0, 0), p(5, 2)), P(0, 2)); + check_intersection

(R(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14))); + + // segment intersection + check_intersection (R(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3))); + check_intersection (R(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3))); + check_intersection (R(p( 2, 1), p( 2, 4)), Rec(p( 2, 0), p(6, 3))); + check_intersection (R(p(-2, 3), p(-1, 3)), Rec(p( 2, 0), p(6, 3))); + } + + void Rec_S() + { + std::cout << "Iso_rectangle - Segment" << std::endl; + + // no intersection + check_no_intersection (S(p( 18, 6), p( 16, 4)), Rec(p( 2, 0), p(6, 3))); + + // point intersection + check_intersection (S(p( -1, 0), p( 4, 5)), Rec(p( 0, 0), p(1, 1)), P(0, 1)); + check_intersection (S(p( 0, 2), p(-4, 14)), Rec(p( 0, 0), p(5, 2)), P(0, 2)); + check_intersection

(S(p( -5, 10), p(-1, -12)), Rec(p(-3, -1), p(2, 14))); + + // segment intersection + check_intersection (S(p( 18, 6), p( 0, 0)), Rec(p( 2, 0), p(6, 3))); + check_intersection (S(p( 2, 14), p( 2, -14)), Rec(p( 2, 0), p(6, 3))); + check_intersection (S(p( 6, 1), p( 6, 2)), Rec(p( 2, 0), p(6, 3))); + check_intersection (S(p(-2, 3), p( 6, 3)), Rec(p( 2, 0), p(6, 3))); } void Rec_Rec() { - std::cout << "Iso_rectangle - Iso_rectangle\n"; + std::cout << "Iso_rectangle - Iso_rectangle" << std::endl; + + // no intersection + check_no_intersection (Rec(p( -4, -12), p(12, 23)), Rec(p( -4, 24), p( 5, 26))); + check_no_intersection (Rec(p( -4, -12), p(12, 23)), Rec(p( 13, -24), p( 14, 15))); + + // point intersection + check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 30, 40), p( 31, 42))/*, p(30, 40)*/); + check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 30, -13), p( 33, 12))/*, p(30, 12)*/); + + // segment intersection + check_intersection (Rec(p( 3, 5), p(4, 6)), Rec(p( 2, 4), p( 6, 5))); + check_intersection (Rec(p( 3, 5), p(4, 6)), Rec(p( 1, 1), p( 3, 8))); + check_intersection (Rec(p( 3, 5), p(9, 9)), Rec(p( 1, 4), p( 3, 8))); + + // Iso rectangle intersection + check_intersection (Rec(p( 10, 12), p(30, 40))); check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 25, 40), p( 26, 103)), Rec(P(25, 40), P(26, 40))); } - void T_Rec() + void Rec_T() { - std::cout << "Triangle Iso_rectangle\n"; + std::cout << "Iso_rectangle - Triangle" << std::endl; + + // no intersection check_no_intersection (Rec(p( 10, 12), p(30, 40)), T(p( 4, 0), p( 12, 4), p(-4, 8))); - check_intersection(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( -1, 2), p(2, 2))); - check_intersection(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p(2, 2), p( -1, 2))); - check_intersection(Rec(p( 0, 0), p(1, 1)), T(p( -1, -2), p( -1, 2), p(5, 2))); - check_intersection(Rec(p( 0, 0), p(2, 2)), T(p( 0, 0), p( 1, 0), p(0, 1))); - check_intersection(Rec(p( 0, 0), p(3, 3)), T(p( 1, 1), p( 2, 1), p(1, 2))); - check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 0, 0), p(0, -1))); - check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( 0, 0), p( -1, 0), p(0, -1))); - check_intersection(Rec(p( 100, 100), p(200, 200)), T(p(150, 50), p(250, 170), p(50, 170))); - } - - void run() - { - std::cout << "2D Intersection tests\n"; - B_P(); - L_L(); - S_S(); - R_R(); - S_R(); - L_R(); - S_L(); - T_T(); - L_T(); - R_T(); - S_T(); - P_T(); - P_P(); - L_Rec(); - R_Rec(); - S_Rec(); - Rec_Rec(); - T_Rec(); + check_no_intersection (Rec(p( 2, 0), p( 3, 1)), T(p( 0, 3), p( 3, 3), p( 0, 0))); + + // point intersection + check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 0, 0), p( 0, -1))); // intersection at a vertex + check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( 0, 0), p( -1, 0), p( 0, -1))); // inversed triangle + check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 2, 3), p(-4, 6))); // intersection on an edge of the triangle + check_intersection (Rec(p( 0, 0), p(3, 3)), T(p( -10, 0), p( 0, 2), p(-1, 4)), p(0, 2)); // intersection on an edge of the iso rectangle + + // segment intersection + check_intersection (Rec(p( 0, 0), p(3, 3)), T(p( -10, 0), p( 0, 0), p( 0, 3))); + check_intersection (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -1, 3), p( 2, 3))); + check_intersection (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -4, 3), p( 2, 3))); + check_intersection (Rec(p(-2, 2), p(3, 3)), T(p( -15, 12), p( -4, 3), p( 15, 3))); + + // triangle intersection + check_intersection (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( -1, 2), p( 2, 2))); + check_intersection (Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 2, 2), p( -1, 2))); + check_intersection (Rec(p( 0, 0), p(2, 2)), T(p( 0, 0), p( 1, 0), p( 0, 1))); + check_intersection (Rec(p( 0, 0), p(3, 3)), T(p( 1, 1), p( 2, 1), p( 1, 2))); + + // polygon intersection + check_intersection(Rec(p( 0, 0), p( 1, 1)), T(p( -1, -2), p( -1, 2), p( 5, 2))); + check_intersection(Rec(p( 100, 100), p(200, 200)), T(p(150, 50), p(250, 170), p(50, 170))); } + void run() + { + std::cout << "2D Intersection tests with Kernel: " << typeid(K).name() << std::endl; + + B_C(); + B_L(); + B_P(); + B_R(); + + C_C(); + C_Rec(); + C_L(); + C_P(); + + Rec_Rec(); + Rec_L(); + Rec_P(); + Rec_R(); + Rec_S(); + Rec_T(); + + L_L(); + L_P(); + L_R(); + L_S(); + L_T(); + + P_P(); + P_R(); + P_S(); + P_T(); + + R_R(); + R_S(); + R_T(); + + S_S(); + S_T(); + + T_T(); + } + +private: + K kernel; }; int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Homogeneous >().run(); - // TODO : test more kernels. + CGAL::Set_ieee_double_precision pfr; + + Test< CGAL::Simple_cartesian::Type > >().run(); + Test< CGAL::Cartesian >().run(); + Test< CGAL::Homogeneous::Type > >().run(); + Test< CGAL::Exact_predicates_inexact_constructions_kernel >().run(); + Test< CGAL::Exact_predicates_exact_constructions_kernel >().run(); } diff --git a/Kernel_23/include/CGAL/Exact_predicates_inexact_constructions_kernel.h b/Kernel_23/include/CGAL/Exact_predicates_inexact_constructions_kernel.h index d30bcd7adca..0677d285d24 100644 --- a/Kernel_23/include/CGAL/Exact_predicates_inexact_constructions_kernel.h +++ b/Kernel_23/include/CGAL/Exact_predicates_inexact_constructions_kernel.h @@ -45,6 +45,12 @@ class Epick #endif {}; +class Epick_without_intervals + : public Static_filters_base< + Type_equality_wrapper< Simple_cartesian::Base::Type, + Epick_without_intervals > > +{}; + typedef Epick Exact_predicates_inexact_constructions_kernel; template <> diff --git a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp index 841aeb1fcd3..25a57e1965e 100644 --- a/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp +++ b/Kernel_23/test/Kernel_23/Filtered_cartesian.cpp @@ -27,6 +27,7 @@ #include #include +#include #include @@ -52,9 +53,12 @@ #include "CGAL/_test_mf_plane_3_to_2d.h" +template +void test(); int main() { + CGAL::force_ieee_double_precision(); typedef CGAL::Cartesian Clsdb; typedef CGAL::Filtered_kernel Clsd; @@ -71,6 +75,17 @@ main() std::cout << "Testing IO with F_k>:" << std::endl; _test_io( Clsd() ); + std::cout << "Testing with Epeck:\n"; + test(); + std::cout << "Testing with Epick:\n"; + test(); + std::cout << "Testing with Epick_without_intervals:\n"; + test(); + return 0; +} + +template +void test() { std::cout << "Testing 2d :"; std::cout << std::endl; _test_2( Cls() ); @@ -101,6 +116,4 @@ main() std::cout << "Testing 3d-2d :"; std::cout << std::endl; _test_mf_plane_3_to_2d( Cls() ); - - return 0; } diff --git a/Kernel_23/test/Kernel_23/Simple_cartesian.cpp b/Kernel_23/test/Kernel_23/Simple_cartesian.cpp index 10d2e4a2fd6..4058ddaa5b3 100644 --- a/Kernel_23/test/Kernel_23/Simple_cartesian.cpp +++ b/Kernel_23/test/Kernel_23/Simple_cartesian.cpp @@ -46,30 +46,26 @@ #include "CGAL/_test_mf_plane_3_to_2d.h" -int -main() -{ - typedef CGAL::Simple_cartesian Clsd; - std::cout << "Testing IO with Simple_cartesian :" << std::endl; - _test_io( Clsd() ); +#include - typedef CGAL::Simple_cartesian > Cls; - std::cout << "Testing 2d with Simple_cartesian> :"; +template +void test_kernel(std::string kernel_name, Cls) { + std::cout << "Testing 2d with "+kernel_name+" :"; std::cout << std::endl; _test_2( Cls() ); - std::cout << "Testing 3d with Simple_cartesian> :"; + std::cout << "Testing 3d with "+kernel_name+" :"; std::cout << std::endl; _test_3( Cls() ); - std::cout << "Testing new 2d with Simple_cartesian>:"; + std::cout << "Testing new 2d with "+kernel_name+" :"; std::cout << std::endl; test_new_2( Cls() ); - std::cout << "Testing new 3d with Simple_cartesian>:"; + std::cout << "Testing new 3d with "+kernel_name+" :"; std::cout << std::endl; test_new_3( Cls() ); - std::cout << "Testing new parts with Simple_cartesian> :"; + std::cout << "Testing new parts with "+kernel_name+" :"; std::cout << std::endl; _test_orientation_and_bounded_side( Cls() ); _test_fct_points_implicit_sphere( Cls() ); @@ -80,9 +76,19 @@ main() _test_cls_iso_cuboid_3( Cls() ); _test_angle( Cls() ); - std::cout << "Testing 3d-2d with Simple_cartesian>:"; + std::cout << "Testing 3d-2d with "+kernel_name+" :"; std::cout << std::endl; _test_mf_plane_3_to_2d( Cls() ); +} +int +main() +{ + typedef CGAL::Simple_cartesian Clsd; + std::cout << "Testing IO with Simple_cartesian :" << std::endl; + _test_io( Clsd() ); + + typedef CGAL::Simple_cartesian > Cls; + test_kernel("Simple_cartesian>", Cls()); return 0; } diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_approx_equal.h b/Kernel_23/test/Kernel_23/include/CGAL/_approx_equal.h new file mode 100644 index 00000000000..361d0800554 --- /dev/null +++ b/Kernel_23/test/Kernel_23/include/CGAL/_approx_equal.h @@ -0,0 +1,44 @@ +#ifndef CGAL_TESTSUITE_APPROX_EQUAL_H +#define CGAL_TESTSUITE_APPROX_EQUAL_H +#include + +namespace CGAL { +namespace testsuite { + +template +bool approx_equal(FT a, FT b) { return a == b; } + +bool approx_equal(double a, double b) { + return std::abs(boost::math::float_distance(a, b)) <= 1; +} + +struct Xyz_tag {}; +struct Xy_tag {}; + +template +bool approx_equal(Object a, Object b, CGAL::testsuite::Xyz_tag) +{ + return approx_equal(a.x(), b.x()) && + approx_equal(a.y(), b.y()) && + approx_equal(a.z(), b.z()); +} + +template +bool approx_equal(Object a, Object b, CGAL::testsuite::Xy_tag) +{ + return approx_equal(a.x(), b.x()) && approx_equal(a.y(), b.y()); +} + +struct Direction_2_tag {}; +template +bool approx_equal(Object a, Object b, CGAL::testsuite::Direction_2_tag) +{ + return CGAL_NTS sign(a.dx()) == CGAL_NTS sign(a.dx()) + && CGAL_NTS sign(a.dy()) == CGAL_NTS sign(b.dy()) + && approx_equal(a.dx() * b.dy(), a.dy() * b.dx()); +} + +} // end namespace testsuite +} // end namespace CGAL + +#endif // CGAL_TESTSUITE_APPROX_EQUAL_H diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_2.h index a4791a873aa..a17c5ee31ca 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_2.h @@ -24,6 +24,9 @@ #ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H #define CGAL__TEST_CLS_AFF_TRANSFORMATION_2_H +#include +#include + template bool _test_cls_aff_transformation_2(const R& ) @@ -33,6 +36,8 @@ _test_cls_aff_transformation_2(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; + const bool nonexact = boost::is_same::value; + typename R::Aff_transformation_2 ia; CGAL::Aff_transformation_2 a1(ia); @@ -56,7 +61,7 @@ _test_cls_aff_transformation_2(const R& ) CGAL::Vector_2 tvec; CGAL::Point_2 pnt( n8, n1, n10 ); // ( 6,-5) CGAL::Point_2 tpnt; - CGAL::Point_2 pvec = CGAL::ORIGIN + vec; + CGAL::Point_2 pvec = CGAL::ORIGIN + vec; CGAL_USE(pvec); CGAL::Vector_2 vpnt = pnt - CGAL::ORIGIN; CGAL::Point_2 p1(-n3, n7, n3 ); // (-1, 2) @@ -168,7 +173,7 @@ _test_cls_aff_transformation_2(const R& ) tisor= isor.transform( a[i]); assert( tseg == CGAL::Segment_2(tp1, tp2) ); assert( tray == CGAL::Ray_2(tp3, tp2) ); - assert( tlin == CGAL::Line_2(tp2, tp4) ); + assert( tlin == CGAL::Line_2(tp2, tp4) || nonexact); assert( ttri == CGAL::Triangle_2(tp2, tp3, tp4) ); assert( tisor== CGAL::Iso_rectangle_2( tp3, tp4 ) ); @@ -178,11 +183,11 @@ _test_cls_aff_transformation_2(const R& ) tray = tray.transform( inv ); tlin = tlin.transform( inv ); ttri = ttri.transform( inv ); - assert( tp4 == p4 ); - assert( tseg == seg ); - assert( tray == ray ); - assert( tlin == lin ); - assert( ttri == tri ); + assert( tp4 == p4 || nonexact ); + assert( tseg == seg || nonexact ); + assert( tray == ray || nonexact ); + assert( tlin == lin || nonexact ); + assert( ttri == tri || nonexact ); }; std::cout << '.'; @@ -291,7 +296,7 @@ _test_cls_aff_transformation_2(const R& ) // rotation assert( d0.transform( rot90 ) == d1 ); assert( d1.transform( rot90.inverse() ) == d0 ); - assert( d0.transform( rot3 ) == CGAL::Direction_2( RT(4), RT(3)) ); + assert( d0.transform( rot3 ) == CGAL::Direction_2( RT(4), RT(3)) || nonexact); co1 = rot3 * rot90; assert( d1.transform( rot3) == d0.transform( co1 ) ); co1 = rot2 * rot90; @@ -324,7 +329,7 @@ _test_cls_aff_transformation_2(const R& ) tp3 = p3.transform( rot3 ); tp4 = p4.transform( rot3 ); tcirc = circ.orthogonal_transform( rot3 ); - assert( tcirc == CGAL::Circle_2( tp2, tp3, tp4 ) ); + assert( tcirc == CGAL::Circle_2( tp2, tp3, tp4 ) || nonexact ); // copy diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_3.h index 35b0df744ca..466e6e2a638 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_aff_transformation_3.h @@ -24,6 +24,9 @@ #ifndef CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H #define CGAL__TEST_CLS_AFF_TRANSFORMATION_3_H +#include +#include + template bool _test_cls_aff_transformation_3(const R& ) @@ -32,6 +35,7 @@ _test_cls_aff_transformation_3(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; + const bool nonexact = boost::is_same::value; typename R::Aff_transformation_3 ia; CGAL::Aff_transformation_3 a1(ia); @@ -56,7 +60,7 @@ _test_cls_aff_transformation_3(const R& ) CGAL::Vector_3 tvec; CGAL::Point_3 pnt( n8, n1, n9, n10 ); // ( 6,-5, 3) CGAL::Point_3 tpnt; - CGAL::Point_3 pvec = CGAL::ORIGIN + vec; + CGAL::Point_3 pvec = CGAL::ORIGIN + vec; CGAL_USE(pvec); CGAL::Vector_3 vpnt = pnt - CGAL::ORIGIN; CGAL::Point_3 p1(-n3, n7, n11, n3 ); // (-1, 2,-3) @@ -182,7 +186,7 @@ _test_cls_aff_transformation_3(const R& ) tlin = lin.transform( a[i] ); ttri = tri.transform( a[i] ); ttet = tet.transform( a[i] ); - assert( tpla == CGAL::Plane_3( tp1, tp2, tp3) ); + assert( tpla == CGAL::Plane_3( tp1, tp2, tp3) || nonexact ); assert( tseg == CGAL::Segment_3(tp1, tp2) ); assert( tray == CGAL::Ray_3(tp3, tp2) ); assert( tlin == CGAL::Line_3(tp2, tp4) ); @@ -196,13 +200,13 @@ _test_cls_aff_transformation_3(const R& ) tlin = tlin.transform( inv ); ttri = ttri.transform( inv ); ttet = ttet.transform( inv ); - assert( tp4 == p4 ); - assert( tpla == pla ); - assert( tseg == seg ); - assert( tray == ray ); - assert( tlin == lin ); - assert( ttri == tri ); - assert( ttet == tet ); + assert( tp4 == p4 || nonexact ); + assert( tpla == pla || nonexact ); + assert( tseg == seg || nonexact ); + assert( tray == ray || nonexact ); + assert( tlin == lin || nonexact ); + assert( ttri == tri || nonexact ); + assert( ttet == tet || nonexact ); }; std::cout << '.'; @@ -211,7 +215,7 @@ _test_cls_aff_transformation_3(const R& ) assert( vec.transform(ident) == vec ); assert( dir.transform(ident) == dir ); assert( pnt.transform(ident) == pnt ); - assert( pla.transform(ident) == pla ); + assert( pla.transform(ident) == pla || nonexact ); // scale11 and gscale tpnt = pnt.transform(scale11); @@ -234,7 +238,7 @@ _test_cls_aff_transformation_3(const R& ) assert( vec.transform(scale11) == vec.transform(gscale) ); assert( dir.transform(scale11) == dir.transform(gscale) ); assert( pnt.transform(scale11) == pnt.transform(gscale) ); - assert( pla.transform(scale11) == pla.transform(gscale) ); + assert( pla.transform(scale11) == pla.transform(gscale) || nonexact ); // translate and gtrans tvec = vec.transform(translate); @@ -272,7 +276,7 @@ _test_cls_aff_transformation_3(const R& ) assert( pnt.transform(xrefl).transform(xrefl) == pnt ); assert( dir.transform(xrefl).transform(xrefl) == dir ); assert( vec.transform(xrefl).transform(xrefl) == vec ); - assert( pla.transform(xrefl).transform(xrefl) == pla ); + assert( pla.transform(xrefl).transform(xrefl) == pla || nonexact ); CGAL::Aff_transformation_3 co1 = xrefl * xrefl; assert( pnt.transform(xrefl).transform(xrefl) == pnt.transform(co1) ); assert( dir.transform(xrefl).transform(xrefl) == dir.transform(co1) ); @@ -282,7 +286,7 @@ _test_cls_aff_transformation_3(const R& ) assert( pnt.transform(gat3).transform(gat2) == pnt.transform(co1) ); assert( dir.transform(gat3).transform(gat2) == dir.transform(co1) ); assert( vec.transform(gat3).transform(gat2) == vec.transform(co1) ); - assert( pla.transform(gat3).transform(gat2) == pla.transform(co1) ); + assert( pla.transform(gat3).transform(gat2) == pla.transform(co1) || nonexact ); co1 = ident * gat1; assert( vec.transform(gat1) == vec.transform(co1) ); assert( dir.transform(gat1) == dir.transform(co1) ); @@ -294,10 +298,10 @@ _test_cls_aff_transformation_3(const R& ) assert( pnt.transform(gat1) == pnt.transform(co1) ); assert( pla.transform(gat1) == pla.transform(co1) ); co1 = gat1 * gat1.inverse() ; - assert( vec == vec.transform(co1) ); - assert( dir == dir.transform(co1) ); - assert( pnt == pnt.transform(co1) ); - assert( pla == pla.transform(co1) ); + assert( vec == vec.transform(co1) || nonexact ); + assert( dir == dir.transform(co1) || nonexact ); + assert( pnt == pnt.transform(co1) || nonexact ); + assert( pla == pla.transform(co1) || nonexact ); assert( vec.transform( gat5 ) == vec.transform( gat2 ) ); assert( dir.transform( gat5 ) == dir.transform( gat2 ) ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_2.h index c93726b81ed..6933bec5a4d 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_2.h @@ -27,6 +27,8 @@ #include #include +#include + template void _test_construct_radical_line(const K &k) { typedef typename K::FT FT; @@ -83,6 +85,8 @@ _test_cls_circle_2(const R& ) typename R::Circle_2 ic; CGAL::Circle_2 c0; + const bool nonexact = boost::is_same::value; + RT n0 = 0; RT n1 = 16; RT n2 = -4; @@ -194,9 +198,9 @@ _test_cls_circle_2(const R& ) == CGAL::ON_POSITIVE_SIDE ); assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \ == CGAL::ON_NEGATIVE_SIDE ); - assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY ); - assert( c10.has_on_boundary(p9) ); - assert( c10.has_on_boundary(p4 + v1) ); + assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY || nonexact); + assert( c10.has_on_boundary(p9) || nonexact); + assert( c10.has_on_boundary(p4 + v1) || nonexact ); CGAL::Point_2 p11( n4, n4, n3) ; // (2.5, 2.5) CGAL::Point_2 p12( n5, n5, n3) ; // ( 5 , 5 ) assert( c10.has_on_bounded_side( p11 ) ); @@ -206,8 +210,8 @@ _test_cls_circle_2(const R& ) assert( c10.has_on_negative_side( p12 ) ); assert( c10.opposite().has_on_negative_side( p11 ) ); assert( c10.opposite().has_on_positive_side( p12 ) ); - assert( c10.has_on_boundary( p6 ) ); - assert( c10.has_on_boundary( p8 ) ); + assert( c10.has_on_boundary( p6 ) || nonexact); + assert( c10.has_on_boundary( p8 ) || nonexact); std::cout << '.'; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_2.h index 07106cadb25..93800057c5c 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_2.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_DIRECTION_2_H #define CGAL__TEST_CLS_DIRECTION_2_H +#include + template bool _test_cls_direction_2(const R& ) @@ -34,7 +36,7 @@ _test_cls_direction_2(const R& ) typename R::Direction_2 id; CGAL::Direction_2 d0; - CGAL::Direction_2 d1(id); + CGAL::Direction_2 d1(id); CGAL_USE(d1); std::cout << '.'; RT n0 = 10; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_3.h index d25d0ad830d..afdb4cff38a 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_direction_3.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_DIRECTION_3_H #define CGAL__TEST_CLS_DIRECTION_3_H +#include + template bool _test_cls_direction_3(const R& ) @@ -35,7 +37,7 @@ _test_cls_direction_3(const R& ) typename R::Direction_3 id; CGAL::Direction_3 d0; - CGAL::Direction_3 d1(id); + CGAL::Direction_3 d1(id); CGAL_USE(d1); std::cout << '.'; RT n0 = 10; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_cuboid_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_cuboid_3.h index 0307fe1f38f..b4fa97c2f29 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_cuboid_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_cuboid_3.h @@ -26,6 +26,7 @@ #include #include +#include template bool @@ -36,9 +37,6 @@ _test_cls_iso_cuboid_3(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; - typename R::Iso_cuboid_3 ir; - CGAL::Iso_cuboid_3 r0(ir); - RT n1 = 1; RT n2 = 2; RT n3 = 3; @@ -65,6 +63,10 @@ _test_cls_iso_cuboid_3(const R& ) CGAL::Point_3 p12(n1, n1, n3 ); // ( 1, 1, 3) CGAL::Point_3 p13(n4, n1, n3 ); // ( 4, 1, 3) + typename R::Iso_cuboid_3 ir0; CGAL_USE(ir0); // test default-construction + typename R::Iso_cuboid_3 ir( p1, p3); + CGAL::Iso_cuboid_3 r0(ir); + const CGAL::Iso_cuboid_3 r1( p1, p3); CGAL::Iso_cuboid_3 r1_( p1, p3, 0); CGAL::Iso_cuboid_3 r2( p3, p1); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_rectangle_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_rectangle_2.h index c2411734ff9..1f488e830af 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_rectangle_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_iso_rectangle_2.h @@ -26,6 +26,7 @@ #include #include +#include template bool @@ -36,9 +37,6 @@ _test_cls_iso_rectangle_2(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; - typename R::Iso_rectangle_2 ir; - CGAL::Iso_rectangle_2 r0(ir); - RT n1 = 1; RT n2 = 2; RT n3 = 3; @@ -59,6 +57,10 @@ _test_cls_iso_rectangle_2(const R& ) CGAL::Point_2 p8( n4, n6, n2); // ( 2, 3) CGAL::Point_2 p9(-n3, n7); // (-3, 7) + typename R::Iso_rectangle_2 ir0; CGAL_USE(ir0); // test default-construction + typename R::Iso_rectangle_2 ir(p1, p3); + CGAL::Iso_rectangle_2 r0(ir); + const CGAL::Iso_rectangle_2 r1( p1, p3); CGAL::Iso_rectangle_2 r1_( p1, p3, 0); CGAL::Iso_rectangle_2 r2( p3, p1); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_2.h index 7c16868a588..f9895fb0270 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_2.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_LINE_2_H #define CGAL__TEST_CLS_LINE_2_H +#include + template bool _test_cls_line_2(const R& ) @@ -47,7 +49,8 @@ _test_cls_line_2(const R& ) CGAL::Point_2 p3(-n6, n6, n3 ); // (-2, 2 ) CGAL::Point_2 p4( n8, n4, n2 ); // ( 4, 2 ) - typename R::Line_2 il; + typename R::Line_2 il0; CGAL_USE(il0); // test default-construction + typename R::Line_2 il(p1, p2); CGAL::Line_2 l0(il); CGAL::Line_2 l12( p1, p2 ); CGAL::Line_2 l21( p2, p1 ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_3.h index af722474195..9c0509b17ab 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_line_3.h @@ -24,6 +24,9 @@ #ifndef CGAL__TEST_CLS_LINE_3_H #define CGAL__TEST_CLS_LINE_3_H +#include +#include + template bool _test_cls_line_3(const R& ) @@ -31,10 +34,11 @@ _test_cls_line_3(const R& ) std::cout << "Testing class Line_3" ; typedef typename R::RT RT; + const bool nonexact = boost::is_same::value; typename R::Line_3 il; - CGAL::Line_3 l0( il ); - CGAL::Line_3 l1; + CGAL::Line_3 l0( il ); CGAL_USE(l0); + CGAL::Line_3 l1; CGAL_USE(l1); RT n1 = 3; RT n2 = 53; @@ -99,20 +103,20 @@ _test_cls_line_3(const R& ) assert( l4.point(2) - l4.point(1) == l4.point(1) - l4.point(0) ); CGAL::Point_3 p1l4proj = l4.projection(p1); - assert( l4.has_on( p1l4proj ) ); - assert( l4.perpendicular_plane( p1l4proj ).has_on( p1l4proj ) ); - assert( l4.perpendicular_plane( p1l4proj ).has_on( p1 ) ); + assert( l4.has_on( p1l4proj ) || nonexact ); + assert( l4.perpendicular_plane( p1l4proj ).has_on( p1l4proj ) || nonexact ); + assert( l4.perpendicular_plane( p1l4proj ).has_on( p1 ) || nonexact ); CGAL::Point_3 p4 = l4.projection(p2); CGAL::Point_3 p5 = l4.projection(p3); assert( ( l4.direction() == ( p5 - p4 ).direction() )\ - ||( l4.direction() == ( p4 - p5 ).direction() ) ); + ||( l4.direction() == ( p4 - p5 ).direction() ) || nonexact ); assert( l5.direction() == - l6.direction() ); std::cout <<'.'; assert( l2.has_on(p1) ); assert( l2.has_on(p2) ); - assert( l4.has_on(p4) ); + assert( l4.has_on(p4) || nonexact ); assert( l4.has_on(p5) ); assert( CGAL::Line_3(p1,p1).is_degenerate() ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_plane_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_plane_3.h index a62e3a2a22d..bf423e8bf09 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_plane_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_plane_3.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_PLANE_3_H #define CGAL__TEST_CLS_PLANE_3_H +#include + template bool _test_cls_plane_3(const R& ) @@ -34,7 +36,7 @@ _test_cls_plane_3(const R& ) typedef typename R::FT FT; typename R::Plane_3 ip; - CGAL::Plane_3 pl0(ip); + CGAL::Plane_3 pl0(ip); CGAL_USE(pl0); RT x1 = -1; RT x2 = 4; @@ -45,7 +47,7 @@ _test_cls_plane_3(const R& ) py(RT(0),RT(1),RT(0)), pz(RT(0),RT(0),RT(1)); - CGAL::Point_3 p3(p1); + CGAL::Point_3 p3(p1); CGAL_USE(p3); CGAL::Direction_3 d1( RT(5), RT(-5), RT(10) ); CGAL::Vector_3 v1 = d1.vector(); @@ -121,8 +123,8 @@ _test_cls_plane_3(const R& ) assert( xy_pl.has_on( gnup ) ); CGAL::Vector_3 nov = pl1.orthogonal_vector(); - CGAL::Vector_3 vb1 = pl1.base1(); - CGAL::Vector_3 vb2 = pl1.base2(); + CGAL::Vector_3 vb1 = pl1.base1(); CGAL_USE(vb1); + CGAL::Vector_3 vb2 = pl1.base2(); CGAL_USE(vb2); assert( (nov*pl1.base1()) == FT(0)&&(nov*pl1.base2()) == FT(0) ); assert( (pl1.base2()*pl1.base1()) == FT(0) ); assert( pl1.has_on(pl1.point() + pl1.base1()) ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_2.h index 802b5482037..6a5a6d4d967 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_2.h @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -49,7 +50,7 @@ _test_cls_point_2(const R& ) typedef typename R::Point_2::Cartesian_const_iterator CCI; CGAL::Point_2 p1; - CGAL::Point_2 p2(ip); + CGAL::Point_2 p2(ip); CGAL_USE(p2); CGAL::Point_2 p0(CGAL::ORIGIN); RT n1(-35 ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_3.h index a54a062e8db..45b61412639 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_point_3.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ _test_cls_point_3(const R& ) typedef typename R::Point_3::Cartesian_const_iterator CCI; CGAL::Point_3 p1; - CGAL::Point_3 p2(ip); + CGAL::Point_3 p2(ip); CGAL_USE(p2); CGAL::Point_3 p0(CGAL::ORIGIN); RT n1(-35 ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_sphere_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_sphere_3.h index 69bac242dae..f3428f32226 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_sphere_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_sphere_3.h @@ -26,6 +26,7 @@ #include #include +#include template bool @@ -38,6 +39,7 @@ _test_cls_sphere_3(const R& ) typename R::Sphere_3 ic; CGAL::Sphere_3 c0; + const bool nonexact = boost::is_same::value; RT n0 = 0; RT n1 = 16; RT n2 = -4; @@ -104,8 +106,8 @@ _test_cls_sphere_3(const R& ) assert( cn3 == cp3.opposite() ); assert( c7.opposite() == c8 ); assert( c8.opposite() == c7 ); - assert( c1.opposite() == c3 ); - assert( c3.opposite() == c1 ); + assert( c1.opposite() == c3 || nonexact ); + assert( c3.opposite() == c1 || nonexact ); assert( c7.orientation() == CGAL::POSITIVE ); assert( c8.orientation() == CGAL::NEGATIVE ); assert( c5.orientation() == CGAL::POSITIVE ); @@ -181,22 +183,22 @@ _test_cls_sphere_3(const R& ) CGAL::Point_3 ori = CGAL::Point_3( RT(0), RT(0), RT(0)); CGAL::Point_3 p6 = p2.transform( rotate1 ); - assert( CGAL::compare_distance_to_point( ori, p2, p6) == CGAL::EQUAL ); + assert( CGAL::compare_distance_to_point( ori, p2, p6) == CGAL::EQUAL || nonexact ); CGAL::Point_3 p7 = p2.transform( rotate2 ); - assert( CGAL::compare_distance_to_point( ori, p2, p7) == CGAL::EQUAL ); + assert( CGAL::compare_distance_to_point( ori, p2, p7) == CGAL::EQUAL || nonexact ); CGAL::Point_3 p8 = p2.transform( rotate3 ); - assert( CGAL::compare_distance_to_point( ori, p2, p8) == CGAL::EQUAL ); + assert( CGAL::compare_distance_to_point( ori, p2, p8) == CGAL::EQUAL || nonexact ); CGAL::Point_3 p9 = p2.transform( rotate4 ); assert( CGAL::compare_distance_to_point( ori, p2, p9) == CGAL::EQUAL ); CGAL::Point_3 p10 = p2.transform( rotate5 ); - assert( CGAL::compare_distance_to_point( ori, p2, p10) == CGAL::EQUAL ); + assert( CGAL::compare_distance_to_point( ori, p2, p10) == CGAL::EQUAL || nonexact ); p6 = p6 + v1; p7 = p7 + v1; p8 = p8 + v1; p9 = p9 + v1; p10 = p10 + v1; CGAL::Sphere_3 c10 (p6, p8, p7, p9); - assert( c10.center() == ori + v1 ); + assert( c10.center() == ori + v1 || nonexact ); assert( c10.orientation() == CGAL::POSITIVE ); assert( c10.opposite().orientation() == CGAL::NEGATIVE ); @@ -205,9 +207,9 @@ _test_cls_sphere_3(const R& ) == CGAL::ON_POSITIVE_SIDE ); assert( c10.oriented_side(CGAL::ORIGIN + v1 + vx*n2 ) \ == CGAL::ON_NEGATIVE_SIDE ); - assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY ); - assert( c10.has_on_boundary(p9) ); - assert( c10.has_on_boundary(p4 + v1) ); + assert( c10.oriented_side(p9 ) == CGAL::ON_ORIENTED_BOUNDARY || nonexact ); + assert( c10.has_on_boundary(p9) || nonexact ); + assert( c10.has_on_boundary(p4 + v1) || nonexact ); CGAL::Point_3 p11( n4, n4, n4, n3) ; // (2.5, 2.5, 2.5) CGAL::Point_3 p12( n5, n5, n5, n3) ; // ( 5 , 5, 5 ) assert( c10.has_on_bounded_side( p11 ) ); @@ -217,8 +219,8 @@ _test_cls_sphere_3(const R& ) assert( c10.has_on_negative_side( p12 ) ); assert( c10.opposite().has_on_negative_side( p11 ) ); assert( c10.opposite().has_on_positive_side( p12 ) ); - assert( c10.has_on_boundary( p6 ) ); - assert( c10.has_on_boundary( p8 ) ); + assert( c10.has_on_boundary( p6 ) || nonexact ); + assert( c10.has_on_boundary( p8 ) || nonexact ); std::cout << '.'; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_2.h index 4c1a4c28655..06f9afd582a 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_triangle_2.h @@ -26,6 +26,7 @@ #include #include +#include template bool @@ -36,9 +37,6 @@ _test_cls_triangle_2(const R& ) typedef typename R::RT RT; typedef typename R::FT FT; - typename R::Triangle_2 it; - CGAL::Triangle_2 t0(it); - RT n0 = 0; RT n1 = 1; RT n2 = 2; @@ -62,6 +60,10 @@ _test_cls_triangle_2(const R& ) CGAL::Point_2 p8(-n12,-n8,-n2); // ( 6, 4) CGAL::Point_2 p9( n9, n9, n3); // ( 3, 3) + typename R::Triangle_2 it0; CGAL_USE(it0); // test default-construction + typename R::Triangle_2 it(p1, p2, p3); + CGAL::Triangle_2 t0(it); + CGAL::Triangle_2 t1( p1, p3, p5); CGAL::Triangle_2 t2( p3, p1, p5); CGAL::Triangle_2 t3( p7, p8, p9); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_2.h index 0ea7a3f621f..8b4b1b5d6af 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_2.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_VECTOR_2_H #define CGAL__TEST_CLS_VECTOR_2_H +#include + template bool _test_cls_vector_2(const R& ) @@ -37,7 +39,7 @@ _test_cls_vector_2(const R& ) typedef typename R::Vector_2::Cartesian_const_iterator CCI; CGAL::Vector_2 v1; - CGAL::Vector_2 v2(iv); + CGAL::Vector_2 v2(iv); CGAL_USE(v2); CGAL::Vector_2 v0(CGAL::NULL_VECTOR); RT n1( 12 ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_3.h index e2b35fab772..7477b855d28 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_vector_3.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_CLS_VECTOR_3_H #define CGAL__TEST_CLS_VECTOR_3_H +#include + template bool _test_cls_vector_3(const R& ) @@ -37,7 +39,7 @@ _test_cls_vector_3(const R& ) typedef typename R::Vector_3::Cartesian_const_iterator CCI; CGAL::Vector_3 v1; - CGAL::Vector_3 v2(iv); + CGAL::Vector_3 v2(iv); CGAL_USE(v2); CGAL::Vector_3 v0(CGAL::NULL_VECTOR); RT n1( 12 ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_points_implicit_sphere.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_points_implicit_sphere.h index abf69f2fe5b..97cf0c43e41 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_points_implicit_sphere.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_points_implicit_sphere.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H #define CGAL__TEST_FCT_POINTS_IMPLICIT_SPHERE_H +#include + template bool _test_fct_points_implicit_sphere(const R&) @@ -32,6 +34,8 @@ _test_fct_points_implicit_sphere(const R&) typedef typename R::FT FT; typedef CGAL::Tetrahedron_3 Tetrahedron; + const bool nonexact = boost::is_same::value; + const RT RT0(0); const RT RT4(4); const FT FT1(1); @@ -70,7 +74,7 @@ _test_fct_points_implicit_sphere(const R&) CGAL::Point_3 tpt = p.transform(rot_z); assert( CGAL::squared_distance( tpt, org ) == FT1 ); p = tpt.transform(rot_z); - assert( CGAL::squared_distance( p, org ) == FT1 ); + assert( CGAL::squared_distance( p, org ) == FT1 || nonexact ); CGAL::rational_rotation_approximation( RT(35), RT(-8), sin, cos, den, @@ -82,9 +86,9 @@ _test_fct_points_implicit_sphere(const R&) assert( CGAL::squared_distance( q, org ) == FT1 ); tpt = q.transform(rot_x); - assert( CGAL::squared_distance( tpt, org ) == FT1 ); + assert( CGAL::squared_distance( tpt, org ) == FT1 || nonexact ); q = tpt.transform(rot_y); - assert( CGAL::squared_distance( q, org ) == FT1 ); + assert( CGAL::squared_distance( q, org ) == FT1 || nonexact ); CGAL::rational_rotation_approximation( RT(9), RT(-8), sin, cos, den, @@ -98,7 +102,7 @@ _test_fct_points_implicit_sphere(const R&) tpt = r.transform(rot_z); assert( CGAL::squared_distance( tpt, org ) == FT1 ); r = tpt.transform(rot_y); - assert( CGAL::squared_distance( r, org ) == FT1 ); + assert( CGAL::squared_distance( r, org ) == FT1 || nonexact ); CGAL::rational_rotation_approximation( RT(-19), RT(-1), sin, cos, den, @@ -137,11 +141,11 @@ _test_fct_points_implicit_sphere(const R&) CGAL::Point_3 ez( RT0, RT0, RT1); CGAL::Point_3 oz( RT0, RT0, -RT1); assert( CGAL::circumcenter(ex, ey, ez, oz) == org ); - assert( CGAL::circumcenter(p,q,r,s) == org ); - assert( CGAL::circumcenter(p,r,q,s) == org ); + assert( CGAL::circumcenter(p,q,r,s) == org || nonexact ); + assert( CGAL::circumcenter(p,r,q,s) == org || nonexact ); assert( CGAL::circumcenter(Tetrahedron(ex, ey, ez, oz)) == org ); - assert( CGAL::circumcenter(Tetrahedron(p,q,r,s)) == org ); - assert( CGAL::circumcenter(Tetrahedron(p,r,q,s)) == org ); + assert( CGAL::circumcenter(Tetrahedron(p,q,r,s)) == org || nonexact ); + assert( CGAL::circumcenter(Tetrahedron(p,r,q,s)) == org || nonexact ); CGAL::Vector_3 v( RT(12), RT(4), RT(-4), RT(2) ); CGAL::Point_3 pt = p + v; @@ -169,10 +173,10 @@ _test_fct_points_implicit_sphere(const R&) assert( CGAL::side_of_bounded_sphere(pt,rt,qt,st,ot) \ == CGAL::ON_UNBOUNDED_SIDE); - assert( CGAL::circumcenter(pt,qt,rt,st) == c ); - assert( CGAL::circumcenter(pt,rt,qt,st) == c ); - assert( CGAL::circumcenter(Tetrahedron(pt,qt,rt,st)) == c ); - assert( CGAL::circumcenter(Tetrahedron(pt,rt,qt,st)) == c ); + assert( CGAL::circumcenter(pt,qt,rt,st) == c || nonexact ); + assert( CGAL::circumcenter(pt,rt,qt,st) == c || nonexact ); + assert( CGAL::circumcenter(Tetrahedron(pt,qt,rt,st)) == c || nonexact ); + assert( CGAL::circumcenter(Tetrahedron(pt,rt,qt,st)) == c || nonexact ); // Now test side_of_bounded_sphere(p, q, t). diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_2.h index dbe58ed1121..a0ffb40e8be 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_2.h @@ -31,6 +31,8 @@ #include #include +#include "_approx_equal.h" + template bool _test_fct_weighted_point_2(const R& ) @@ -158,8 +160,9 @@ _test_fct_weighted_point_2(const R& ) std::cout << CGAL::weighted_circumcenter(wp_00, wp_10, wp_01) << std::endl; - assert( CGAL::squared_radius_smallest_orthogonal_circle(wp1, wp3, wp5) - == CGAL::squared_radius(p1, p3, p5)); + using CGAL::testsuite::approx_equal; + assert( approx_equal(CGAL::squared_radius_smallest_orthogonal_circle(wp1, wp3, wp5), + CGAL::squared_radius(p1, p3, p5)) ); assert( CGAL::squared_radius_smallest_orthogonal_circle(wp_00, wp_10, wp_01) == RT(0)); std::cout << "done" << std::endl; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_3.h index 11d455778db..b860bc86c3d 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_weighted_point_3.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ _test_fct_weighted_point_3(const R& ) std::cout << "Testing functions Weighted_point_3" ; typedef typename R::RT RT; + const bool nonexact = boost::is_same::value; CGAL::Point_3 p1(RT(18), RT(15), RT(-21), RT(3) ); // 6, 5, -7 CGAL::Point_3 p2(RT(18), RT(15), RT( 12), RT(3) ); // 6, 5, 4 @@ -138,7 +140,7 @@ _test_fct_weighted_point_3(const R& ) assert( CGAL::power_side_of_bounded_power_sphere(wp3_b, wp1_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE ); assert( CGAL::power_side_of_bounded_power_sphere(wp1_b, wp3_b, wp6b_b) == CGAL::ON_BOUNDED_SIDE ); - assert( CGAL::coplanar(p4, p5, p6, p7) ); + assert( CGAL::coplanar(p4, p5, p6, p7) || nonexact ); assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp7) == CGAL::side_of_bounded_sphere(p4, p5, p6, p7) ); assert( CGAL::power_side_of_bounded_power_sphere(wp4, wp5, wp6, wp5) @@ -171,11 +173,11 @@ _test_fct_weighted_point_3(const R& ) assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1_b, wp3_b) == RT(164)); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp5) - == CGAL::squared_radius(p1, p3, p5)); + == CGAL::squared_radius(p1, p3, p5) || nonexact); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010) == RT(0)); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp1, wp3, wp4, wp5) - == CGAL::squared_radius(p1, p3, p4, p5)); + == CGAL::squared_radius(p1, p3, p4, p5) || nonexact); assert( CGAL::squared_radius_smallest_orthogonal_sphere(wp000, wp100, wp010, wp001) == RT(0)); std::cout << "."; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_further_fct_point_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_further_fct_point_2.h index f17c9028deb..828b0493d0e 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_further_fct_point_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_further_fct_point_2.h @@ -24,6 +24,9 @@ #ifndef CGAL__TEST_FURTHER_FCT_POINT_2_H #define CGAL__TEST_FURTHER_FCT_POINT_2_H +#include "_approx_equal.h" +#include + template bool _test_further_fct_point_2(const R& ) @@ -95,23 +98,27 @@ _test_further_fct_point_2(const R& ) p4 = p0.transform(rotate4); p5 = p0.transform(rotate5); + using CGAL::testsuite::approx_equal; + using CGAL::testsuite::Direction_2_tag; - assert( (p5 - CGAL::ORIGIN).direction() == dir5 ); + const bool nonexact = boost::is_same::value; + + assert( approx_equal((p5 - CGAL::ORIGIN).direction(), dir5, Direction_2_tag()) ); assert( CGAL::side_of_bounded_circle(p1, p2, p3, CGAL::Point_2(CGAL::ORIGIN))\ == CGAL::ON_BOUNDED_SIDE ); assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN + v) \ == CGAL::ON_BOUNDED_SIDE ); assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, CGAL::ORIGIN - v) \ - == CGAL::ON_UNBOUNDED_SIDE ); + == CGAL::ON_UNBOUNDED_SIDE || nonexact); assert( CGAL::side_of_bounded_circle(p1, p2, p3, p4) \ - == CGAL::ON_BOUNDARY ); + == CGAL::ON_BOUNDARY || nonexact); assert( CGAL::side_of_bounded_circle(p1+v, p2+v, p3+v, p4+v) \ - == CGAL::ON_BOUNDARY ); + == CGAL::ON_BOUNDARY || nonexact); assert( CGAL::side_of_bounded_circle(p1+v, p3+v, p4+v, p2+v) \ - == CGAL::ON_BOUNDARY ); + == CGAL::ON_BOUNDARY || nonexact); assert( CGAL::side_of_bounded_circle(p2+v, p4+v, p1+v, p3+v) \ - == CGAL::ON_BOUNDARY ); + == CGAL::ON_BOUNDARY || nonexact); assert( CGAL::orientation( p1, p2, p3 ) == CGAL::POSITIVE ); @@ -126,11 +133,11 @@ _test_further_fct_point_2(const R& ) assert( CGAL::side_of_oriented_circle(p2+v, p1+v, p3+v, CGAL::ORIGIN - v) \ == CGAL::ON_POSITIVE_SIDE ); assert( CGAL::side_of_oriented_circle(p1, p2, p3, p4) \ - == CGAL::ON_ORIENTED_BOUNDARY ); + == CGAL::ON_ORIENTED_BOUNDARY || nonexact); assert( CGAL::side_of_oriented_circle(p1+v, p2+v, p3+v, p4+v) \ - == CGAL::ON_ORIENTED_BOUNDARY ); + == CGAL::ON_ORIENTED_BOUNDARY || nonexact); assert( CGAL::side_of_oriented_circle(p1+v, p3+v, p4+v, p2+v) \ - == CGAL::ON_ORIENTED_BOUNDARY ); + == CGAL::ON_ORIENTED_BOUNDARY || nonexact); CGAL::Point_2 p10( RT(100), RT(100), RT(10) ); CGAL::Point_2 p11( RT(-100), RT(-100), RT(10) ); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_mf_plane_3_to_2d.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_mf_plane_3_to_2d.h index 48348c0e2c6..d86c33d2e2f 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_mf_plane_3_to_2d.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_mf_plane_3_to_2d.h @@ -24,6 +24,8 @@ #ifndef CGAL__TEST_MF_PLANE_3_TO_2D_H #define CGAL__TEST_MF_PLANE_3_TO_2D_H +#include + template bool _test_mf_plane_3_to_2d(const R& ) @@ -35,6 +37,8 @@ _test_mf_plane_3_to_2d(const R& ) typedef CGAL::Point_3< R> Point_3; typedef CGAL::Point_2< R> Point_2; + const bool nonexact = boost::is_same::value; + RT n0 = 0; RT n1 = 7; RT n2 = 21; @@ -51,33 +55,33 @@ _test_mf_plane_3_to_2d(const R& ) Point_3 p4 = p3 + (p2 - p1); Plane_3 pl1( p1, p2, p3); - assert( pl1.has_on( pl1.to_3d( pl1.to_2d( pl1.point() ))) ); - assert( pl1.has_on( pl1.to_3d( pl1.to_2d( p4 ))) ); - assert( p1 == pl1.to_3d( pl1.to_2d( p1)) ); - assert( p2 == pl1.to_3d( pl1.to_2d( p2)) ); - assert( p3 == pl1.to_3d( pl1.to_2d( p3)) ); - assert( p4 == pl1.to_3d( pl1.to_2d( p4)) ); + assert( pl1.has_on( pl1.to_3d( pl1.to_2d( pl1.point() ))) || nonexact ); + assert( pl1.has_on( pl1.to_3d( pl1.to_2d( p4 ))) || nonexact ); + assert( p1 == pl1.to_3d( pl1.to_2d( p1)) || nonexact ); + assert( p2 == pl1.to_3d( pl1.to_2d( p2)) || nonexact ); + assert( p3 == pl1.to_3d( pl1.to_2d( p3)) || nonexact ); + assert( p4 == pl1.to_3d( pl1.to_2d( p4)) || nonexact ); std::cout << '.'; Plane_3 pl2( p2, p1, p3); - assert( pl2.has_on( pl2.to_3d( pl2.to_2d( pl2.point() ))) ); - assert( pl2.has_on( pl2.to_3d( pl2.to_2d( p4 ))) ); - assert( p1 == pl2.to_3d( pl2.to_2d( p1)) ); - assert( p2 == pl2.to_3d( pl2.to_2d( p2)) ); - assert( p3 == pl2.to_3d( pl2.to_2d( p3)) ); - assert( p4 == pl2.to_3d( pl2.to_2d( p4)) ); + assert( pl2.has_on( pl2.to_3d( pl2.to_2d( pl2.point() ))) || nonexact ); + assert( pl2.has_on( pl2.to_3d( pl2.to_2d( p4 ))) || nonexact ); + assert( p1 == pl2.to_3d( pl2.to_2d( p1)) || nonexact ); + assert( p2 == pl2.to_3d( pl2.to_2d( p2)) || nonexact ); + assert( p3 == pl2.to_3d( pl2.to_2d( p3)) || nonexact ); + assert( p4 == pl2.to_3d( pl2.to_2d( p4)) || nonexact ); Point_3 p5( n2, n8, n0, n7); Point_3 p6( n4, n5, n0, n8); Plane_3 pl3( p4, p5, p6); - assert( p4 == pl3.to_3d( pl3.to_2d( p4)) ); + assert( p4 == pl3.to_3d( pl3.to_2d( p4)) || nonexact ); assert( p5 == pl3.to_3d( pl3.to_2d( p5)) ); - assert( p6 == pl3.to_3d( pl3.to_2d( p6)) ); + assert( p6 == pl3.to_3d( pl3.to_2d( p6)) || nonexact ); Plane_3 pl4( p4, p6, p5); - assert( p4 == pl4.to_3d( pl4.to_2d( p4)) ); + assert( p4 == pl4.to_3d( pl4.to_2d( p4)) || nonexact ); assert( p5 == pl4.to_3d( pl4.to_2d( p5)) ); - assert( p6 == pl4.to_3d( pl4.to_2d( p6)) ); + assert( p6 == pl4.to_3d( pl4.to_2d( p6)) || nonexact ); Point_3 p7 = CGAL::midpoint( p1, p2); Point_3 p8 = CGAL::midpoint( p3, p3 + (p2-p1) ); @@ -98,14 +102,14 @@ _test_mf_plane_3_to_2d(const R& ) CGAL::Segment_2 sp2( pp9, pp10); Point_2 pp; assert( CGAL::assign( pp, CGAL::intersection( sp1, sp2)) ); - assert( sp1.has_on( pp) ); - assert( sp2.has_on( pp) ); + assert( sp1.has_on( pp) || nonexact ); + assert( sp2.has_on( pp) || nonexact ); Point_3 p = pl1.to_3d( pp); - assert( pl1.has_on( p )); + assert( pl1.has_on( p ) || nonexact ); CGAL::Segment_3 s1( p7, p8); CGAL::Segment_3 s2( p9, p10); - assert( s1.has_on( p) ); - assert( s2.has_on( p) ); + assert( s1.has_on( p) || nonexact ); + assert( s2.has_on( p) || nonexact ); std::cout << '.' << std::endl; return true; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_2.h index ae3ae7fbbe8..59f0a94a19a 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_2.h @@ -35,7 +35,7 @@ #include "_test_cls_iso_rectangle_new_2.h" #include "_test_cls_circle_new_2.h" -#include +#include using CGAL::internal::use; @@ -175,8 +175,8 @@ test_new_2(const R& rep) typename R::Construct_triangle_2 construct_triangle = rep.construct_triangle_2_object(); - Triangle_2 t1; - Triangle_2 t2 = construct_triangle(p2,p3,p4); + Triangle_2 t0; CGAL_USE(t0); // test default-construction + Triangle_2 t2 = construct_triangle(p2,p3,p4), t1 = t2; typename R::Construct_iso_rectangle_2 construct_iso_rectangle = rep.construct_iso_rectangle_2_object(); @@ -379,6 +379,7 @@ test_new_2(const R& rep) typename R::Compute_power_product_2 compute_power_product = rep.compute_power_product_2_object(); tmp22d = compute_power_product(wp6, wp7); + CGAL_USE(tmp22d); typename R::Compute_squared_length_2 Compute_squared_length = rep.compute_squared_length_2_object(); @@ -672,7 +673,7 @@ test_new_2(const R& rep) use(tmp9); use(tmp10); use(tmp11); use(tmp12); use(tmp12a); use(tmp14); use(tmp14a); use(tmp15); use(tmp16); use(tmp16); use(tmp17); use(tmp19); use(tmp19a); use(tmp22a); - use(tmp22b); use(tmp22c); use(tmp23); + use(tmp22b); use(tmp22c); use(tmp22d); use(tmp23); use(tmp58); use(tmp57); use(tmp56); use(tmp55); use(tmp54); use(tmp53b); use(tmp53a); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h index c9493e57108..6b5939a9afa 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h @@ -29,7 +29,7 @@ #include #include -#include +#include using CGAL::internal::use; @@ -157,8 +157,8 @@ test_new_3(const R& rep) typename R::Construct_segment_3 construct_segment = rep.construct_segment_3_object(); - Segment_3 s1; - Segment_3 s2 = construct_segment(p2,p3); + Segment_3 s0; CGAL_USE(s0); // test default-construction + Segment_3 s2 = construct_segment(p2,p3), s1 = s2; typename R::Construct_ray_3 construct_ray = rep.construct_ray_3_object(); @@ -214,11 +214,10 @@ test_new_3(const R& rep) Sphere_3 sp8 = construct_sphere(p3); Sphere_3 sp9 = construct_sphere(p3,CLOCKWISE); - + Triangle_3 t0; CGAL_USE(t0); // test the default-construction typename R::Construct_triangle_3 construct_triangle = rep.construct_triangle_3_object(); - Triangle_3 t1; - Triangle_3 t2 = construct_triangle(p2,p3,p4); + Triangle_3 t1 = construct_triangle(p2,p3,p4), t2 = t1; typename R::Construct_tetrahedron_3 construct_tetrahedron = rep.construct_tetrahedron_3_object(); diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index 5c34e8b50fd..808a65014c9 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -216,7 +216,7 @@ public: stored_polyhedra.push_back(bounding_polyhedron); get(face_patch_id_t(), stored_polyhedra.back()); this->add_primitives(stored_polyhedra.back()); - if(bounding_polyhedron.empty()) { + if(CGAL::is_empty(bounding_polyhedron)) { this->set_surface_only(); } else { this->add_primitives_to_bounding_tree(stored_polyhedra.back()); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index 874556b3985..8ca1c6649b0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -1615,6 +1615,7 @@ void remove_unused_polylines( } } + std::vector vertices_kept; for(vertex_descriptor v : vertices_to_remove) { bool to_remove=true; @@ -1629,7 +1630,31 @@ void remove_unused_polylines( } if (to_remove) remove_vertex(v,tm); + else + vertices_kept.push_back(v); } + + // update next/prev pointers around vertices in vertices_kept + for(vertex_descriptor v: vertices_kept) + { + halfedge_descriptor h = halfedge(v, tm), start=GT::null_halfedge(); + + do{ + while ( !is_border(h, tm) || is_border(opposite(h, tm), tm) ) + h = opposite(next(h, tm), tm); + halfedge_descriptor in = h; + if (start==GT::null_halfedge()) + start=in; + else + if (start==in) + break; + while ( is_border(h, tm) ) + h = opposite(next(h, tm), tm); + set_next(in, opposite(h, tm), tm); + } + while(true);//this loop handles non-manifold vertices + } + for(edge_descriptor e : edges_to_remove) remove_edge(e,tm); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 0b7c0f79f57..804beed5389 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -89,33 +89,27 @@ public: bool applicable(QAction* a) const { if(a == actionSplitPolylines) { return qobject_cast - (scene->item(scene->mainSelectionIndex())) != 0; + (scene->item(scene->mainSelectionIndex())) != nullptr; } #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - if(qobject_cast(scene->item(scene->mainSelectionIndex())) != NULL - && a == actionMesh_3) + if(qobject_cast + (scene->item(scene->mainSelectionIndex())) != nullptr) { return true; + } #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - Q_FOREACH(int ind, scene->selectionIndices()){ - if( qobject_cast(scene->item(ind))) - return true; + if( qobject_cast + (scene->item(scene->mainSelectionIndex())) != nullptr ) { + return true; } -#endif - Q_FOREACH(int ind, scene->selectionIndices()){ +#endif + for(int ind: scene->selectionIndices()){ Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(ind)); - if(NULL == sm_item) - continue; - if (a == actionMesh_3) - { - if(sm_item) - return is_closed(*sm_item->polyhedron()); - } - else - return true; + if(nullptr == sm_item) + return false; } - return false; + return true; } public Q_SLOTS: @@ -138,6 +132,7 @@ private: Messages_interface* msg; QMessageBox* message_box_; Scene_item* source_item_; + QString source_item_name_; CGAL::Three::Scene_interface* scene; QMainWindow* mw; bool as_facegraph; @@ -182,66 +177,76 @@ void Mesh_3_plugin::mesh_3_volume() void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) { - Scene_surface_mesh_item* sm_item = NULL; - Scene_surface_mesh_item* bounding_sm_item = NULL; - Scene_implicit_function_item* function_item = NULL; - Scene_image_item* image_item = NULL; - Scene_polylines_item* polylines_item = NULL; + QList sm_items; + Scene_surface_mesh_item* bounding_sm_item = nullptr; + Scene_implicit_function_item* function_item = nullptr; + Scene_image_item* image_item = nullptr; + Scene_polylines_item* polylines_item = nullptr; - Q_FOREACH(int ind, scene->selectionIndices()) { - if(sm_item == NULL) - { - sm_item = qobject_cast(scene->item(ind)); - if (sm_item != NULL - && scene->selectionIndices().size() == 2 - && bounding_sm_item == NULL) - { - bounding_sm_item = qobject_cast( - scene->item(scene->selectionIndices().back())); - if (bounding_sm_item != NULL) - { - if (is_closed(*sm_item->polyhedron()) - && !is_closed(*bounding_sm_item->polyhedron())) - { - //todo : check sm_item is inside bounding_sm_item - std::swap(sm_item, bounding_sm_item); - //now bounding_sm_item is the bounding one - } - } + for(int ind: scene->selectionIndices()) { + Scene_surface_mesh_item* sm_item = + qobject_cast(scene->item(ind)); + if(sm_item) { + sm_items.push_back(sm_item); + if(is_closed(*sm_item->polyhedron())) { + bounding_sm_item = sm_item; } } #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - if(function_item == NULL){ - function_item = qobject_cast(scene->item(ind)); - } + else if(function_item == nullptr && + nullptr != + (function_item = qobject_cast(scene->item(ind)))) + {} #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - if(image_item == NULL){ - image_item = qobject_cast(scene->item(ind)); - } + else if(image_item == nullptr && + nullptr != (image_item = qobject_cast(scene->item(ind)))) + {} #endif - if(polylines_item == NULL){ - polylines_item = qobject_cast(scene->item(ind)); - } - } - Scene_item* item = NULL; - bool features_protection_available = false; - if(NULL != sm_item) - { - if (!is_triangle_mesh(*sm_item->polyhedron())) - { - QMessageBox::warning(mw, tr(""), - tr("Selected Scene_surface_mesh__item is not triangulated.")); + else if(polylines_item == nullptr && + nullptr != (polylines_item = qobject_cast(scene->item(ind)))) + {} + else { + QMessageBox::warning(mw, tr("Mesh_3 plugin"), + tr("Wrong selection of items")); return; } - item = sm_item; + } + Scene_item* item = nullptr; + const bool more_than_one_item = sm_items.size() > 1; + bool features_protection_available = false; + if(!sm_items.empty()) + { + for(auto sm_item : sm_items) { + if(nullptr == sm_item->polyhedron()) { + QApplication::restoreOverrideCursor(); + QMessageBox::critical(mw, tr("Mesh_3 plugin"), + tr("ERROR: no data in selected item %1").arg(sm_item->name())); + return; + } + if (!is_triangle_mesh(*sm_item->polyhedron())) + { + QApplication::restoreOverrideCursor(); + QMessageBox::warning(mw, tr("Mesh_3 plugin"), + tr("Selected Scene_surface_mesh_item %1 is not triangulated.") + .arg(sm_item->name())); + return; + } + if(sm_item->getNbIsolatedvertices() != 0) + { + QApplication::restoreOverrideCursor(); + QMessageBox::critical(mw, tr(""), tr("ERROR: there are isolated vertices in this mesh.")); + return; + } + } + item = sm_items.front(); features_protection_available = true; } #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - else if (NULL != function_item) { item = function_item; } + else if (nullptr != function_item) { item = function_item; } #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - else if (NULL != image_item) + else if (nullptr != image_item) { item = image_item; features_protection_available = true; @@ -275,7 +280,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) } #endif - if (NULL == item) + if (nullptr == item) { QMessageBox::warning(mw, tr(""), tr("Selected object can't be meshed")); @@ -336,9 +341,18 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) connect(ui.protect, SIGNAL(toggled(bool)), ui.protectEdges, SLOT(setEnabled(bool))); + QString item_name = more_than_one_item ? + QString("%1...").arg(item->name()) : + item->name(); + // Set default parameters CGAL::Three::Scene_interface::Bbox bbox = item->bbox(); - ui.objectName->setText(item->name()); + if(more_than_one_item) { + for(auto it: sm_items) { + bbox = bbox + it->bbox(); + } + } + ui.objectName->setText(item_name); ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") .arg(bbox.xmax() - bbox.xmin(),0,'g',3) .arg(bbox.ymax() - bbox.ymin(),0,'g',3) @@ -372,13 +386,13 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) ui.protectEdges->setEnabled(features_protection_available); ui.facegraphCheckBox->setVisible(surface_only); - ui.initializationGroup->setVisible(image_item != NULL && !image_item->isGray()); - ui.grayImgGroup->setVisible(image_item != NULL && image_item->isGray()); - if (sm_item != NULL) - ui.volumeGroup->setVisible(!surface_only && is_closed(*sm_item->polyhedron())); + ui.initializationGroup->setVisible(image_item != nullptr && !image_item->isGray()); + ui.grayImgGroup->setVisible(image_item != nullptr && image_item->isGray()); + if (!sm_items.empty()) + ui.volumeGroup->setVisible(!surface_only && nullptr != bounding_sm_item); else ui.volumeGroup->setVisible(!surface_only); - if ((sm_item == NULL)|| polylines_item != NULL) { + if ((!sm_items.empty())|| polylines_item != nullptr) { ui.sharpEdgesAngleLabel->setVisible(false); ui.sharpEdgesAngle->setVisible(false); @@ -394,7 +408,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) if (features_protection_available) { - if (NULL != sm_item) + if (!sm_items.empty()) { if (surface_only) { @@ -404,9 +418,9 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) else ui.protectEdges->addItem(QString("Sharp edges")); } - else if(NULL != image_item) + else if(nullptr != image_item) { - if(polylines_item != NULL) + if(polylines_item != nullptr) ui.protectEdges->addItem(QString("Input polylines")); else { @@ -444,30 +458,24 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); as_facegraph = surface_only ? ui.facegraphCheckBox->isChecked() : false; - Meshing_thread* thread = NULL; - if ( NULL != sm_item ) + Meshing_thread* thread = nullptr; + if (!sm_items.empty()) { - SMesh* pMesh = sm_item->polyhedron(); - if (NULL == pMesh) - { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); - return; - } - if(sm_item->getNbIsolatedvertices() != 0) - { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(mw, tr(""), tr("ERROR: there are isolated vertices in this mesh.")); - return; - } + QList polyhedrons; + sm_items.removeAll(bounding_sm_item); + std::transform(sm_items.begin(), sm_items.end(), + std::back_inserter(polyhedrons), + [](Scene_surface_mesh_item* item) { + return item->polyhedron(); + }); Scene_polylines_item::Polylines_container plc; - SMesh *pBMesh = (bounding_sm_item == NULL) ? NULL - : bounding_sm_item->polyhedron(); + SMesh *bounding_polyhedron = + (bounding_sm_item == nullptr) ? nullptr : bounding_sm_item->polyhedron(); - thread = cgal_code_mesh_3(pMesh, - (polylines_item == NULL)?plc:polylines_item->polylines, - pBMesh, - item->name(), + thread = cgal_code_mesh_3(polyhedrons, + (polylines_item == nullptr)?plc:polylines_item->polylines, + bounding_polyhedron, + item_name, angle, facet_sizing, approx, @@ -482,10 +490,10 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) } // Image #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - else if (NULL != function_item) + else if (nullptr != function_item) { const Implicit_function_interface* pFunction = function_item->function(); - if (NULL == pFunction) + if (nullptr == pFunction) { QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); return; @@ -503,10 +511,10 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) } #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - else if (NULL != image_item) + else if (nullptr != image_item) { const Image* pImage = image_item->image(); - if (NULL == pImage) + if (nullptr == pImage) { QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); return; @@ -515,7 +523,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) Scene_polylines_item::Polylines_container plc; thread = cgal_code_mesh_3(pImage, - (polylines_item == NULL)?plc:polylines_item->polylines, + (polylines_item == nullptr)?plc:polylines_item->polylines, angle, facet_sizing, approx, @@ -533,7 +541,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) } #endif - if ( NULL == thread ) + if ( nullptr == thread ) { QMessageBox::critical(mw,tr(""),tr("ERROR: no thread created")); return; @@ -541,6 +549,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) // Launch thread source_item_ = item; + source_item_name_ = item_name; launch_thread(thread); QApplication::restoreOverrideCursor(); @@ -592,7 +601,7 @@ void Mesh_3_plugin:: status_report(QString str) { - if ( NULL == message_box_ ) { return; } + if ( nullptr == message_box_ ) { return; } message_box_->setInformativeText(str); } @@ -604,7 +613,7 @@ meshing_done(Meshing_thread* thread) { // Print message in console QString str = QString("Meshing of \"%1\" done in %2s
") - .arg(source_item_->name()) + .arg(source_item_name_) .arg(thread->time()); Q_FOREACH( QString param, thread->parameters_log() ) @@ -629,7 +638,7 @@ meshing_done(Meshing_thread* thread) // close message box message_box_->done(0); - message_box_ = NULL; + message_box_ = nullptr; // free memory // TODO: maybe there is another way to do that @@ -644,7 +653,7 @@ treat_result(Scene_item& source_item, { if(!as_facegraph) { - result_item->setName(tr("%1 [3D Mesh]").arg(source_item.name())); + result_item->setName(tr("%1 [3D Mesh]").arg(source_item_name_)); result_item->c3t3_changed(); @@ -670,7 +679,7 @@ treat_result(Scene_item& source_item, { Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item; CGAL::facets_in_complex_3_to_triangle_mesh(result_item->c3t3(), *new_item->face_graph()); - new_item->setName(tr("%1 [Remeshed]").arg(source_item.name())); + new_item->setName(tr("%1 [Remeshed]").arg(source_item_name_)); Q_FOREACH(int ind, scene->selectionIndices()) { scene->item(ind)->setVisible(false); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index ba91f1a93b0..3425d41f357 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -31,15 +31,9 @@ struct Compare_to_isovalue { } }; -template -struct Polyhedral_mesh_domain_selector -{ - typedef Polyhedral_mesh_domain type; -}; -template -Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh, +Meshing_thread* cgal_code_mesh_3(QList pMeshes, const Polylines_container& polylines, - const Mesh* pBoundingMesh, + const SMesh* pBoundingMesh, QString filename, const double facet_angle, const double facet_sizing, @@ -53,43 +47,39 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh, const int manifold, const bool surface_only) { - if(!pMesh) return 0; + if(pMeshes.empty() && nullptr == pBoundingMesh) return 0; std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n"; std::cerr << " angle: " << facet_angle << std::endl << " edge size bound: " << edge_size << std::endl << " facets size bound: " << facet_sizing << std::endl << " approximation bound: " << facet_approx << std::endl; - if (is_closed(*pMesh)) + if (!surface_only) std::cerr << " tetrahedra size bound: " << tet_sizing << std::endl; std::cerr << "Build AABB tree..."; CGAL::Real_timer timer; timer.start(); - typedef typename Polyhedral_mesh_domain_selector::type Polyhedral_mesh_domain; // Create domain - Polyhedral_mesh_domain* p_domain = NULL; - if (!surface_only && is_closed(*pMesh)) - p_domain = new Polyhedral_mesh_domain(*pMesh); - else if (!surface_only && pBoundingMesh != NULL && is_closed(*pBoundingMesh)) - p_domain = new Polyhedral_mesh_domain(*pMesh, *pBoundingMesh); + Polyhedral_mesh_domain* p_domain = nullptr; + if (surface_only || nullptr == pBoundingMesh) + p_domain = new Polyhedral_mesh_domain(pMeshes.begin(), pMeshes.end()); + else if(pMeshes.empty()) + p_domain = new Polyhedral_mesh_domain(*pBoundingMesh); else - { - std::vector poly_ptrs_vector(1, pMesh); - p_domain = new Polyhedral_mesh_domain(poly_ptrs_vector.begin(), poly_ptrs_vector.end()); - } - + p_domain = new Polyhedral_mesh_domain(pMeshes.begin(), pMeshes.end(), + *pBoundingMesh); // Features - if(polylines.empty() && protect_features) { + if(polylines.empty()) { + if(protect_features) { //includes detection of borders in the surface case p_domain->detect_features(sharp_edges_angle); - } - else if (polylines.empty() && protect_borders) - { - p_domain->detect_borders(); - } - if(! polylines.empty()){ + } + else if (protect_borders) { + p_domain->detect_borders(); + } + } else { p_domain->add_features(polylines.begin(), polylines.end()); protect_features = true; // so that it will be passed in make_mesh_3 } @@ -109,7 +99,7 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh, .arg(edge_size) .arg(facet_sizing) .arg(facet_approx); - if (is_closed(*pMesh)) + if (!surface_only) tooltip += QString("

  • Tetrahedra size bound: %1
  • " ) .arg(tet_sizing); tooltip += ""; @@ -133,40 +123,6 @@ Meshing_thread* cgal_code_mesh_3_templated(const Mesh* pMesh, return new Meshing_thread(p_mesh_function, p_new_item); } - - -Meshing_thread* cgal_code_mesh_3(const SMesh* pMesh, - const Polylines_container& polylines, - const SMesh* pBoundingMesh, - QString filename, - const double facet_angle, - const double facet_sizing, - const double facet_approx, - const double tet_sizing, - const double edge_size, - const double tet_shape, - bool protect_features, - bool protect_borders, - const double sharp_edges_angle, - const int manifold, - const bool surface_only) -{ - return cgal_code_mesh_3_templated(pMesh, - polylines, - pBoundingMesh, - filename, - facet_angle, - facet_sizing, - facet_approx, - tet_sizing, - edge_size, - tet_shape, - protect_features, - protect_borders, - sharp_edges_angle, - manifold, - surface_only); -} #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, @@ -179,7 +135,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, const int manifold, const bool surface_only) { - if (pfunction == NULL) { return NULL; } + if (pfunction == nullptr) { return nullptr; } CGAL::Bbox_3 domain_bbox(pfunction->bbox().xmin(), pfunction->bbox().ymin(), @@ -238,7 +194,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, float value_outside, bool inside_is_less) { - if (NULL == pImage) { return NULL; } + if (nullptr == pImage) { return nullptr; } if(! polylines.empty()){ protect_features = true; // so that it will be passed in make_mesh_3 diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h index 6cae306aea5..22c5ab667f7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h @@ -8,6 +8,7 @@ #include "Meshing_thread.h" #include "Scene_surface_mesh_item.h" #include +#include class Scene_surface_mesh_item; @@ -19,7 +20,7 @@ namespace CGAL { namespace Three { typedef std::list > Polylines_container; -Meshing_thread* cgal_code_mesh_3(const SMesh* pMesh, +Meshing_thread* cgal_code_mesh_3(QList pMeshes, const Polylines_container& polylines, const SMesh* pBoundingMesh, QString filename, diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 0b9d97e8f7e..ebff326b116 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -306,9 +306,9 @@ public: if(!static_cast(CGAL::QGLViewer::QGLViewerPool().first())->isClipping()) return true; - double x = p.x(), y = p.y(), z = p.z(); + double x = p.x()+offset.x, y = p.y()+offset.y, z = p.z()+offset.z; - return !(clipbox[0][0]*x+clipbox[0][1]*y+clipbox[0][2]*z+clipbox[0][3]>0 || + return !(clipbox[0][0]*x+clipbox[0][1]*y+clipbox[0][2]*z+clipbox[0][3] >0 || clipbox[1][0]*x+clipbox[1][1]*y+clipbox[1][2]*z+clipbox[1][3]>0 || clipbox[2][0]*x+clipbox[2][1]*y+clipbox[2][2]*z+clipbox[2][3]>0 || clipbox[3][0]*x+clipbox[3][1]*y+clipbox[3][2]*z+clipbox[3][3]>0 || diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2.h index 6c5d6712a5e..6d3ce93ca0b 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -968,11 +969,11 @@ protected: std::map& vmap, List& l) const; - void expand_conflict_region_remove(const Face_handle& f, - const Site_2& t, - const Storage_site_2& ss, - List& l, Face_map& fm, - Sign_map& sign_map); + void expand_conflict_region_remove(const Face_handle& in_f, + const Site_2& t, + List& l, + Face_map& fm, + Sign_map& sign_map); void find_conflict_region_remove(const Vertex_handle& v, const Vertex_handle& vnearest, @@ -1448,16 +1449,22 @@ protected: std::pair find_faces_to_split(const Vertex_handle& v, const Site_2& t) const; - void expand_conflict_region(const Face_handle& f, const Site_2& t, - const Storage_site_2& ss, -#ifdef CGAL_SDG_NO_FACE_MAP - List& l, -#else - List& l, Face_map& fm, - std::map& sign_map, + bool check_unregistered_face(const Face_handle& n, + const Site_2& t, + List& l, +#ifndef CGAL_SDG_NO_FACE_MAP + Face_map& fm, #endif - Triple& vcross); + Triple& vcross); + + void expand_conflict_region(const Face_handle& in_f, + const Site_2& t, + List& l, +#ifndef CGAL_SDG_NO_FACE_MAP + Face_map& fm, + std::map& sign_map, +#endif + Triple& vcross); Vertex_handle add_bogus_vertex(Edge e, List& l); Vertex_list add_bogus_vertices(List& l); diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h index 099499c7f20..46e1d105273 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2_impl.h @@ -465,9 +465,9 @@ insert_point2(const Storage_site_2& ss, const Site_2& t, // REGION AND EXPANDS THE CONFLICT REGION. initialize_conflict_region(start_f, l); #ifdef CGAL_SDG_NO_FACE_MAP - expand_conflict_region(start_f, t, ss, l, vcross); + expand_conflict_region(start_f, t, l, vcross); #else - expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); + expand_conflict_region(start_f, t, l, fm, sign_map, vcross); #endif CGAL_assertion( !vcross.first ); @@ -846,9 +846,9 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss, // REGION AND EXPANDS THE CONFLICT REGION. initialize_conflict_region(start_f, l); #ifdef CGAL_SDG_NO_FACE_MAP - expand_conflict_region(start_f, t, ss, l, vcross); + expand_conflict_region(start_f, t, l, vcross); #else - expand_conflict_region(start_f, t, ss, l, fm, sign_map, vcross); + expand_conflict_region(start_f, t, l, fm, sign_map, vcross); #endif CGAL_assertion( vcross.third == AT2::DISJOINT || @@ -958,152 +958,190 @@ initialize_conflict_region(const Face_handle& f, List& l) template -void +bool Segment_Delaunay_graph_2:: -expand_conflict_region(const Face_handle& f, const Site_2& t, - const Storage_site_2& ss, -#ifdef CGAL_SDG_NO_FACE_MAP - List& l, -#else - List& l, Face_map& fm, - std::map& sign_map, +check_unregistered_face(const Face_handle& n, + const Site_2& t, + List& l, +#ifndef CGAL_SDG_NO_FACE_MAP + Face_map& fm, #endif - Triple& vcross) + Triple& vcross) { + for (int j = 0; j < 3; ++j) + { + Vertex_handle vf = n->vertex(j); + + if ( is_infinite(vf) ) + continue; + + Arrangement_type at_res = arrangement_type(t, vf); + + CGAL_assertion( vcross.third == AT2::DISJOINT || + vcross.third == AT2::CROSSING || + vcross.third == AT2::INTERIOR ); + + if ( vf->is_segment() ) + { + CGAL_assertion( at_res != AT2::IDENTICAL ); + CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 ); + CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 ); + + if ( at_res == AT2::CROSSING ) + { + vcross.first = true; + vcross.second = vf; + vcross.third = AT2::CROSSING; + l.clear(); #ifdef CGAL_SDG_NO_FACE_MAP - if ( f->tds_data().is_in_conflict() ) { return; } + fhc_.clear(); #else - if ( fm.find(f) != fm.end() ) { return; } + fm.clear(); #endif - - // this is done to stop the recursion when intersecting segments - // are found - if ( vcross.first ) { return; } - - // setting fm[f] to true means that the face has been reached and - // that the face is available for recycling. If we do not want the - // face to be available for recycling we must set this flag to - // false. -#ifdef CGAL_SDG_NO_FACE_MAP - f->tds_data().mark_in_conflict(); - fhc_.push_back(f); -#else - fm[f] = true; -#endif - - // CGAL_assertion( fm.find(f) != fm.end() ); - - for (int i = 0; i < 3; i++) { - Face_handle n = f->neighbor(i); - -#ifdef CGAL_SDG_NO_FACE_MAP - bool face_registered = n->tds_data().is_in_conflict(); -#else - bool face_registered = (fm.find(n) != fm.end()); -#endif - - if ( !face_registered ) { - for (int j = 0; j < 3; j++) { - Vertex_handle vf = n->vertex(j); - - if ( is_infinite(vf) ) { continue; } - - Arrangement_type at_res = arrangement_type(t, vf); - - CGAL_assertion( vcross.third == AT2::DISJOINT || - vcross.third == AT2::CROSSING || - vcross.third == AT2::INTERIOR ); - - if ( vf->is_segment() ) { - CGAL_assertion( at_res != AT2::IDENTICAL ); - CGAL_assertion( at_res != AT2::TOUCH_11_INTERIOR_1 ); - CGAL_assertion( at_res != AT2::TOUCH_12_INTERIOR_1 ); - - if ( at_res == AT2::CROSSING ) { - vcross.first = true; - vcross.second = vf; - vcross.third = AT2::CROSSING; - l.clear(); -#ifdef CGAL_SDG_NO_FACE_MAP - fhc_.clear(); -#else - fm.clear(); -#endif - return; - } else { - CGAL_assertion ( at_res == AT2::DISJOINT || - at_res == AT2::TOUCH_1 || - at_res == AT2::TOUCH_2 || - at_res == AT2::TOUCH_11 || - at_res == AT2::TOUCH_12 || - at_res == AT2::TOUCH_21 || - at_res == AT2::TOUCH_22 ); - // we do nothing in these cases - } - } else { - CGAL_assertion( vf->is_point() ); - if ( at_res == AT2::INTERIOR ) { - vcross.first = true; - vcross.second = vf; - vcross.third = AT2::INTERIOR; - l.clear(); -#ifdef CGAL_SDG_NO_FACE_MAP - fhc_.clear(); -#else - fm.clear(); -#endif - return; - } - } + return true; + } + else // at_res != AT2::CROSSING + { + CGAL_assertion ( at_res == AT2::DISJOINT || + at_res == AT2::TOUCH_1 || + at_res == AT2::TOUCH_2 || + at_res == AT2::TOUCH_11 || + at_res == AT2::TOUCH_12 || + at_res == AT2::TOUCH_21 || + at_res == AT2::TOUCH_22 ); + // we do nothing in these cases } } + else // ! vf->is_segment() + { + CGAL_assertion( vf->is_point() ); + if ( at_res == AT2::INTERIOR ) + { + vcross.first = true; + vcross.second = vf; + vcross.third = AT2::INTERIOR; + l.clear(); +#ifdef CGAL_SDG_NO_FACE_MAP + fhc_.clear(); +#else + fm.clear(); +#endif + return true; + } + } + } - Sign s = incircle(n, t); + return false; +} + +template +void +Segment_Delaunay_graph_2:: +expand_conflict_region(const Face_handle& in_f, + const Site_2& t, + List& l, +#ifndef CGAL_SDG_NO_FACE_MAP + Face_map& fm, + std::map& sign_map, +#endif + Triple& vcross) +{ + std::stack face_stack; + face_stack.push(in_f); + + while(!face_stack.empty()) + { + // Stop as soon as intersecting segments are found + if ( vcross.first ) + break; + + const Face_handle curr_f = face_stack.top(); + face_stack.pop(); #ifdef CGAL_SDG_NO_FACE_MAP - n->tds_data().set_incircle_sign(s); - - Sign s_f = f->tds_data().incircle_sign(); + if ( curr_f->tds_data().is_in_conflict() ) + continue; #else - sign_map[n] = s; - - Sign s_f = sign_map[f]; + if ( fm.find(curr_f) != fm.end() ) + continue; #endif - if ( s == POSITIVE ) { continue; } - if ( s != s_f ) { continue; } + // setting fm[f] to true means that the face has been reached and + // that the face is available for recycling. If we do not want the + // face to be available for recycling we must set this flag to false. +#ifdef CGAL_SDG_NO_FACE_MAP + curr_f->tds_data().mark_in_conflict(); + fhc_.push_back(curr_f); +#else + fm[curr_f] = true; +#endif - bool interior_in_conflict = edge_interior(f, i, t, s); +// CGAL_assertion( fm.find(curr_f) != fm.end() ); - if ( !interior_in_conflict ) { continue; } - - if ( face_registered ) { continue; } - - Edge e = sym_edge(f, i); - - CGAL_assertion( l.is_in_list(e) ); - int j = this->_tds.mirror_index(f, i); - Edge e_before = sym_edge(n, ccw(j)); - Edge e_after = sym_edge(n, cw(j)); - if ( !l.is_in_list(e_before) ) { - l.insert_before(e, e_before); - } - if ( !l.is_in_list(e_after) ) { - l.insert_after(e, e_after); - } - l.remove(e); + for (int i = 0; i < 3; ++i) + { + Face_handle n = curr_f->neighbor(i); #ifdef CGAL_SDG_NO_FACE_MAP - expand_conflict_region(n, t, ss, l, vcross); + bool face_registered = n->tds_data().is_in_conflict(); #else - expand_conflict_region(n, t, ss, l, fm, sign_map, vcross); + bool face_registered = (fm.find(n) != fm.end()); #endif - // this is done to stop the recursion when intersecting segments - // are found - // if ( fm.size() == 0 && l.size() == 0 ) { return; } - if ( vcross.first ) { return; } - } // for-loop + if ( !face_registered ) + { +#ifdef CGAL_SDG_NO_FACE_MAP + if(check_unregistered_face(n, t, l, vcross)) +#else + if(check_unregistered_face(n, t, l, fm, vcross)) +#endif + { + CGAL_assertion(vcross.first); + break; // intersecting segments were found + } + } + + Sign s = incircle(n, t); + +#ifdef CGAL_SDG_NO_FACE_MAP + n->tds_data().set_incircle_sign(s); + + Sign s_f = curr_f->tds_data().incircle_sign(); +#else + sign_map[n] = s; + + Sign s_f = sign_map[curr_f]; +#endif + + if ( s == POSITIVE ) + continue; + if ( s != s_f ) + continue; + if ( face_registered ) + continue; + + bool interior_in_conflict = edge_interior(curr_f, i, t, s); + if ( !interior_in_conflict ) + continue; + + Edge e = sym_edge(curr_f, i); + CGAL_assertion( l.is_in_list(e) ); + + int j = this->_tds.mirror_index(curr_f, i); + Edge e_before = sym_edge(n, ccw(j)); + Edge e_after = sym_edge(n, cw(j)); + + if ( !l.is_in_list(e_before) ) + l.insert_before(e, e_before); + + if ( !l.is_in_list(e_after) ) + l.insert_after(e, e_after); + + l.remove(e); + + face_stack.push(n); + } // neighbor for-loop + } } @@ -1563,56 +1601,72 @@ equalize_degrees(const Vertex_handle& v, Self& small_d, template void Segment_Delaunay_graph_2:: -expand_conflict_region_remove(const Face_handle& f, const Site_2& t, - const Storage_site_2& ss, - List& l, Face_map& fm, Sign_map& sign_map) +expand_conflict_region_remove(const Face_handle& in_f, + const Site_2& t, + List& l, + Face_map& fm, + Sign_map& sign_map) { - if ( fm.find(f) != fm.end() ) { return; } + std::stack face_stack; + face_stack.push(in_f); - // setting fm[f] to true means that the face has been reached and - // that the face is available for recycling. If we do not want the - // face to be available for recycling we must set this flag to - // false. - fm[f] = true; + while(!face_stack.empty()) + { + const Face_handle curr_f = face_stack.top(); + face_stack.pop(); - // CGAL_assertion( fm.find(f) != fm.end() ); + if ( fm.find(curr_f) != fm.end() ) + continue; - for (int i = 0; i < 3; i++) { - Face_handle n = f->neighbor(i); + // setting fm[curr_f] to true means that the face has been reached and + // that the face is available for recycling. If we do not want the + // face to be available for recycling we must set this flag to + // false. + fm[curr_f] = true; - bool face_registered = (fm.find(n) != fm.end()); + // CGAL_assertion( fm.find(f) != fm.end() ); - Sign s = incircle(n, t); + for (int i = 0; i < 3; ++i) + { + Face_handle n = curr_f->neighbor(i); - sign_map[n] = s; + bool face_registered = (fm.find(n) != fm.end()); - Sign s_f = sign_map[f]; + Sign s = incircle(n, t); - if ( s == POSITIVE ) { continue; } - if ( s != s_f ) { continue; } + sign_map[n] = s; - bool interior_in_conflict = edge_interior(f, i, t, s); + Sign s_f = sign_map[curr_f]; - if ( !interior_in_conflict ) { continue; } + if ( s == POSITIVE ) + continue; + if ( s != s_f ) + continue; + if ( face_registered ) + continue; - if ( face_registered ) { continue; } + bool interior_in_conflict = edge_interior(curr_f, i, t, s); + if ( !interior_in_conflict ) + continue; - Edge e = sym_edge(f, i); + Edge e = sym_edge(curr_f, i); + CGAL_assertion( l.is_in_list(e) ); - CGAL_assertion( l.is_in_list(e) ); - int j = this->_tds.mirror_index(f, i); - Edge e_before = sym_edge(n, ccw(j)); - Edge e_after = sym_edge(n, cw(j)); - if ( !l.is_in_list(e_before) ) { - l.insert_before(e, e_before); - } - if ( !l.is_in_list(e_after) ) { - l.insert_after(e, e_after); - } - l.remove(e); + int j = this->_tds.mirror_index(curr_f, i); + Edge e_before = sym_edge(n, ccw(j)); + Edge e_after = sym_edge(n, cw(j)); - expand_conflict_region_remove(n, t, ss, l, fm, sign_map); - } // for-loop + if ( !l.is_in_list(e_before) ) + l.insert_before(e, e_before); + + if ( !l.is_in_list(e_after) ) + l.insert_after(e, e_after); + + l.remove(e); + + face_stack.push(n); + } // neighbor for-loop + } } @@ -1690,7 +1744,7 @@ find_conflict_region_remove(const Vertex_handle& v, } initialize_conflict_region(start_f, l); - expand_conflict_region_remove(start_f, t, ss, l, fm, sign_map); + expand_conflict_region_remove(start_f, t, l, fm, sign_map); } diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_hierarchy_2_impl.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_hierarchy_2_impl.h index f96d359e955..9b0337d7185 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_hierarchy_2_impl.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Segment_Delaunay_graph_hierarchy_2_impl.h @@ -478,8 +478,7 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss, vcross(false, Vertex_handle(), AT2::DISJOINT); hierarchy[0]->initialize_conflict_region(start_f, l); - hierarchy[0]->expand_conflict_region(start_f, t, ss, l, fm, - sign_map, vcross); + hierarchy[0]->expand_conflict_region(start_f, t, l, fm, sign_map, vcross); CGAL_assertion( vcross.third == AT2::DISJOINT || vcross.third == AT2::CROSSING || diff --git a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Segment_Delaunay_graph_Linf_hierarchy_2_impl.h b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Segment_Delaunay_graph_Linf_hierarchy_2_impl.h index c7cadcbe37a..92f48a6db85 100644 --- a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Segment_Delaunay_graph_Linf_hierarchy_2_impl.h +++ b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Segment_Delaunay_graph_Linf_hierarchy_2_impl.h @@ -520,8 +520,7 @@ insert_segment_interior(const Site_2& t, const Storage_site_2& ss, vcross(false, Vertex_handle(), AT2::DISJOINT); hierarchy[0]->initialize_conflict_region(start_f, l); - hierarchy[0]->expand_conflict_region(start_f, t, ss, l, fm, - sign_map, vcross); + hierarchy[0]->expand_conflict_region(start_f, t, l, fm, sign_map, vcross); CGAL_assertion( vcross.third == AT2::DISJOINT || vcross.third == AT2::CROSSING || diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index 1d0087cf9dd..77711dc1ef6 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -28,6 +28,11 @@ #include #include +#include +#include +#include + + namespace CGAL {