conic_arc_2_core.h

来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 2,297 行 · 第 1/5 页

H
2,297
字号
// Copyright (c) 1999  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.//// $Source: /CVSROOT/CGAL/Packages/Arrangement/include/CGAL/Arrangement_2/Conic_arc_2_core.h,v $// $Revision: 1.2 $ $Date: 2004/05/27 11:52:28 $// $Name:  $//// Author(s)     : Ron Wein <wein@post.tau.ac.il>#ifndef CGAL_CONIC_ARC_2_CORE_H#define CGAL_CONIC_ARC_2_CORE_H#include <CGAL/Cartesian.h>#include <CGAL/Point_2.h>#include <CGAL/Conic_2.h>#include <CGAL/predicates_on_points_2.h>#include <CGAL/Bbox_2.h>#include <CGAL/Arrangement_2/Conic_arc_2_eq_core.h>#include <list>#include <ostream>#define CGAL_CONIC_ARC_USE_CACHINGCGAL_BEGIN_NAMESPACE/*! * A class that stores additional information with the point's coordinates: * Namely the conic IDs of the generating curves. */template <class Kernel_>class Point_ex_2 : public Kernel_::Point_2{public:  typedef Kernel_                       Kernel;  typedef typename Kernel::Point_2      Base;  typedef Point_ex_2<Kernel>            Self;      typedef typename Kernel::FT           CoNT; private:  int    _id1;       // The ID of the first generating conic (or 0).  int    _id2;       // The ID of the second generating conic (or 0). public:  // Constructors.  Point_ex_2 () :    Base(),    _id1(0),    _id2(0)  {}  Point_ex_2 (const CoNT& hx, const CoNT& hy, const CoNT& hz) :    Base(hx,hy,hz),    _id1(0),    _id2(0)  {}  Point_ex_2 (const CoNT& hx, const CoNT& hy,	      const int& id1 = 0, const int& id2 = 0) :    Base(hx,hy),    _id1(id1),    _id2(id2)  {}  Point_ex_2 (const Base& p) :    Base(p),    _id1(0),    _id2(0)  {}  Point_ex_2 (const Base& p,	      const int& id1, const int& id2 = 0) :    Base(p),    _id1(id1),    _id2(id2)  {}  // Set the generating conic IDs.  void set_generating_conics (const int& id1,			      const int& id2 = 0)  {    _id1 = id1;    _id2 = id2;    return;  }  // Check if the given conic generates the point.  bool is_generating_conic_id (const int& id) const  {    return (id != 0 &&	    (id == _id1 || id == _id2));  }  // Check whether two points are equal.  bool equals (const Self& p) const  {    // If the two points are the same:    if (this == &p)      return (true);    // Use the parent's equality operator.    return ((*this) == p);  }    // Compare the x coordinates.  Comparison_result compare_x (const Self& p) const  {    return (CGAL_NTS compare(x(), p.x()));  }  // Compare the y coordinates.  Comparison_result compare_y (const Self& p) const  {    return (CGAL_NTS compare(y(), p.y()));  }  // Compare two points lexicographically.  Comparison_result compare_lex_xy (const Self& p) const  {    Comparison_result   res = this->compare_x (p);    if (res != EQUAL)      return (res);        return (this->compare_y (p));  }};/*! * Representation of a conic arc -- a bounded segment that lies on a conic * curve, the loci of all points satisfying the equation: *   r*x^2 + s*y^2 + t*xy + u*x + v*y +w = 0 * * The class is templated with two parameters:  * CfNT_ is a number type for representing the conic coefficients (integers). * Kernel_ is a geometric kernel, where Kernel_::FT is the number type for the * coordinates of points (which are algebraic numbers). */static int _conics_count = 0;template <class CfNT_, class Kernel_> class Arr_conic_traits_2;template <class CfNT_, class Kernel_>class Conic_arc_2{protected:  typedef Conic_arc_2<CfNT_, Kernel_>  Self;        public:  typedef CfNT_                        CfNT;  typedef Kernel_                      Kernel;  typedef typename Kernel::FT          CoNT;      typedef Point_ex_2<Kernel>           Point_2;  typedef Segment_2<Kernel>            Segment_2;  typedef Circle_2<Kernel>             Circle_2;   protected:  friend class Arr_conic_traits_2<CfNT, Kernel>;  enum  {    DEGREE_0 = 0,    DEGREE_1 = 1,    DEGREE_2 = 2,    DEGREE_MASK = 1 + 2,    FULL_CONIC = 4,    X_MONOTONE = 8,    X_MON_UNDEFINED = 8 + 16,    FACING_UP = 32,    FACING_DOWN = 64,    FACING_MASK = 32 + 64,    IS_CIRCLE = 128,    IS_HYPERBOLA = 256  };  CfNT     _r;              //  CfNT     _s;              // The coefficeint of the underlying conic curve:  CfNT     _t;              //  CfNT     _u;              //  CfNT     _v;              // r*x^2 + s*y^2 + t*xy + u*x + v*y +w = 0  CfNT     _w;              //  Orientation _orient;      // The orientation of the conic.  int         _conic_id;    // The id of the conic.  Point_2     _source;      // The source of the arc.   Point_2     _target;      // The target of the arc.  int         _info;        // A bit array with extra information:                            // Bit 0 & 1 - The degree of the conic                             //             (either 1 or 2).                            // Bit 2     - Whether the arc is a full conic.                            // Bit 3 & 4 - Whether the arc is x-monotone                            //             (00, 01 or 11 - undefined).                            // Bit 5 & 6 - Indicate whether the arc is                            //             facing upwards or downwards (for                            //             x-monotone curves of degree 2).                            // Bit 7     - Is the underlying curve a circle.                            // Bit 8     - Is the underlying curve a hyperbola.  // For arcs whose base is a hyperbola we store the axis (a*x + b*y + c = 0)  // which separates the two bracnes of the hyperbola. We also store the side  // (-1 or 1) that the arc occupies.  struct Hyperbolic_arc_data  {    CoNT     a;    CoNT     b;    CoNT     c;    int      side;  };  // In case of a circle, is is convinient to store its center and radius.  struct Circular_arc_data  {    CoNT       x0;    CoNT       y0;    CoNT       r;  };#ifdef CGAL_CONIC_ARC_USE_CACHING  struct Intersections  {    int     id1;    int     id2;    int     n_points;    Point_2 ps[4];  };#endif  union  {    Hyperbolic_arc_data *hyper_P;    Circular_arc_data   *circ_P;  } _data;  // Produce a unique id for a new conic.   int _get_new_conic_id ()  {    _conics_count++;    return (_conics_count);  }  /*!   * Protected constructor: Construct an arc which is a segment of the given   * conic arc, with a new source and target points.   * \param The copied arc.   * \param source The new source point.   * \param target The new target point.   */  Conic_arc_2 (const Self & arc,	       const Point_2& source, const Point_2 & target) :    _r(arc._r), _s(arc._s), _t(arc._t), _u(arc._u), _v(arc._v), _w(arc._w),    _orient(arc._orient),    _conic_id(arc._conic_id),    _source(source),    _target(target)  {    _info = (arc._info & DEGREE_MASK) |       X_MON_UNDEFINED;    // Check whether the conic is x-monotone.    if (is_x_monotone())    {      _info = (_info & ~X_MON_UNDEFINED) | X_MONOTONE;      // Check whether the facing information is set for the orginating arc.      // If it is, just copy it - otherwise calculate it if the degree is 2.      Comparison_result facing_res = arc.facing();      if (facing_res != EQUAL)	_info = _info | (facing_res == LARGER ? FACING_UP : FACING_DOWN);      else if ((_info & DEGREE_MASK) == DEGREE_2)	_set_facing();    }    else    {      _info = (_info & ~X_MON_UNDEFINED);    }    // Copy the hyperbolic or circular data, if necessary.    if ((arc._info & IS_HYPERBOLA) != 0)    {      _info = _info | IS_HYPERBOLA;      _data.hyper_P = new Hyperbolic_arc_data (*(arc._data.hyper_P));    }    else if ((arc._info & IS_CIRCLE) != 0)    {      _info = _info | IS_CIRCLE;      _data.circ_P = new Circular_arc_data (*(arc._data.circ_P));    }    else    {      _data.hyper_P = NULL;    }  } public:  /*!   * Default constructor.   */  Conic_arc_2 () :    _r(0), _s(0), _t(0), _u(0), _v(0), _w(0),    _orient(CGAL::COLLINEAR),    _conic_id(0),    _info(X_MON_UNDEFINED)  {    _data.hyper_P = NULL;  }  /*!   * Copy constructor.   * \param arc The copied arc.   */  Conic_arc_2 (const Self & arc) :    _r(arc._r), _s(arc._s), _t(arc._t), _u(arc._u), _v(arc._v), _w(arc._w),    _orient(arc._orient),    _conic_id(arc._conic_id),    _source(arc._source),    _target(arc._target),    _info(arc._info)  {    // Copy the hyperbolic or circular data, if necessary.    if ((arc._info & IS_HYPERBOLA) != 0)    {      _data.hyper_P = new Hyperbolic_arc_data (*(arc._data.hyper_P));    }    else if ((arc._info & IS_CIRCLE) != 0)    {      _data.circ_P = new Circular_arc_data (*(arc._data.circ_P));    }    else    {      _data.hyper_P = NULL;    }  }  /*!    * Construct a conic arc which lies on the conic:   *   C: r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0   * \param orient The orientation of the arc (clockwise or couterclockwise).   * \param source The source point.   * \param target The target point.   * \pre The source and the target must be on the conic boundary and must   * not be the same.   */  Conic_arc_2 (const CfNT& r, const CfNT& s, const CfNT& t,	       const CfNT& u, const CfNT& v, const CfNT& w,	       const Orientation& orient,	       const Point_2& source, const Point_2& target) :    _r(r), _s(s), _t(t), _u(u), _v(v), _w(w),    _source(source),    _target(target),    _info(X_MON_UNDEFINED)  {    // Make sure the conic contains the two end-points on its boundary.    CGAL_precondition(_conic_has_on_boundary(source));    CGAL_precondition(_conic_has_on_boundary(target));    // Make sure that the source and the taget are not the same.    CGAL_precondition(source != target);          // Set the arc properties (no need to compute the orientation).    _orient = orient;    _set (false);  }  /*!    * Construct a conic arc which is the full conic:   *   C: r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0   * \pre The conic C must be an ellipse (so 4rs - t^2 > 0).   */  Conic_arc_2 (const CfNT& r, const CfNT& s, const CfNT& t,	       const CfNT& u, const CfNT& v, const CfNT& w) :    _r(r), _s(s), _t(t), _u(u), _v(v), _w(w)  {    // Make sure the given curve is an ellipse.    CGAL_precondition(CGAL_NTS compare(4*r*s - t*t, CfNT(0)) == LARGER);            // Set the arc to be the full conic (and compute the orientation).    _set_full (true);  }  /*!   * Construct a conic arc from the given line segment, specified by its   * end-points (x1,y1) and (x2, y2).   */  Conic_arc_2 (const CfNT& x1, const CfNT& y1,	       const CfNT& x2, const CfNT& y2) :    _source(CoNT(x1),CoNT(y1)),    _target(CoNT(x2),CoNT(y2))  {    const CfNT _zero = 0;    const CfNT _one = 1;    // Make sure that the source and the taget are not the same.    CGAL_precondition(_source != _target);          // The supporting conic is r=s=t=0, and u*x + v*y + w = 0 should hold    // for both the source (x1,y1) and the target (x2, y2).    if (CGAL_NTS compare (x1, x2) == EQUAL)    {      // The supporting conic is a vertical line, of the form x = CONST.      _r = _zero;    _s = _zero;    _t =  _zero;      _u = _one;      _v = _zero;      _w = -x1;    }    else    {      // The supporting line is A*x + B*y + C = 0, where:      //      //  A = y2 - y1,    B = x1 - x2,    C = x2*y1 - x1*y2       //      _r = _zero;    _s = _zero;    _t =  _zero;      _u = y2 - y1;      _v = x1 - x2;      _w = x2*y1 - x1*y2;    }    // The orientation is zero in case of a linear object.    _orient = CGAL::COLLINEAR;    // Set the arc properties (no need to compute the orientation).    _set (false);  }  /*!   * Set a circular arc that lies on the given circle:   *   C: (x - x0)^2 + (y - y0)^2 = R^2   * \param orient The orientation of the circle.   * \param source The source point.   * \param target The target point.   * \pre The source and the target must be on the conic boundary and must   * not be the same.   */    Conic_arc_2 (const CfNT& x0, const CfNT& y0,	       const CfNT& R,	       const Orientation& orient,	       const Point_2& source, const Point_2& target) :    _source(source),    _target(target),    _info(X_MON_UNDEFINED)

⌨️ 快捷键说明

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