conic_arc_2.h

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

H
2,200
字号
    if (turn == LEFT_TURN)    {      _orient = CGAL::COUNTERCLOCKWISE;      same_turn = (orient_f(p1, p3, p5) == LEFT_TURN) &&                  (orient_f(p1, p4, p5) == LEFT_TURN);    }    else    {      _orient = CGAL::CLOCKWISE;      same_turn = (orient_f(p1, p3, p5) != LEFT_TURN) &&                  (orient_f(p1, p4, p5) != LEFT_TURN);    }    if (! same_turn)      // In this case, the arc is invalid.      return;    // Set the arc properties (no need to compute the orientation).    _set (false);    // Make sure that all midpoints are strictly between the    // source and the target.    bool      valid_midpoints = true;    Point_2   mp2 (CoNT(p2.x()), CoNT(p2.y()));    if (! _is_strictly_between_endpoints (mp2))    {      valid_midpoints = false;    }    else    {      Point_2   mp3 (CoNT(p3.x()), CoNT(p3.y()));      if (! _is_strictly_between_endpoints (mp3))      {        valid_midpoints = false;      }      else      {        Point_2   mp4 (CoNT(p4.x()), CoNT(p4.y()));        if (! _is_strictly_between_endpoints (mp4))          valid_midpoints = false;      }    }    // If the midpoints are not valid, mark the arc as invalid.    if (! valid_midpoints)      _info = (_info & ~IS_VALID);  }  // Construct a conic arc which lies on the conic:  //   C: r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0  // The source and the target are specified by the intersection of the  // conic with:  //   C_1: r_1*x^2 + s_1*y^2 + t_1*xy + u_1*x + v_1*y + w_1 = 0  //   C_2: r_2*x^2 + s_2*y^2 + t_2*xy + u_2*x + v_2*y + w_2 = 0  // The user must also specify the source and the target with approximated  // coordinates. The actual intersection points that best fits the source   // (or the target) will be selected.  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& app_source,               const CfNT& r_1, const CfNT& s_1, const CfNT& t_1,               const CfNT& u_1, const CfNT& v_1, const CfNT& w_1,               const Point_2& app_target,               const CfNT& r_2, const CfNT& s_2, const CfNT& t_2,               const CfNT& u_2, const CfNT& v_2, const CfNT& w_2) :    _r(r), _s(s), _t(t), _u(u), _v(v), _w(w),    _info(X_MON_UNDEFINED),    _hyper_P(NULL)  {    // Create the two auxiliary conic arcs.    Conic_arc_2    aux_s_arc, aux_t_arc;    aux_s_arc._r = r_1;       aux_t_arc._r = r_2;    aux_s_arc._s = s_1;       aux_t_arc._s = s_2;    aux_s_arc._t = t_1;       aux_t_arc._t = t_2;    aux_s_arc._u = u_1;       aux_t_arc._u = u_2;    aux_s_arc._v = v_1;       aux_t_arc._v = v_2;    aux_s_arc._w = w_1;       aux_t_arc._w = w_2;    // Compute the source and the target.    const CfNT _zero = 0;    int        my_info;    CoNT       xs[4];        // The x coordinates of intersection points.    int        n_xs;         // Number of x coordinates.    CoNT       ys[4];        // The y coordinates of intersection points.    int        n_ys;         // Number of y coordinates.    Point_2    ipts[4];      // The intersection points.    int        n_points;     // Their number.    CoNT       dist, best_dist;    int        ind, best_ind;    int        k;    if (CGAL_NTS compare(r, _zero) == EQUAL &&         CGAL_NTS compare(s, _zero) == EQUAL &&        CGAL_NTS compare(t, _zero) == EQUAL)    {      my_info = DEGREE_1;    }    else    {      my_info = DEGREE_2;    }    for (k = 0; k < 2; k++)    {      // Get the x- and y-coordinates of the intersection points with the      // first (if k == 0) or the second (if k == 1) auxiliary curves.      const Conic_arc_2& arc = (k == 0) ? aux_s_arc : aux_t_arc;      int         arc_info;      if (CGAL_NTS compare(arc._r, _zero) == EQUAL &&           CGAL_NTS compare(arc._s, _zero) == EQUAL &&          CGAL_NTS compare(arc._t, _zero) == EQUAL)      {        arc_info = DEGREE_1;      }      else      {        arc_info = DEGREE_2;      }      n_xs = _x_coordinates_of_intersection_points (_r, _s, _t, _u, _v, _w,                                                    my_info,                                                    arc._r, arc._s, arc._t,                                                     arc._u, arc._v, arc._w,                                                    arc_info,                                                    xs);            n_ys = _y_coordinates_of_intersection_points (_r, _s, _t, _u, _v, _w,                                                    my_info,                                                    arc._r, arc._s, arc._t,                                                     arc._u, arc._v, arc._w,                                                    arc_info,                                                    ys);      // Perform the pairing process of the x and y coordinates.      n_points = _pair_intersection_points (arc,                                            xs, n_xs,                                            ys, n_ys,                                            ipts);            if (n_points == 0)        // In this case, the arc is invalid.        return;      // Choose the intersection point closest to the source      // (or the target point).      const Point_2&  p = (k == 0) ? app_source : app_target;      best_ind = -1;      for (ind = 0; ind < n_points; ind++)      {        dist = CGAL::squared_distance (p, ipts[ind]);        if (best_ind < 0 || CGAL_NTS compare(best_dist, dist) == LARGER)        {          best_dist = dist;          best_ind = ind;        }      }      // Set the source (or the target).      if (k == 0)        _source = ipts[best_ind];      else        _target = ipts[best_ind];    }    // Make sure that the source and the taget are not the same.    if (_source == _target)      // In this case, the arc is invalid.      return;    // Set the prescribed orientation.    _orient = orient;        // Set the arc properties (no need to compute the orientation).    _set (false);  }  /*!   * Destructor.   */  virtual ~Conic_arc_2 ()  {    if (_hyper_P)      delete _hyper_P;    _hyper_P = NULL;  }  /*!   * Assignment operator.   * \param arc The copied arc.   */  const Self& operator= (const Self& arc)  {    if (this == &arc)      return (*this);    // Free any existing data.    if (_hyper_P != NULL)      delete _hyper_P;    _hyper_P = NULL;    // Copy the arc's attributes.    _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;    // Duplicate the data for hyperbolic arcs.    if (arc._hyper_P != NULL)      _hyper_P = new Hyperbolic_arc_data (*(arc._hyper_P));    return (*this);  }  /*!    * Get the coefficients of the underlying conic.   */  const CfNT& r () const {return (_r);}  const CfNT& s () const {return (_s);}  const CfNT& t () const {return (_t);}  const CfNT& u () const {return (_u);}  const CfNT& v () const {return (_v);}  const CfNT& w () const {return (_w);}  /*!   * Check if the arc is valid.   * \return Whether the arc is valid.   */  bool is_valid () const  {    return ((_info & IS_VALID) != 0);  }  /*!   * Get the arc's source.   * \return The source point.   */  const Point_2& source () const  {    return (_source);  }  /*!   * Get the arc's target.   * \return The target point.   */  const Point_2& target () const  {    return (_target);  }  /*!   * Get the arc's orientation.   * \return The orientation.   */  Orientation orientation () const  {    return (_orient);  }  /*!   * Check whether the two arcs are the same (have the same graph).   * \param arc The compared arc.   * \return (true) if the two arcs are equal.   */  bool equals (const Self& arc) const  {    // Check if (*this) and arc are really the same object:    if (this == &arc)      return (true);    // Check whether all arc features are the same.    if (_orient == arc._orient)    {      // Same orientation: The base conics must be the same and the sources      // and targets must be equal.      return (this->has_same_base_conic(arc) &&              _source.equals(arc._source) &&              _target.equals(arc._target));    }    else    {      // Opposite orientation: The base conics must be the same and the sources      // and targets must be flipped.      return (this->has_same_base_conic(arc) &&              _source.equals(arc._target) &&              _target.equals(arc._source));    }  }  /*!   * Check whether the two arcs have the same base conic.   * \param arc The compared arc.   * \return (true) if the two base conics are the same (have the same graph).   */  bool has_same_base_conic (const Self& arc) const  {    // In case the two arcs originiat from the same base conic:    if (_conic_id == arc._conic_id)      return (true);    // In case both arcs are collinear, check if they have the same    // supporting lines.    if (_orient == CGAL::COLLINEAR && arc._orient == CGAL::COLLINEAR)    {      // Construct the two supporting lines and compare them.      typename Alg_kernel::Line_2  l1 (_source, _target);      typename Alg_kernel::Line_2  l2 (arc._source, arc._target);      Alg_kernel                   ker;      typename Alg_kernel::Equal_2 equal_f = ker.equal_2_object();      if (equal_f (l1, l2))        return (true);            // Try to compare l1 with the opposite of l2.      typename Alg_kernel::Line_2  op_l2 (arc._target, arc._source);      return (equal_f (l1, op_l2));    }    // Check whether arc equals (*this) up to a constant factor.    const CfNT _zero = 0;    CfNT       factor1 = 1, factor2 = 1;    if (CGAL_NTS compare(_r, _zero) != EQUAL)      factor1 = _r;    else if (CGAL_NTS compare(_s, _zero) != EQUAL)      factor1 = _s;    else if (CGAL_NTS compare(_t, _zero) != EQUAL)      factor1 = _t;    else if (CGAL_NTS compare(_u, _zero) != EQUAL)      factor1 = _u;    else if (CGAL_NTS compare(_v, _zero) != EQUAL)      factor1 = _v;    else if (CGAL_NTS compare(_w, _zero) != EQUAL)      factor1 = _w;    if (CGAL_NTS compare(arc._r, _zero) != EQUAL)      factor2 = arc._r;    else if (CGAL_NTS compare(arc._s, _zero) != EQUAL)      factor2 = arc._s;    else if (CGAL_NTS compare(arc._t, _zero) != EQUAL)      factor2 = arc._t;    else if (CGAL_NTS compare(arc._u, _zero) != EQUAL)      factor2 = arc._u;    else if (CGAL_NTS compare(arc._v, _zero) != EQUAL)      factor2 = arc._v;    else if (CGAL_NTS compare(arc._w, _zero) != EQUAL)      factor2 = arc._w;    return (CGAL_NTS compare (_r * factor2, arc._r * factor1) == EQUAL &&             CGAL_NTS compare (_s * factor2, arc._s * factor1) == EQUAL &&            CGAL_NTS compare (_t * factor2, arc._t * factor1) == EQUAL &&            CGAL_NTS compare (_u * factor2, arc._u * factor1) == EQUAL &&            CGAL_NTS compare (_v * factor2, arc._v * factor1) == EQUAL &&            CGAL_NTS compare (_w * factor2, arc._w * factor1) == EQUAL);  }  /*!   * Check whether the arc is a full conic (i.e. a non-degenerate ellipse).   * \return (true) if the arc represents a full conic.   */  bool is_full_conic () const  {    return ((_info & FULL_CONIC) != 0);  }  /*!   * Check whether the arc is a circular arc.   * \return (true) if the underlying conic curve is a circle.   */  bool is_circular() const  {    return (CGAL_NTS compare(_r, _s) == EQUAL &&             CGAL_NTS compare(_t, 0) == EQUAL);  }    /*!   * Check whether the arc is a line segment.   * \return (true) if the underlying conic curve is linear.   */  bool is_segment () const  {    // Notice that the orientation is COLLINEAR if the underlying curve has    // a degree 1, or when it is a line-pair.    return (_orient == CGAL::COLLINEAR);  }  /*!   * Check whether the arc is a vertical segment.   * \return (true) if the arc is a vertical segment.   */  bool is_vertical_segment () const  {    return ((_info & IS_VERTICAL_SEGMENT) != 0);  }  /*!   * Get a bounding box for the conic arc.   * \return The bounding box.   */  Bbox_2 bbox () const  {    // Use the source and target to initialize the exterme points.    bool   source_left =       CGAL::to_double(_source.x()) < CGAL::to_double(_target.x());    double x_min = source_left ?      CGAL::to_double(_source.x()) : CGAL::to_double(_target.x());    double x_max = source_left ?      CGAL::to_double(_target.x()) : CGAL::to_double(_source.x());    bool   source_down =       CGAL::to_double(_source.y()) < CGAL::to_double(_target.y());    double y_min = source_down ?      CGAL::to_double(_source.y()) : CGAL::to_double(_target.y());    double y_max = source_down ?      CGAL::to_double(_target.y()) : CGAL::to_double(_source.y());    // Go over the vertical tangency points and try to update the x-points.    Point_2 tps[2];    int        n_tps;    int        i;    n_tps = vertical_tangency_points (tps);

⌨️ 快捷键说明

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