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