From c40d7124d07780fcf8d64d0a8529cc8ebc3e4ad7 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 18 May 2018 17:47:01 +0200 Subject: [PATCH 1/4] Fix CDT_2 errors, using snapping of intersection points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `Constrained_triangulation_2` computes the intersection of two segments, with a floating-point number type, and with `Exact_predicates_tag`, the computed intersection point is snapped to an extremity of the two segments, if it is closest to 4 ulp (with the l-inf distance). That value `4` can be changed by defining the macro `CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE` to another value. --- .../CGAL/Constrained_triangulation_2.h | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 6ca828a3adb..6f60a7ec484 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -37,6 +37,9 @@ #include #include +#include +#include + namespace CGAL { struct No_intersection_tag{}; @@ -1422,11 +1425,70 @@ intersection(const Gt& gt, const typename Gt::Point_2& pc, const typename Gt::Point_2& pd, typename Gt::Point_2& pi, - Exact_predicates_tag) + Exact_predicates_tag, + CGAL::Tag_false /* not a FT is not floating-point */) { return compute_intersection(gt,pa,pb,pc,pd,pi); } +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag, + CGAL::Tag_true /* FT is a floating-point type */) +{ + const bool result = compute_intersection(gt,pa,pb,pc,pd,pi); + if(!result) return result; + if(pi == pa || pi == pb || pi == pc || pi == pd) { +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + std::cerr << " CT_2::intersection: intersection is an existing point " + << pi << std::endl; +#endif + return result; + } + + using boost::math::float_advance; +#ifdef CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE + const int dist = CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE; +#else + const int dist = 4; +#endif + const Bbox_2 bbox(float_advance(pi.x(), -dist), float_advance(pi.y(), -dist), + float_advance(pi.x(), +dist), float_advance(pi.y(), +dist)); + if(do_overlap(bbox, pa.bbox())) pi = pa; + if(do_overlap(bbox, pb.bbox())) pi = pb; + if(do_overlap(bbox, pc.bbox())) pi = pc; + if(do_overlap(bbox, pd.bbox())) pi = pd; +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + if(pi == pa || pi == pb || pi == pc || pi == pd) { + std::cerr << " CT_2::intersection: intersection SNAPPED to an existing point " + << pi << std::endl; + } +#endif + return result; +} + +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag exact_predicates_tag) +{ + typedef typename Gt::FT FT; + return intersection(gt,pa,pb,pc,pd,pi, + exact_predicates_tag, + Boolean_tag::value>()); +} + template bool From 1123afb70e8d75f3107dc97b536959ae60c39426 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 24 May 2018 11:08:05 +0100 Subject: [PATCH 2/4] Add Bbox_{2,3}.dilate(int) so that the snapping in the CT_2 also works with Projection_traits classes --- Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h | 5 +++++ Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h | 4 ++++ Kernel_23/include/CGAL/Bbox_2.h | 14 +++++++++++++- Kernel_23/include/CGAL/Bbox_3.h | 17 +++++++++++++++++ .../CGAL/internal/Projection_traits_3.h | 4 ++++ .../ConstrainedTriangulationTraits_2.h | 8 ++++++++ .../CGAL/Constrained_triangulation_2.h | 19 +++++++++++-------- ...Triangulation_2_projection_traits_base_3.h | 4 ++++ 8 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h index 284cc4178fa..3f70437c5b5 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h @@ -95,6 +95,11 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_2& operator+=(const Bbox_2 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); + /// @} }; /* end Bbox_2 */ diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h index 66d54449ae3..88d9f4dd426 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h @@ -109,6 +109,10 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_3& operator+=(const Bbox_3 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); /// @} }; /* end Bbox_3 */ diff --git a/Kernel_23/include/CGAL/Bbox_2.h b/Kernel_23/include/CGAL/Bbox_2.h index aa982b91745..003271353d5 100644 --- a/Kernel_23/include/CGAL/Bbox_2.h +++ b/Kernel_23/include/CGAL/Bbox_2.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace CGAL { @@ -75,6 +76,7 @@ public: inline Bbox_2 operator+(const Bbox_2 &b) const; inline Bbox_2& operator+=(const Bbox_2 &b); + inline void dilate(int dist); }; inline @@ -155,7 +157,17 @@ Bbox_2::operator+=(const Bbox_2& b) rep[3] = (std::max)(ymax(), b.ymax()); return *this; } - +inline +void +Bbox_2::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[3],dist); + float_advance(rep[4],dist); +} + inline bool do_overlap(const Bbox_2 &bb1, const Bbox_2 &bb2) diff --git a/Kernel_23/include/CGAL/Bbox_3.h b/Kernel_23/include/CGAL/Bbox_3.h index 4e1adee6265..9089df3209c 100644 --- a/Kernel_23/include/CGAL/Bbox_3.h +++ b/Kernel_23/include/CGAL/Bbox_3.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace CGAL { @@ -77,6 +78,8 @@ public: Bbox_3 operator+(const Bbox_3& b) const; Bbox_3& operator+=(const Bbox_3& b); + + void dilate(int dist); }; inline @@ -175,6 +178,20 @@ Bbox_3::operator+=(const Bbox_3& b) return *this; } +inline +void +Bbox_3::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[2],-dist); + float_advance(rep[3],dist); + float_advance(rep[4],dist); + float_advance(rep[5],dist); +} + + inline bool do_overlap(const Bbox_3& bb1, const Bbox_3& bb2) diff --git a/Kernel_23/include/CGAL/internal/Projection_traits_3.h b/Kernel_23/include/CGAL/internal/Projection_traits_3.h index e5ba5ae0123..99da7e70d25 100644 --- a/Kernel_23/include/CGAL/internal/Projection_traits_3.h +++ b/Kernel_23/include/CGAL/internal/Projection_traits_3.h @@ -801,6 +801,7 @@ public: typedef typename Rp::Construct_scaled_vector_3 Construct_scaled_vector_2; typedef typename Rp::Construct_triangle_3 Construct_triangle_2; typedef typename Rp::Construct_line_3 Construct_line_2; + typedef typename Rp::Construct_bbox_3 Construct_bbox_2; struct Less_xy_2 { typedef bool result_type; @@ -985,6 +986,9 @@ public: Construct_line_2 construct_line_2_object() const {return Construct_line_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + Compute_scalar_product_2 compute_scalar_product_2_object() const {return Compute_scalar_product_2();} diff --git a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h index 70518403f11..e13c8388506 100644 --- a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h +++ b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h @@ -76,6 +76,14 @@ between `p` and `l`. */ typedef unspecified_type Compute_squared_distance_2; +/*! +A function object whose +`operator()` computes the bounding box of a point. + +`Point_2 operator()(Point_2 p);` Returns the bounding box of `p`. +*/ +typedef unspecified_type Compute_bounding_box_2; + /// @} /// \name Access to Constructor Objects diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 6f60a7ec484..4bcac74f891 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -37,7 +37,8 @@ #include #include -#include + +#include #include namespace CGAL { @@ -1452,18 +1453,20 @@ intersection(const Gt& gt, return result; } - using boost::math::float_advance; + #ifdef CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE const int dist = CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE; #else const int dist = 4; #endif - const Bbox_2 bbox(float_advance(pi.x(), -dist), float_advance(pi.y(), -dist), - float_advance(pi.x(), +dist), float_advance(pi.y(), +dist)); - if(do_overlap(bbox, pa.bbox())) pi = pa; - if(do_overlap(bbox, pb.bbox())) pi = pb; - if(do_overlap(bbox, pc.bbox())) pi = pc; - if(do_overlap(bbox, pd.bbox())) pi = pd; + typedef typename Gt::Construct_bbox_2 Construct_bbox_2; + Construct_bbox_2 bbox = gt.construct_bbox_2_object(); + typename boost::result_of::type bb(bbox(pi)); + bb.dilate(dist); + if(do_overlap(bb, bbox(pa))) pi = pa; + if(do_overlap(bb, bbox(pb))) pi = pb; + if(do_overlap(bb, bbox(pc))) pi = pc; + if(do_overlap(bb, bbox(pd))) pi = pd; #ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS if(pi == pa || pi == pb || pi == pc || pi == pd) { std::cerr << " CT_2::intersection: intersection SNAPPED to an existing point " diff --git a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h index 7037f6fcc28..10745a8ceee 100644 --- a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h +++ b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h @@ -379,6 +379,7 @@ public: typedef typename K::Construct_circumcenter_3 Construct_circumcenter_2; typedef typename K::Compute_area_3 Compute_area_2; + typedef typename K::Construct_bbox_3 Construct_bbox_2; Less_x_2 less_x_2_object() const @@ -465,6 +466,9 @@ public: {return Compute_area_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + // Special functor, not in the Kernel concept class Projection_to_plan { From 469b90456aff0481535de8cd2d4b492332eee015 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 25 May 2018 10:36:24 +0100 Subject: [PATCH 3/4] Fix doc --- .../Concepts/ConstrainedTriangulationTraits_2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h index e13c8388506..dd235e31e37 100644 --- a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h +++ b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h @@ -80,7 +80,8 @@ typedef unspecified_type Compute_squared_distance_2; A function object whose `operator()` computes the bounding box of a point. -`Point_2 operator()(Point_2 p);` Returns the bounding box of `p`. +`unspecified_type operator()(Point_2 p);` Returns the bounding box of `p`. +The result type is either `Bbox_2` or `Bbox_3` (for projection traits classes). */ typedef unspecified_type Compute_bounding_box_2; From 8fa2670526536e212098bb32c5753687a9f208d1 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sat, 26 May 2018 13:35:46 +0100 Subject: [PATCH 4/4] fix Bbox_2::dilate() --- Kernel_23/include/CGAL/Bbox_2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel_23/include/CGAL/Bbox_2.h b/Kernel_23/include/CGAL/Bbox_2.h index 003271353d5..094e785394c 100644 --- a/Kernel_23/include/CGAL/Bbox_2.h +++ b/Kernel_23/include/CGAL/Bbox_2.h @@ -164,8 +164,8 @@ Bbox_2::dilate(int dist) using boost::math::float_advance; float_advance(rep[0],-dist); float_advance(rep[1],-dist); + float_advance(rep[2],dist); float_advance(rep[3],dist); - float_advance(rep[4],dist); } inline