// Copyright (c) 1998,2003 // 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) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Kernel_23/include/CGAL/Kernel/Wutils.h $ // $Id: Wutils.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Geert-Jan Giezeman, Sylvain Pion #ifndef CGAL_KERNEL_WUTILS_H #define CGAL_KERNEL_WUTILS_H #include #include #include #include // Functions wmult() and wcross(). namespace CGAL { namespace internal { template < typename Rep_Tag > struct wmult_tag; template <> struct wmult_tag { template < typename RT > const RT & operator()(const RT &a, const RT &) const { return a; } template < typename RT > const RT & operator()(const RT &a, const RT &, const RT &) const { return a; } template < typename RT > const RT & operator()(const RT &a, const RT &, const RT &, const RT &) const { return a; } template < typename RT > const RT & operator()(const RT &a, const RT &, const RT &, const RT &, const RT &) const { return a; } }; template <> struct wmult_tag { template < typename RT > RT operator()(const RT &a, const RT &w) const { return a*w; } template < typename RT > RT operator()(const RT &a, const RT &w1, const RT &w2) const { return a*w1*w2; } template < typename RT > RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3) const { return a*w1*w2*w3; } template < typename RT > RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3, const RT &w4) const { return a*w1*w2*w3*w4; } }; template < typename K > struct wmult_functor : public wmult_tag {}; template < typename Rep_Tag > struct wmult_hw_tag; template <> struct wmult_hw_tag { template < typename RT, typename T > const RT & operator()(const RT &a, const T &) const { return a; } template < typename RT, typename T > const RT & operator()(const RT &a, const RT &, const T &) const { return a; } template < typename RT, typename T > const RT & operator()(const RT &a, const RT &, const RT &, const T &) const { return a; } template < typename RT, typename T > const RT & operator()(const RT &a, const RT &, const RT &, const RT &, const T &) const { return a; } }; template <> struct wmult_hw_tag { template < typename RT, typename T > RT operator()(const RT &a, const T &t) const { return a*t.hw(); } template < typename RT, typename T > RT operator()(const RT &a, const RT &w1, const T &t) const { return a*w1*t.hw(); } template < typename RT, typename T > RT operator()(const RT &a, const RT &w1, const RT &w2, const T &t) const { return a*w1*w2*t.hw(); } template < typename RT, typename T > RT operator()(const RT &a, const RT &w1, const RT &w2, const RT &w3, const T &t) const { return a*w1*w2*w3*t.hw(); } }; template < typename K > struct wmult_hw_functor : public wmult_hw_tag {}; template < typename Rep_Tag > struct wcross_tag_2; template <> struct wcross_tag_2 { template < typename Point_2 > typename Point_2::R::RT operator()(const Point_2 &p, const Point_2 &q, const Point_2 &r) const { return (q.x()-p.x())*(r.y()-q.y()) - (q.y()-p.y())*(r.x()-q.x()); } }; template <> struct wcross_tag_2 { template < typename Point_2 > typename Point_2::R::RT operator()(const Point_2 &p, const Point_2 &q, const Point_2 &r) const { return determinant(p.hx(), q.hx(), r.hx(), p.hy(), q.hy(), r.hy(), p.hw(), q.hw(), r.hw()); } }; template < typename K > struct wcross_functor_2 : public wcross_tag_2 {}; template < typename Rep_Tag > struct wcross_tag_3; template <> struct wcross_tag_3 { template < typename Point_3 > typename Point_3::R::Vector_3 operator()(const Point_3 &p, const Point_3 &q, const Point_3 &r) const { typedef typename Point_3::R::FT FT; typedef typename Point_3::R::Vector_3 Vector_3; FT x = (q.y()-p.y())*(r.z()-q.z()) - (q.z()-p.z())*(r.y()-q.y()); FT y = (q.z()-p.z())*(r.x()-q.x()) - (q.x()-p.x())*(r.z()-q.z()); FT z = (q.x()-p.x())*(r.y()-q.y()) - (q.y()-p.y())*(r.x()-q.x()); return Vector_3(x, y, z); } }; template <> struct wcross_tag_3 { template < typename Point_3 > typename Point_3::R::Vector_3 operator()(const Point_3 &p, const Point_3 &q, const Point_3 &r) const { typedef typename Point_3::R::RT RT; typedef typename Point_3::R::Vector_3 Vector_3; RT x = p.hy() * (q.hz()*r.hw() - q.hw()*r.hz() ) + p.hz() * (q.hw()*r.hy() - q.hy()*r.hw() ) + p.hw() * (q.hy()*r.hz() - q.hz()*r.hy() ); RT y = p.hz() * (q.hx()*r.hw() - q.hw()*r.hx() ) + p.hx() * (q.hw()*r.hz() - q.hz()*r.hw() ) + p.hw() * (q.hz()*r.hx() - q.hx()*r.hz() ); RT z = p.hx() * (q.hy()*r.hw() - q.hw()*r.hy() ) + p.hy() * (q.hw()*r.hx() - q.hx()*r.hw() ) + p.hw() * (q.hx()*r.hy() - q.hy()*r.hx() ); return Vector_3(x, y, z); } }; template < typename K > struct wcross_functor_3 : public wcross_tag_3 {}; } // end namespace internal // wmult_hw() is like wmult(), except it calls .hw() on its last argument. // This way, we can completely avoid creating FT(1) for Cartesian. template < typename K, typename T > inline typename K::RT wmult_hw(K*, const typename K::RT &a, const T &t) { return internal::wmult_hw_functor()(a, t); } template < typename K, typename T > inline typename K::RT wmult_hw(K*, const typename K::RT &a, const typename K::RT &w1, const T &t) { return internal::wmult_hw_functor()(a, w1, t); } template < typename K, typename T > inline typename K::RT wmult_hw(K*, const typename K::RT &a, const typename K::RT &w1, const typename K::RT &w2, const T &t) { return internal::wmult_hw_functor()(a, w1, w2, t); } template < typename K, typename T > inline typename K::RT wmult_hw(K*, const typename K::RT &a, const typename K::RT &w1, const typename K::RT &w2, const typename K::RT &w3, const T &t) { return internal::wmult_hw_functor()(a, w1, w2, w3, t); } template < typename K > inline typename K::RT wmult(K*, const typename K::RT &a, const typename K::RT &w) { return internal::wmult_functor()(a, w); } template < typename K > inline typename K::RT wmult(K*, const typename K::RT &a, const typename K::RT &w1, const typename K::RT &w2) { return internal::wmult_functor()(a, w1, w2); } template < typename K > inline typename K::RT wmult(K*, const typename K::RT &a, const typename K::RT &w1, const typename K::RT &w2, const typename K::RT &w3) { return internal::wmult_functor()(a, w1, w2, w3); } template < typename K > inline typename K::RT wmult(K*, const typename K::RT &a, const typename K::RT &w1, const typename K::RT &w2, const typename K::RT &w3, const typename K::RT &w4) { return internal::wmult_functor()(a, w1, w2, w3, w4); } template < typename K > inline typename K::RT wcross(K*, const Point_2 &p, const Point_2 &q, const Point_2 &r) { return internal::wcross_functor_2()(p, q, r); } template < typename K > inline typename K::Vector_3 wcross(const Point_3 &p, const Point_3 &q, const Point_3 &r) { return internal::wcross_functor_3()(p, q, r); } } //namespace CGAL #endif // CGAL_KERNEL_WUTILS_H