1 // Copyright (c) 1998,2003 2 // Utrecht University (The Netherlands), 3 // ETH Zurich (Switzerland), 4 // INRIA Sophia-Antipolis (France), 5 // Max-Planck-Institute Saarbruecken (Germany), 6 // and Tel-Aviv University (Israel). All rights reserved. 7 // 8 // This file is part of CGAL (www.cgal.org) 9 // 10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Kernel_23/include/CGAL/Kernel/Wutils.h $ 11 // $Id: Wutils.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot 12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial 13 // 14 // 15 // Author(s) : Geert-Jan Giezeman, Sylvain Pion 16 17 #ifndef CGAL_KERNEL_WUTILS_H 18 #define CGAL_KERNEL_WUTILS_H 19 20 #include <CGAL/representation_tags.h> 21 #include <CGAL/determinant.h> 22 #include <CGAL/Point_2.h> 23 #include <CGAL/Point_3.h> 24 25 // Functions wmult() and wcross(). 26 27 namespace CGAL { 28 29 namespace internal { 30 31 template < typename Rep_Tag > struct wmult_tag; 32 33 template <> 34 struct wmult_tag<Cartesian_tag> 35 { 36 template < typename RT > 37 const RT & operator()(const RT &a, const RT &) const 38 { return a; } 39 40 template < typename RT > 41 const RT & operator()(const RT &a, const RT &, const RT &) const 42 { return a; } 43 44 template < typename RT > 45 const RT & operator()(const RT &a, const RT &, const RT &, const RT &) const 46 { return a; } 47 48 template < typename RT > 49 const RT & operator()(const RT &a, const RT &, const RT &, const RT &, 50 const RT &) const 51 { return a; } 52 }; 53 54 template <> 55 struct wmult_tag<Homogeneous_tag> 56 { 57 template < typename RT > 58 RT operator()(const RT &a, const RT &w) const 59 { return a*w; } 60 61 template < typename RT > 62 RT operator()(const RT &a, const RT &w1, const RT &w2) const 63 { return a*w1*w2; } 64 65 template < typename RT > 66 RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3) const 67 { return a*w1*w2*w3; } 68 69 template < typename RT > 70 RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3, 71 const RT &w4) const 72 { return a*w1*w2*w3*w4; } 73 }; 74 75 template < typename K > 76 struct wmult_functor 77 : public wmult_tag<typename K::Rep_tag> {}; 78 79 80 template < typename Rep_Tag > struct wmult_hw_tag; 81 82 template <> 83 struct wmult_hw_tag<Cartesian_tag> 84 { 85 template < typename RT, typename T > 86 const RT & operator()(const RT &a, const T &) const 87 { return a; } 88 89 template < typename RT, typename T > 90 const RT & operator()(const RT &a, const RT &, const T &) const 91 { return a; } 92 93 template < typename RT, typename T > 94 const RT & operator()(const RT &a, const RT &, const RT &, const T &) const 95 { return a; } 96 97 template < typename RT, typename T > 98 const RT & operator()(const RT &a, const RT &, const RT &, const RT &, 99 const T &) const 100 { return a; } 101 }; 102 103 template <> 104 struct wmult_hw_tag<Homogeneous_tag> 105 { 106 template < typename RT, typename T > 107 RT operator()(const RT &a, const T &t) const 108 { return a*t.hw(); } 109 110 template < typename RT, typename T > 111 RT operator()(const RT &a, const RT &w1, const T &t) const 112 { return a*w1*t.hw(); } 113 114 template < typename RT, typename T > 115 RT operator()(const RT &a, const RT &w1, const RT &w2, const T &t) const 116 { return a*w1*w2*t.hw(); } 117 118 template < typename RT, typename T > 119 RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3, 120 const T &t) const 121 { return a*w1*w2*w3*t.hw(); } 122 }; 123 124 125 template < typename K > 126 struct wmult_hw_functor 127 : public wmult_hw_tag<typename K::Rep_tag> {}; 128 129 130 template < typename Rep_Tag > struct wcross_tag_2; 131 132 template <> 133 struct wcross_tag_2<Cartesian_tag> 134 { 135 template < typename Point_2 > 136 typename Point_2::R::RT operator()(const Point_2 &p, 137 const Point_2 &q, 138 const Point_2 &r) const 139 { 140 return (q.x()-p.x())*(r.y()-q.y()) - (q.y()-p.y())*(r.x()-q.x()); 141 } 142 }; 143 144 template <> 145 struct wcross_tag_2<Homogeneous_tag> 146 { 147 template < typename Point_2 > 148 typename Point_2::R::RT operator()(const Point_2 &p, 149 const Point_2 &q, 150 const Point_2 &r) const 151 { 152 return determinant(p.hx(), q.hx(), r.hx(), 153 p.hy(), q.hy(), r.hy(), 154 p.hw(), q.hw(), r.hw()); 155 } 156 }; 157 158 template < typename K > 159 struct wcross_functor_2 160 : public wcross_tag_2<typename K::Rep_tag> {}; 161 162 163 template < typename Rep_Tag > struct wcross_tag_3; 164 165 template <> 166 struct wcross_tag_3<Cartesian_tag> 167 { 168 template < typename Point_3 > 169 typename Point_3::R::Vector_3 operator()(const Point_3 &p, 170 const Point_3 &q, 171 const Point_3 &r) const 172 { 173 typedef typename Point_3::R::FT FT; 174 typedef typename Point_3::R::Vector_3 Vector_3; 175 FT x = (q.y()-p.y())*(r.z()-q.z()) - (q.z()-p.z())*(r.y()-q.y()); 176 FT y = (q.z()-p.z())*(r.x()-q.x()) - (q.x()-p.x())*(r.z()-q.z()); 177 FT z = (q.x()-p.x())*(r.y()-q.y()) - (q.y()-p.y())*(r.x()-q.x()); 178 return Vector_3(x, y, z); 179 } 180 }; 181 182 template <> 183 struct wcross_tag_3<Homogeneous_tag> 184 { 185 template < typename Point_3 > 186 typename Point_3::R::Vector_3 operator()(const Point_3 &p, 187 const Point_3 &q, 188 const Point_3 &r) const 189 { 190 typedef typename Point_3::R::RT RT; 191 typedef typename Point_3::R::Vector_3 Vector_3; 192 RT x = p.hy() * (q.hz()*r.hw() - q.hw()*r.hz() ) 193 + p.hz() * (q.hw()*r.hy() - q.hy()*r.hw() ) 194 + p.hw() * (q.hy()*r.hz() - q.hz()*r.hy() ); 195 RT y = p.hz() * (q.hx()*r.hw() - q.hw()*r.hx() ) 196 + p.hx() * (q.hw()*r.hz() - q.hz()*r.hw() ) 197 + p.hw() * (q.hz()*r.hx() - q.hx()*r.hz() ); 198 RT z = p.hx() * (q.hy()*r.hw() - q.hw()*r.hy() ) 199 + p.hy() * (q.hw()*r.hx() - q.hx()*r.hw() ) 200 + p.hw() * (q.hx()*r.hy() - q.hy()*r.hx() ); 201 return Vector_3(x, y, z); 202 } 203 }; 204 205 template < typename K > 206 struct wcross_functor_3 207 : public wcross_tag_3<typename K::Rep_tag> {}; 208 209 } // end namespace internal 210 211 212 // wmult_hw() is like wmult(), except it calls .hw() on its last argument. 213 // This way, we can completely avoid creating FT(1) for Cartesian. 214 215 template < typename K, typename T > 216 inline 217 typename K::RT 218 wmult_hw(K*, const typename K::RT &a, 219 const T &t) 220 { 221 return internal::wmult_hw_functor<K>()(a, t); 222 } 223 224 template < typename K, typename T > 225 inline 226 typename K::RT 227 wmult_hw(K*, const typename K::RT &a, 228 const typename K::RT &w1, 229 const T &t) 230 { 231 return internal::wmult_hw_functor<K>()(a, w1, t); 232 } 233 234 template < typename K, typename T > 235 inline 236 typename K::RT 237 wmult_hw(K*, const typename K::RT &a, 238 const typename K::RT &w1, 239 const typename K::RT &w2, 240 const T &t) 241 { 242 return internal::wmult_hw_functor<K>()(a, w1, w2, t); 243 } 244 245 template < typename K, typename T > 246 inline 247 typename K::RT 248 wmult_hw(K*, const typename K::RT &a, 249 const typename K::RT &w1, 250 const typename K::RT &w2, 251 const typename K::RT &w3, 252 const T &t) 253 { 254 return internal::wmult_hw_functor<K>()(a, w1, w2, w3, t); 255 } 256 257 258 template < typename K > 259 inline 260 typename K::RT 261 wmult(K*, const typename K::RT &a, 262 const typename K::RT &w) 263 { 264 return internal::wmult_functor<K>()(a, w); 265 } 266 267 template < typename K > 268 inline 269 typename K::RT 270 wmult(K*, const typename K::RT &a, 271 const typename K::RT &w1, 272 const typename K::RT &w2) 273 { 274 return internal::wmult_functor<K>()(a, w1, w2); 275 } 276 277 template < typename K > 278 inline 279 typename K::RT 280 wmult(K*, const typename K::RT &a, 281 const typename K::RT &w1, 282 const typename K::RT &w2, 283 const typename K::RT &w3) 284 { 285 return internal::wmult_functor<K>()(a, w1, w2, w3); 286 } 287 288 template < typename K > 289 inline 290 typename K::RT 291 wmult(K*, const typename K::RT &a, 292 const typename K::RT &w1, 293 const typename K::RT &w2, 294 const typename K::RT &w3, 295 const typename K::RT &w4) 296 { 297 return internal::wmult_functor<K>()(a, w1, w2, w3, w4); 298 } 299 300 template < typename K > 301 inline 302 typename K::RT 303 wcross(K*, const Point_2<K> &p, 304 const Point_2<K> &q, 305 const Point_2<K> &r) 306 { 307 return internal::wcross_functor_2<K>()(p, q, r); 308 } 309 310 template < typename K > 311 inline 312 typename K::Vector_3 313 wcross(const Point_3<K> &p, 314 const Point_3<K> &q, 315 const Point_3<K> &r) 316 { 317 return internal::wcross_functor_3<K>()(p, q, r); 318 } 319 320 } //namespace CGAL 321 322 #endif // CGAL_KERNEL_WUTILS_H 323