1 // Copyright (c) 2017 INRIA Sophia-Antipolis (France). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Periodic_3_triangulation_3/include/CGAL/internal/Robust_periodic_weighted_circumcenter_traits_3.h $ 7 // $Id: Robust_periodic_weighted_circumcenter_traits_3.h 254d60f 2019-10-19T15:23:19+02:00 Sébastien Loriot 8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // Author(s) : Mael Rouxel-Labbé 11 12 #ifndef CGAL_ROBUST_PERIODIC_WEIGHTED_CIRCUMCENTER_TRAITS_3_H 13 #define CGAL_ROBUST_PERIODIC_WEIGHTED_CIRCUMCENTER_TRAITS_3_H 14 15 #include <CGAL/license/Periodic_3_triangulation_3.h> 16 17 #include <CGAL/number_utils_classes.h> 18 #include <CGAL/Exact_kernel_selector.h> 19 20 #include <CGAL/Periodic_3_regular_triangulation_traits_3.h> 21 22 namespace CGAL 23 { 24 25 template <typename K_, typename CWC_Base_> 26 class Robust_periodic_construct_weighted_circumcenter_3 27 : public CWC_Base_ 28 { 29 typedef K_ Base_traits; 30 typedef CWC_Base_ Base; 31 32 public: 33 typedef typename Base_traits::FT FT; 34 typedef typename Base_traits::Point_3 Point_3; 35 typedef typename Base_traits::Weighted_point_3 Weighted_point_3; 36 typedef typename Base_traits::Sphere_3 Sphere_3; 37 38 typedef typename Base_traits::Offset Offset; 39 40 typedef Point_3 result_type; 41 Robust_periodic_construct_weighted_circumcenter_3(const Base_traits & base_traits)42 Robust_periodic_construct_weighted_circumcenter_3(const Base_traits& base_traits) 43 : Base(base_traits.construct_weighted_circumcenter_3_object()), 44 base_traits(base_traits) 45 { } 46 operator()47 Point_3 operator()(const Weighted_point_3& p, const Weighted_point_3& q, 48 const Weighted_point_3& r, const Weighted_point_3& s) const 49 { 50 return Base::operator()(p,q,r,s); 51 } 52 operator()53 Point_3 operator()(const Weighted_point_3& p, const Weighted_point_3& q, const Weighted_point_3& r) const 54 { 55 return Base::operator()(p,q,r); 56 } 57 operator()58 Point_3 operator()(const Weighted_point_3& p, const Weighted_point_3& q) const 59 { 60 return Base::operator()(p,q); 61 } 62 operator()63 Point_3 operator()(const Weighted_point_3& p, 64 const Weighted_point_3& q, 65 const Weighted_point_3& r, 66 const Weighted_point_3& s, 67 const Offset& o_p, const Offset& o_q, 68 const Offset& o_r, const Offset& o_s) const 69 { 70 typename Base_traits::Construct_weighted_point_3 p2wp = 71 base_traits.construct_weighted_point_3_object(); 72 typename Base_traits::Construct_weighted_circumcenter_3 cwc = 73 base_traits.construct_weighted_circumcenter_3_object(); 74 typename Base_traits::Power_side_of_oriented_power_sphere_3 ps = 75 base_traits.power_side_of_oriented_power_sphere_3_object(); 76 77 Point_3 c = cwc(p, q, r, s, o_p, o_q, o_r, o_s); 78 79 if(ps(p, q, r, s, p2wp(c), o_p, o_q, o_r, o_s, Offset()) != ON_POSITIVE_SIDE) 80 { 81 // switch to exact 82 typedef typename Base_traits::Kernel K; 83 typedef typename Exact_kernel_selector<K>::Exact_kernel EK; 84 typedef typename Exact_kernel_selector<K>::C2E C2E; 85 typedef typename Exact_kernel_selector<K>::E2C E2C; 86 87 C2E to_exact; 88 E2C back_from_exact; 89 90 typedef Periodic_3_regular_triangulation_traits_3<EK> Exact_traits; 91 Exact_traits etraits(to_exact(base_traits.get_domain())); 92 93 c = back_from_exact( 94 etraits.construct_weighted_circumcenter_3_object()( 95 to_exact(p), to_exact(q), to_exact(r), to_exact(s), 96 o_p, o_q, o_r, o_s)); 97 98 CGAL_assertion(ps(p, q, r, s, p2wp(c), o_p, o_q, o_r, o_s, Offset()) == ON_POSITIVE_SIDE); 99 } 100 101 return c; 102 } 103 operator()104 Point_3 operator()(const Weighted_point_3 & p, 105 const Weighted_point_3 & q, 106 const Weighted_point_3 & r, 107 const Offset& o_p, const Offset& o_q, 108 const Offset& o_r) const 109 { 110 typename Base_traits::Construct_weighted_point_3 p2wp = 111 base_traits.construct_weighted_point_3_object(); 112 typename Base_traits::Construct_weighted_circumcenter_3 cwc = 113 base_traits.construct_weighted_circumcenter_3_object(); 114 typename Base_traits::Power_side_of_bounded_power_sphere_3 ps = 115 base_traits.power_side_of_bounded_power_sphere_3_object(); 116 117 Point_3 c = cwc(p, q, r, o_p, o_q, o_r); 118 119 if(ps(p, q, r, p2wp(c), o_p, o_q, o_r, Offset()) != ON_BOUNDED_SIDE) 120 { 121 // switch to exact 122 typedef typename Base_traits::Kernel K; 123 typedef typename Exact_kernel_selector<K>::Exact_kernel EK; 124 typedef typename Exact_kernel_selector<K>::C2E C2E; 125 typedef typename Exact_kernel_selector<K>::E2C E2C; 126 127 C2E to_exact; 128 E2C back_from_exact; 129 130 typedef Periodic_3_regular_triangulation_traits_3<EK> Exact_traits; 131 Exact_traits etraits(to_exact(base_traits.get_domain())); 132 133 c = back_from_exact( 134 etraits.construct_weighted_circumcenter_3_object()( 135 to_exact(p), to_exact(q), to_exact(r), o_p, o_q, o_r)); 136 137 CGAL_assertion(ps(p, q, r, p2wp(c), o_p, o_q, o_r, Offset()) == ON_BOUNDED_SIDE); 138 } 139 140 return c; 141 } 142 operator()143 Point_3 operator()(const Weighted_point_3 & p, 144 const Weighted_point_3 & q, 145 const Offset& o_p, const Offset& o_q) const 146 { 147 typename Base_traits::Construct_weighted_point_3 p2wp = 148 base_traits.construct_weighted_point_3_object(); 149 typename Base_traits::Construct_weighted_circumcenter_3 cwc = 150 base_traits.construct_weighted_circumcenter_3_object(); 151 typename Base_traits::Power_side_of_bounded_power_sphere_3 ps = 152 base_traits.power_side_of_bounded_power_sphere_3_object(); 153 154 Point_3 c = cwc(p, q, o_p, o_q); 155 156 if(ps(p, q, p2wp(c), o_p, o_q, Offset()) != ON_BOUNDED_SIDE) 157 { 158 // switch to exact 159 typedef typename Base_traits::Kernel K; 160 typedef typename Exact_kernel_selector<K>::Exact_kernel EK; 161 typedef typename Exact_kernel_selector<K>::C2E C2E; 162 typedef typename Exact_kernel_selector<K>::E2C E2C; 163 164 C2E to_exact; 165 E2C back_from_exact; 166 167 typedef Periodic_3_regular_triangulation_traits_3<EK> Exact_traits; 168 Exact_traits etraits(to_exact(base_traits.get_domain())); 169 170 c = back_from_exact( 171 etraits.construct_weighted_circumcenter_3_object()( 172 to_exact(p), to_exact(q), o_p, o_q)); 173 174 CGAL_assertion(ps(p, q, p2wp(c), o_p, o_q, Offset()) == ON_BOUNDED_SIDE); 175 } 176 177 return c; 178 } 179 180 const Base_traits& base_traits; 181 }; 182 183 template <typename K_> 184 class Robust_periodic_weighted_circumcenter_traits_3 185 : public K_ 186 { 187 typedef K_ Base_traits; 188 189 public: 190 typedef typename Base_traits::Iso_cuboid_3 Iso_cuboid_3; 191 192 typedef CGAL::Robust_periodic_construct_weighted_circumcenter_3< 193 Base_traits, typename Base_traits::Construct_weighted_circumcenter_3> 194 Construct_weighted_circumcenter_3; 195 196 Construct_weighted_circumcenter_3 construct_weighted_circumcenter_3_object()197 construct_weighted_circumcenter_3_object() const 198 { return Construct_weighted_circumcenter_3(static_cast<const Base_traits&>(*this)); } 199 200 Robust_periodic_weighted_circumcenter_traits_3(const Iso_cuboid_3& domain = Iso_cuboid_3(0,0,0,1,1,1), 201 const Base_traits& t = Base_traits()) Base_traits(domain,t)202 : Base_traits(domain, t) 203 { } 204 }; 205 206 } // end namespace CGAL 207 208 #endif // CGAL_ROBUST_PERIODIC_WEIGHTED_CIRCUMCENTER_TRAITS_3_H 209