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

📄 exact_offset_base_2.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
// 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/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/Exact_offset_base_2.h $// $Id: Exact_offset_base_2.h 37897 2007-04-03 18:34:02Z efif $//// Author(s)     : Ron Wein   <wein@post.tau.ac.il>#ifndef CGAL_EXACT_OFFSET_BASE_H#define CGAL_EXACT_OFFSET_BASE_H#include <CGAL/Polygon_2.h>#include <CGAL/Gps_traits_2.h>#include <CGAL/Minkowski_sum_2/Labels.h>#include <CGAL/Minkowski_sum_2/Arr_labeled_traits_2.h>CGAL_BEGIN_NAMESPACE/*! \class * A base class for computing the offset of a given polygon by a given * radius in an exact manner. */template <class Traits_, class Container_>class Exact_offset_base_2{private:    typedef Traits_                                        Traits_2;    // Rational kernel types:  typedef typename Traits_2::Rat_kernel                  Rat_kernel;  typedef typename Rat_kernel::FT                        Rational;  typedef typename Rat_kernel::Point_2                   Rat_point_2;  typedef typename Rat_kernel::Line_2                    Rat_line_2;  typedef typename Rat_kernel::Circle_2                  Rat_circle_2;protected:  typedef Rat_kernel                                     Basic_kernel;  typedef Rational                                       Basic_NT;private:  // Algebraic kernel types:  typedef typename Traits_2::Alg_kernel                  Alg_kernel;  typedef typename Alg_kernel::FT                        Algebraic;  typedef typename Alg_kernel::Point_2                   Alg_point_2;  typedef typename Traits_2::Nt_traits                   Nt_traits;  // Traits-class types:  typedef typename Traits_2::Curve_2                     Curve_2;  typedef typename Traits_2::X_monotone_curve_2          X_monotone_curve_2;  typedef CGAL::Gps_traits_2<Traits_2>                   Gps_traits_2; protected:  typedef CGAL::Polygon_2<Rat_kernel, Container_>        Polygon_2;  typedef typename Gps_traits_2::Polygon_2               Offset_polygon_2;  private:  // Polygon-related types:  typedef typename Polygon_2::Vertex_circulator          Vertex_circulator;protected:  typedef Arr_labeled_traits_2<Traits_2>                 Labeled_traits_2;   typedef typename Labeled_traits_2::X_monotone_curve_2  Labeled_curve_2;public:  /*! Default constructor. */  Exact_offset_base_2 ()  {}    protected:  /*!   * Compute the curves that constitute the offset of a simple polygon by a   * given radius.   * \param pgn The polygon.   * \param r The offset radius.   * \param cycle_id The index of the cycle.   * \param oi An output iterator for the offset curves.   * \pre The value type of the output iterator is Labeled_curve_2.   * \return A past-the-end iterator for the holes container.   */  template <class OutputIterator>  OutputIterator _offset_polygon (const Polygon_2& pgn,                                  const Rational& r,                                  unsigned int cycle_id,                                  OutputIterator oi) const  {    // Prepare circulators over the polygon vertices.    const bool            forward = (pgn.orientation() == COUNTERCLOCKWISE);    Vertex_circulator     first, curr, next;        first = pgn.vertices_circulator();    curr = first;     next = first;    // Traverse the polygon vertices and edges and construct the arcs that    // constitute the single convolution cycle.    Alg_kernel                    alg_ker;    typename Alg_kernel::Equal_2  f_equal = alg_ker.equal_2_object();    Nt_traits       nt_traits;    const Rational  sqr_r = CGAL::square (r);    const Algebraic alg_r = nt_traits.convert (r);    Rational        x1, y1;              // The source of the current edge.    Rational        x2, y2;              // The target of the current edge.    Rational        delta_x, delta_y;    // (x2 - x1) and (y2 - y1), resp.    Algebraic       len;                 // The length of the current edge.    Algebraic       trans_x, trans_y;    // The translation vector.    Alg_point_2     op1, op2;            // The edge points of the offset edge.    Alg_point_2     first_op;            // The first offset point.    Algebraic       a, b, c;    unsigned int                    curve_index = 0;    Traits_2                        traits;    std::list<Object>               xobjs;    std::list<Object>::iterator     xobj_it;    typename Traits_2::Make_x_monotone_2                       f_make_x_monotone = traits.make_x_monotone_2_object();    Curve_2                         arc;    X_monotone_curve_2              xarc;    bool                            assign_success;    do    {      // Get a circulator for the next vertex (in counterclockwise      // orientation).      if (forward)	++next;      else	--next;      // Compute the vector v = (delta_x, delta_y) of the current edge,      // and compute the edge length ||v||.      x1 = curr->x();      y1 = curr->y();      x2 = next->x();      y2 = next->y();      delta_x = x2 - x1;      delta_y = y2 - y1;      len = nt_traits.sqrt (nt_traits.convert (CGAL::square (delta_x) +                                                CGAL::square (delta_y)));      // The angle theta between the vector v and the x-axis is given by:      //      //                 y2 - y1                        x2 - x1      //   sin(alpha) = ---------         cos(alpha) = ---------      //                  ||v||                          ||v||      //      // To offset the endpoints of the current edge we compute a vector      // (trans_x, trans_y) perpendicular to v. Since we traverse the polygon      // in a counterclockwise manner, the angle this vector forms with the      // x-axis is (alpha - PI/2), and we have:      //      //   trans_x = r*cos(alpha - PI/2) = r*sin(alpha)      //   trans_y = r*sin(alpha - PI/2) = -r*cos(alpha)      trans_x = nt_traits.convert (r * delta_y) / len;      trans_y = nt_traits.convert (-r * delta_x) / len;      // Construct the first offset vertex, which corresponds to the      // source vertex of the current polygon edge.      op1 = Alg_point_2 (nt_traits.convert (x1) + trans_x,                          nt_traits.convert (y1) + trans_y);      if (curr == first)      {	// This is the first edge we visit -- store op1 for future use.	first_op = op1;      }      else      {        if (! f_equal (op2, op1))        {          // Connect op2 (from the previous iteration) and op1 with a circular          // arc, whose supporting circle is (x1, x2) with radius r.          arc = Curve_2 (Rat_circle_2 (*curr, sqr_r),                         CGAL::COUNTERCLOCKWISE,                         op2, op1);                    // Subdivide the arc into x-monotone subarcs and append them to the          // convolution cycle.          xobjs.clear();          f_make_x_monotone (arc, std::back_inserter(xobjs));                    for (xobj_it = xobjs.begin(); xobj_it != xobjs.end(); ++xobj_it)          {            assign_success = CGAL::assign (xarc, *xobj_it);            CGAL_assertion (assign_success);            *oi = Labeled_curve_2 (xarc,                                   X_curve_label (xarc.is_directed_right(),                                                  cycle_id,                                                  curve_index));            ++oi;            curve_index++;          }        }      }      // Construct the second offset vertex, which corresponds to the      // target vertex of the current polygon edge.      op2 = Alg_point_2 (nt_traits.convert (x2) + trans_x,                          nt_traits.convert (y2) + trans_y);      // The equation of the line connecting op1 and op2 is given by:      //      //   (y1 - y2)*x + (x2 - x1)*y + (r*len - y1*x2 - x1*y2) = 0      //      a = nt_traits.convert (-delta_y);      b = nt_traits.convert (delta_x);      c = alg_r*len - nt_traits.convert (y1*x2 - x1*y2);      xarc = X_monotone_curve_2 (a, b, c,                                 op1, op2);      *oi = Labeled_curve_2 (xarc,                             X_curve_label (xarc.is_directed_right(),                                            cycle_id,                                            curve_index));      ++oi;      curve_index++;      // Proceed to the next polygon vertex.      curr = next;        } while (curr != first);    if (! f_equal (op2, first_op))    {      // Close the convolution cycle by creating the final circular arc,      // centered at the first vertex.      arc = Curve_2 (Rat_circle_2 (*first, sqr_r),                     CGAL::COUNTERCLOCKWISE,                     op2, first_op);            // Subdivide the arc into x-monotone subarcs and append them to the      // convolution cycle.      bool           is_last;            xobjs.clear();      f_make_x_monotone (arc, std::back_inserter(xobjs));            xobj_it = xobjs.begin();      while (xobj_it != xobjs.end())      {        assign_success = CGAL::assign (xarc, *xobj_it);        CGAL_assertion (assign_success);                ++xobj_it;        is_last = (xobj_it == xobjs.end());                *oi = Labeled_curve_2 (xarc,                               X_curve_label (xarc.is_directed_right(),                                              cycle_id,                                              curve_index,                                              is_last));        ++oi;        curve_index++;      }    }    return (oi);  }};CGAL_END_NAMESPACE#endif

⌨️ 快捷键说明

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