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

📄 bezier_cache.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 2006  Tel-Aviv University (Israel).// 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/Arrangement_2/include/CGAL/Arr_traits_2/Bezier_cache.h $// $Id: Bezier_cache.h 37177 2007-03-17 08:48:10Z afabri $// //// Author(s)     : Ron Wein     <wein@post.tau.ac.il>#ifndef CGAL_BEZIER_CACHE_H#define CGAL_BEZIER_CACHE_H/*! \file * Header file for the _Bezier_cache class. */#include <set>#include <map>#include <ostream>CGAL_BEGIN_NAMESPACE/*! \class _Bezier_cache * Stores all cached intersection points and vertical tangency points. */template <class Nt_traits_> class _Bezier_cache{public:  typedef Nt_traits_                              Nt_traits;  typedef typename Nt_traits::Integer             Integer;  typedef typename Nt_traits::Polynomial          Polynomial;  typedef typename Nt_traits::Algebraic           Algebraic;  typedef _Bezier_cache<Nt_traits>                Self;  /// \name Type definitions for the vertical tangency-point mapping.  //@{  typedef size_t                                     Curve_id;  typedef std::list<Algebraic>                       Vertical_tangency_list;  typedef    typename Vertical_tangency_list::const_iterator  Vertical_tangency_iter;  //@}  /// \name Type definitions for the intersection-point mapping.  //@{  /*! \struct Intersection_point_2   * Representation of an intersection point (in both parameter and physical   * spaces).   */  struct Intersection_point_2  {    Algebraic          s;      // The parameter for the first curve.    Algebraic          t;      // The parameter for the second curve.    Algebraic          x;      // The x-coordinate.    Algebraic          y;      // The y-coordinate.    /*! Constructor. */    Intersection_point_2 (const Algebraic& _s, const Algebraic& _t,                          const Algebraic& _x, const Algebraic& _y) :      s(_s), t(_t),      x(_x), y(_y)    {}  };  typedef std::pair<Curve_id, Curve_id>              Curve_pair;  typedef std::pair<Algebraic, Algebraic>            Parameter_pair;  typedef std::list<Intersection_point_2>            Intersection_list;  typedef    typename Intersection_list::const_iterator       Intersection_iter;private:  typedef std::map<Curve_id,                   Vertical_tangency_list>           Vert_tang_map;  typedef typename Vert_tang_map::value_type         Vert_tang_map_entry;  typedef typename Vert_tang_map::iterator           Vert_tang_map_iterator;  /*! \struct Less_curve_pair   * An auxiliary functor for comparing pair of curve IDs.   */  struct Less_curve_pair  {    bool operator() (const Curve_pair& cp1, const Curve_pair& cp2) const    {      // Compare the pairs of IDs lexicographically.      return (cp1.first < cp2.first ||              (cp1.first == cp2.first && cp1.second < cp2.second));    }  };  typedef std::list<Algebraic>                       Parameter_list;  typedef std::pair<Intersection_list, bool>         Intersection_info;  typedef std::map<Curve_pair,                   Intersection_info,                   Less_curve_pair>                  Intersect_map;  typedef typename Intersect_map::value_type         Intersect_map_entry;  typedef typename Intersect_map::iterator           Intersect_map_iterator;  /*! \struct My_point_2   * Representation of exact and approximate point coordinates.   */  struct My_point_2  {    typename Parameter_list::const_iterator  prm_it;    Algebraic                                x;    Algebraic                                y;    double                                   app_x;    double                                   app_y;    /*! Default constructor. */    My_point_2 () :      app_x (0),      app_y (0)    {}    /*! Constructor. */    My_point_2 (typename Parameter_list::const_iterator it,                const Algebraic& _x, const Algebraic& _y) :      prm_it (it),      x (_x),      y (_y),      app_x (CGAL::to_double(_x)),      app_y (CGAL::to_double(_y))    {}    /*! Get the parameter value. */    const Algebraic& parameter () const    {      return (*prm_it);    }    /*! Check if the given two points are equal. */    bool equals (const My_point_2& other) const    {      return (CGAL::compare (x, other.x) == EQUAL &&              CGAL::compare (y, other.y) == EQUAL);    }  };  /*! \struct Less_distance_iter   * An auxiliary functor for comparing approximate distances.   */  typedef std::list<My_point_2>                      Point_list;  typedef typename Point_list::iterator              Point_iter;  typedef std::pair<double, Point_iter>              Distance_iter;  struct Less_distance_iter  {    bool operator() (const Distance_iter& dit1,                     const Distance_iter& dit2) const    {      return (dit1.first < dit2.first);    }  };  // Data members:  Nt_traits         nt_traits;        /*! Number-type traits. */  Vert_tang_map     vert_tang_map;    /*! Maps curves to their vertical                                          tangency parameters. */  Intersect_map     intersect_map;    /*! Maps curve pairs to their                                          intersection parameter pairs. */  // Copy constructor and assignment operator - not supported.  _Bezier_cache (const Self& );  Self& operator= (const Self& );public:  /*! Constructor. */  _Bezier_cache ()  {}  /*!   * Get the vertical tangency parameters of a given curve (X(t), Y(t)).   * \param id The curve ID.   * \param polyX The coefficients of X(t).   * \param normX The normalizing factor of X(t).   * \return A list of parameters 0 < t_1 < ...< t_k < 1 such that X'(t_i) = 0.   */  const Vertical_tangency_list&  get_vertical_tangencies (const Curve_id& id,                           const Polynomial& polyX, const Integer& normX);  /*!   * Get the intersection parameters of two given curve (X_1(s), Y_1(s))   * and (X_2(t), Y_2(t)).   * \param id1 The ID of the first curve.   * \param polyX_1 The coefficients of X_1.   * \param normX_1 The normalizing factor of X_1.   * \param polyY_1 The coefficients of Y_1.   * \param normY_1 The normalizing factor of Y_1.   * \param id2 The ID of the second curve.   * \param polyX_2 The coefficients of X_2.   * \param normX_2 The normalizing factor of X_2.   * \param polyY_2 The coefficients of Y_2.   * \param normY_2 The normalizing factor of Y_2.   * \param do_ovlp Output: Do the two curves overlap.   * \pre id1 < id2 (swap their order if this is not the case).   * \return A list of parameter pairs (s_1, t_1), ..., (s_k, t_k) such that   *         X_1(s_i) = X_2(t_i) and Y_1(s_i) = Y_2(t_i).   *         Each pair is also associated with the physical point coordinates.   */  const Intersection_list&  get_intersections (const Curve_id& id1,                     const Polynomial& polyX_1, const Integer& normX_1,                     const Polynomial& polyY_1, const Integer& normY_1,                     const Curve_id& id2,                     const Polynomial& polyX_2, const Integer& normX_2,                     const Polynomial& polyY_2, const Integer& normY_2,                     bool& do_ovlp);private:  /*!   * Compute all parameter values of (X_1(s), Y_1(s)) with (X_2(t), Y_2(t)).   * \param polyX_1 The coefficients of X_1.   * \param normX_1 The normalizing factor of X_1.   * \param polyY_1 The coefficients of Y_1.   * \param normY_1 The normalizing factor of Y_1.   * \param polyX_2 The coefficients of X_2.   * \param normX_2 The normalizing factor of X_2.   * \param polyY_2 The coefficients of Y_2.   * \param normY_2 The normalizing factor of Y_2.   * \param s_vals Output: A list of s-values such that (X_1(s), Y_1(s))   *                       is an intersection point with (X_2(t), Y_2(t)).   *                       The list is given in ascending order.   *                       Note that the values are not bounded to [0,1].   * \return Do the two curves overlap (if they do, s_vals is empty).   */  bool _intersection_params (const Polynomial& polyX_1, const Integer& normX_1,                             const Polynomial& polyY_1, const Integer& normY_1,                             const Polynomial& polyX_2, const Integer& normX_2,                             const Polynomial& polyY_2, const Integer& normY_2,                             Parameter_list& s_vals) const;  /*!   * Compute the resultant of two bivariate polynomials in x and y with   * respect to y. The bivariate polynomials are given as vectors of   * polynomials, where bp1[i] is a coefficient of y^i, which is in turn a   * polynomial in x.   * \param bp1 The first bivariate polynomial.   * \param bp2 The second bivariate polynomial.   * \return The resultant polynomial (a polynomial in x).   */  Polynomial _compute_resultant (const std::vector<Polynomial>& bp1,                                 const std::vector<Polynomial>& bp2) const;};// ---------------------------------------------------------------------------// Get the vertical tangency parameters of a given curve (X(t), Y(t)).//template<class NtTraits>const typename _Bezier_cache<NtTraits>::Vertical_tangency_list&_Bezier_cache<NtTraits>::get_vertical_tangencies        (const Curve_id& id,         const Polynomial& polyX, const Integer& /* normX */){  // Try to find the curve ID in the map.  Vert_tang_map_iterator    map_iter = vert_tang_map.find (id);  if (map_iter != vert_tang_map.end())  {    // Found in the map: return the cached parameters' list.    return (map_iter->second);  }  // We need to compute the vertical tangency parameters: find all t-values  // such that X'(t) = 0, and store them in the cache.  Vertical_tangency_list&  vert_tang_list = vert_tang_map[id];  const Polynomial&        polyX_der = nt_traits.derive (polyX);    nt_traits.compute_polynomial_roots (polyX_der, 0, 1,                                      std::back_inserter(vert_tang_list));  return (vert_tang_list);}// ---------------------------------------------------------------------------// Get the intersection parameters of two given curve (X_1(s), Y_1(s))// and (X_2(t), Y_2(t)).//template<class NtTraits>const typename _Bezier_cache<NtTraits>::Intersection_list&_Bezier_cache<NtTraits>::get_intersections        (const Curve_id& id1,         const Polynomial& polyX_1, const Integer& normX_1,         const Polynomial& polyY_1, const Integer& normY_1,         const Curve_id& id2,         const Polynomial& polyX_2, const Integer& normX_2,         const Polynomial& polyY_2, const Integer& normY_2,         bool& do_ovlp){  CGAL_precondition (id1 < id2);  // Construct the pair of curve IDs, and try to find it in the map.  Curve_pair                curve_pair (id1, id2);  Intersect_map_iterator    map_iter = intersect_map.find (curve_pair);  if (map_iter != intersect_map.end())  {    // Found in the map: return the cached information.    do_ovlp = map_iter->second.second;    return (map_iter->second.first);  }  // We need to compute the intersection-parameter pairs.  Intersection_info&      info = intersect_map[curve_pair];  // Compute s-values and t-values such that (X_1(s), Y_1(s)) and  // (X_2(t), Y_2(t)) are the intersection points.  Parameter_list          s_vals;  do_ovlp = _intersection_params (polyX_1, normX_1, polyY_1, normY_1,                                  polyX_2, normX_2, polyY_2, normY_2,                                  s_vals);  if (do_ovlp)  {    // Update the cache and return an empty list of intersection parameters.    info.second = true;    return (info.first);  }  Parameter_list          t_vals;  do_ovlp = _intersection_params (polyX_2, normX_2, polyY_2, normY_2,                                  polyX_1, normX_1, polyY_1, normY_1,                                  t_vals);  CGAL_assertion (! do_ovlp);  // We should now have the same number of s-values and t-values, and we have  // to pair them together.   CGAL_assertion (s_vals.size() == s_vals.size());  // Compute all points on (X_1, Y_1) that match an s-value from the list.  typename Parameter_list::iterator  s_it;  const Algebraic&                   denX_1 = nt_traits.convert (normX_1);  const Algebraic&                   denY_1 = nt_traits.convert (normY_1);

⌨️ 快捷键说明

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