⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 min_sphere_of_spheres_d_support_set.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
// Copyright (c) 1997  ETH Zurich (Switzerland).// All rights reserved.//// This file is part of CGAL (www.cgal.org); you may redistribute it under// the terms of the Q Public License version 1.0.// See the file LICENSE.QPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.3-branch/Min_sphere_of_spheres_d/include/CGAL/Min_sphere_of_spheres_d/Min_sphere_of_spheres_d_support_set.h $// $Id: Min_sphere_of_spheres_d_support_set.h 37980 2007-04-06 09:08:04Z afabri $// //// Author(s)     : Kaspar Fischer#ifndef CGAL_MINIBALL_SUPPORTSET#define CGAL_MINIBALL_SUPPORTSET#include <utility>#include <functional>#include <cmath>#include <CGAL/Min_sphere_of_spheres_d/Min_sphere_of_spheres_d_configure.h>namespace CGAL_MINIBALL_NAMESPACE {  namespace Min_sphere_of_spheres_d_impl {    // The package provides specializations of (some of) the    // algorithms for float and double, while the generic version    // works with exact number types (which have no rounding    // errors). So depending on the number type FT of the input (i.e.,    // of the input point coordinates and radii) we choose a different    // algorithm. In fact, not only the algorithm depends on FT but    // also the type of the result (i.e., of the radius and the center    // coordinates of the miniball): if FT is an exact number type,    // the result is a Pair<FT> (because the radius and the center    // coordinates may be degree-2 numbers which we encode as pairs);    // if on the other hand FT is float or double, the result type    // coincides with FT.    //    // The following struct Selector<FT> contains the appropriate    // result type, and a flag telling whether the exact or floating-    // point specialization of the chosen algorithm is to be run.    template<typename FT>    struct Selector {      typedef Pair<FT> Result;      typedef Tag_true Is_exact;    };    template<>      struct Selector<float> {	typedef float Result;	typedef Tag_false Is_exact;      };    template<>    struct Selector<double> {      typedef double Result;      typedef Tag_false Is_exact;    };    template<typename FT>    struct Subtract_and_square {      inline FT operator()(const FT x,const FT y) const {        return sqr(x-y);      }    };    template<typename FT>    class Subtract_and_square_pair {    private:      const FT& d;    public:      Subtract_and_square_pair(const FT& d) : d(d) {}      inline Pair<FT> operator()(const Pair<FT>& x,                                     const FT& y) const {        const FT t = x.first - y;        return Pair<FT>(sqr(t)+sqr(x.second)*d,FT(2)*t*x.second);      }    };    template<typename FT>    struct Pair_to_double {      const double root;      Pair_to_double(const FT& disc) :        root(std::sqrt(CGAL_MINIBALL_NTS to_double(disc))) {}      inline double operator()(const Pair<FT>& p) const {        return CGAL_MINIBALL_NTS to_double(p.first) +               CGAL_MINIBALL_NTS to_double(p.second) * root;      }    };    template<typename FT>    struct Subtract_and_square_to_double {      inline double operator()(const double x,const FT& y) const {        return sqr(x - CGAL_MINIBALL_NTS to_double(y));      }    };    template<class Traits>    class Support_set {    private: // some short hands:      typedef typename Traits::FT FT;      typedef typename Min_sphere_of_spheres_d_impl::                       Selector<FT>::Result Result;      typedef typename Min_sphere_of_spheres_d_impl::                       Selector<FT>::Is_exact Is_exact;      typedef typename Traits::Use_square_roots Use_sqrt;      typedef typename Traits::Sphere Sphere;      static const int D = Traits::D;      typedef typename Traits::Cartesian_const_iterator CIt;    public: // constructor:      inline Support_set(Traits& traits);    public: // access:      inline const Result& radius() const;      inline const Result *begin() const;      inline const FT& disc() const;    public: // containment test:      template<typename InputIterator>      bool contains(InputIterator c,const FT& r,                    const FT tol,                    const Tag_false /* is_exact */) const {        // scale ball:        const FT r1 = sol[m]*tol;        // check radii:        if (r > r1)          return false;        // compute the (squared) distance from center to c:        const FT dist = inner_product_n<D>(center,c,          FT(0),std::plus<FT>(),Subtract_and_square<FT>());        // check containment:        return dist <= sqr(r1-r);      }      template<typename InputIterator>      bool contains(InputIterator c,const FT& r,                    const double,const Tag_true /* is_exact */) const {        typedef Pair<FT> P;        // check radii:        const P rd = sol[m]-r;        if (is_neg(rd,discrim[m]))          return false;        // compute the (squared) distance from center to c:        const P dist = inner_product_n<D>(center,c,          P(0,0),std::plus<P>(),Subtract_and_square_pair<FT>(discrim[m]));        // compute the square of rd:        const P sqrRd(sqr(rd.first)+sqr(rd.second)*discrim[m],                      FT(2)*rd.first*rd.second);        // check containment:        return is_neg_or_zero(dist-sqrRd,discrim[m]);      }    public: // modification:      void reset();      bool pivot(std::vector<const typename Traits::Sphere *>& l,  	       int& e,const int d);    private: // modification:      bool push(const Sphere& ball);      inline void pop();      bool is_spanning();    private: // utility:      inline bool find_radius(const Tag_false is_exact);      inline bool find_radius(const Tag_true is_exact);    private: // traits class:      Traits& t;    private: // for internal consisteny checks:      #ifdef CGAL_MINIBALL_DEBUG      // The following variable is true if and only if no ball has been      // pushed so far, or is_spanning() has been called at least once and      // neither pop() nor push() have been called since last is_spanning().      bool is_spanning_was_called;      #endif    private: // member fields:      int m;                    // number of pushed balls      const Sphere *b[D+1];     // pointers to pushed balls      Result center[D+1];       // contains, when is_spanning() returns true,                                // the center of the miniball      // variables of the device:      FT u[D+1][D];      FT d[D+1][D];      FT e[D+1][D];      FT f[D+1][D];      FT alpha[D+1];      FT delta[D+1];      FT eps[D+1];      FT phi[D+1];      FT sigma[D+1];      FT chi[D+1];      FT psi[D+1];      FT omega[D+1];      FT tau[D][D+1];      Result sol[D+2];      FT discrim[D+2];      FT maxradius[D+1];    };    template<class Traits>    Support_set<Traits>::Support_set(Traits& traits) : t(traits) {      reset();    }    template<class Traits>    void Support_set<Traits>::reset() {      m = 0;      sol[0] = FT(-1);      discrim[0] = FT(0);      CGAL_MINIBALL_DO_DEBUG(is_spanning_was_called = true);    }    template<class Traits>    const typename Support_set<Traits>::Result&      Support_set<Traits>::radius() const {      CGAL_MINIBALL_ASSERT(is_spanning_was_called);      return sol[m];    }    template<class Traits>    const typename Support_set<Traits>::Result      *Support_set<Traits>::begin() const {      CGAL_MINIBALL_ASSERT(is_spanning_was_called);      return center;    }    template<class Traits>    const typename Support_set<Traits>::FT&      Support_set<Traits>::disc() const {      CGAL_MINIBALL_ASSERT(is_spanning_was_called);      return discrim[m];    }    template<class Traits>    void Support_set<Traits>::pop() {      CGAL_MINIBALL_ASSERT(m>0);      CGAL_MINIBALL_DO_DEBUG(is_spanning_was_called = false);      --m;    }    template<class Traits>    bool Support_set<Traits>::find_radius(const Tag_false /* is_exact */) {      using namespace Min_sphere_of_spheres_d_impl;      // find discriminant:      discrim[m+1] = sqr(psi[m]) - 4*chi[m]*omega[m];      if (discrim[m+1] < Min_float)        return false;      // handle degenerate quadratic:      if (std::abs(chi[m]) < Min_float) {        if (std::abs(psi[m]) < Min_float)          return false;        sol[m+1] = -omega[m]/psi[m];        return sol[m+1]*Tol >= maxradius[m];      }      // calculate the two solutions:      FT sd = std::sqrt(discrim[m+1]);      if (psi[m] > 0)        sd = -sd;      Result sols[2] = { (sd-psi[m])     / (FT(2)*chi[m]),                          FT(2)*omega[m] / (sd-psi[m]) };      // order the solutions (*):      if (sols[1] < sols[0])        std::swap(sols[0],sols[1]);      // eliminate negative solutions:      if (sols[0]*Tol >= maxradius[m]) {        sol[m+1] = sols[0];        return true;      }      sol[m+1] = sols[1];      return sol[m+1]*Tol >= maxradius[m];    }    template<class Traits>    bool Support_set<Traits>::find_radius(const Tag_true /* is_exact */) {      // find discriminant:      discrim[m+1] = sqr(psi[m]) - FT(4)*chi[m]*omega[m];      if (discrim[m+1] < FT(0))        return false;      // handle degenerate quadratic:      if (chi[m] == FT(0)) {        if (psi[m] == FT(0))          return false;        sol[m+1] = Pair<FT>(-omega[m]/psi[m],FT(0));        return sol[m+1].first >= maxradius[m];      }      // calculate the two solutions:      const FT tmp = FT(-1)/(FT(2)*chi[m]);      Result sols[2] = {        Pair<FT>(psi[m]*tmp, tmp),        Pair<FT>(psi[m]*tmp,-tmp)      };      // order the solutions (*):      if (chi[m] < FT(0))        std::swap(sols[0],sols[1]);      CGAL_MINIBALL_ASSERT(is_neg_or_zero(sols[0]-sols[1],discrim[m+1]));      // eliminate negative solutions:      if (!is_neg(sols[0]-maxradius[m],discrim[m+1])) {        sol[m+1] = sols[0];        return true;      }      sol[m+1] = sols[1];      return !is_neg(sols[1]-maxradius[m],discrim[m+1]);    }  } // namespace Min_sphere_of_spheres_d_impl} // namespace CGAL_MINIBALL_NAMESPACE#include <CGAL/Min_sphere_of_spheres_d/Min_sphere_of_spheres_d_support_set_impl.h>#endif // CGAL_MINIBALL_SUPPORTSET

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -