conic_arc_2_core.h
来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 2,297 行 · 第 1/5 页
H
2,297 行
// Return only the points that are contained in the arc interior. int m = 0; for (int i = 0; i < n; i++) { if (is_full_conic() || _is_strictly_between_endpoints(ps[i])) { vpts[m] = ps[i]; m++; } } // Return the number of vertical tangency points found. return (m); } /*! * Calculate the horizontal tangency points of the arc. * \param hpts The horizontal tangency points -- should be allocated at the * size of 2). * \return The number of horizontal tangency points. */ int horizontal_tangency_points (Point_2* hpts) const { // No horizontal tangency points for segments: if ((_info & DEGREE_MASK) < 2) return (0); // Calculate the horizontal tangency points of the conic. Point_2 ps[2]; int n; n = _conic_horizontal_tangency_points (ps); // Return only the points that are contained in the arc interior. int m = 0; for (int i = 0; i < n; i++) { if (is_full_conic() || _is_strictly_between_endpoints(ps[i])) { hpts[m] = ps[i]; m++; } } // Return the number of horizontal tangency points found. return (m); } /*! * Check whether the arc is x-monotone. * \return (true) if the arc is x-monotone. */ bool is_x_monotone() const { // If the answer is pre-calculated (and stored in the _info field), just // return it: int is_x_mon = _info & X_MON_UNDEFINED; if (is_x_mon == 0) return (false); else if (is_x_mon == X_MONOTONE) return (true); // Check the number of vertical tangency points. Point_2 vpts[2]; return (vertical_tangency_points(vpts) == 0); } /*! * Find all points on the arc with a given x-coordinate. * \param p A placeholder for the x-coordinate. * \param ps The point on the arc at x(p) -- should be allocated at the * size of 2. * \return The number of points found. */ int get_points_at_x (const Point_2& p, Point_2 *ps) const { // Get the y coordinates of the points on the conic. CoNT ys[2]; int n; n = _conic_get_y_coordinates (p.x(), ys); // Find all the points that are contained in the arc. int m = 0; for (int i = 0; i < n; i++) { ps[m] = Point_2 (p.x(), ys[i], _conic_id); if (is_full_conic() || _is_between_endpoints(ps[m])) m++; } // Return the number of points on the arc. return (m); } /*! * Find all points on the arc with a given y-coordinate. * \param p A placeholder for the y-coordinate. * \param ps The point on the arc at y(p) -- should be allocated at the * size of 2. * \return The number of points found. */ int get_points_at_y (const Point_2& p, Point_2 *ps) const { // Get the y coordinates of the points on the conic. CoNT xs[2]; int n; n = _conic_get_x_coordinates (p.y(), xs); // Find all the points that are contained in the arc. int m = 0; for (int i = 0; i < n; i++) { ps[m] = Point_2 (xs[i], p.y(), _conic_id); if (is_full_conic() || _is_between_endpoints(ps[m])) m++; } // Return the number of points on the arc. return (m); } /*! * Flip the conic arc: change its orientation and swap it source and target. * \return The flipped arc. */ Self flip () const { // Create a base conic with opposite orientation: Self opp_arc; opp_arc._r = -r; opp_arc._s = -s; opp_arc._t = -t; opp_arc._u = -u; opp_arc._v = -v; opp_arc._w = -w; if (_orient == CGAL::COUNTERCLOCKWISE) opp_arc._orient = CGAL::CLOCKWISE; else if (_orient == CGAL::CLOCKWISE) opp_arc._orient = CGAL::COUNTERCLOCKWISE; else opp_arc._orient = _orient; // Linear arc (a segment). opp_arc._conic_id = _conic_id; // Exchange the source and the target. opp_arc._source = _target; opp_arc._target = _source; opp_arc._info = _info; // These properties do not change. if ((_info & IS_HYPERBOLA) != 0) { opp_arc._data.hyper_P = new Hyperbolic_arc_data (*_data.hyper_P); } else if ((_info & IS_CIRCLE) != 0) { opp_arc._data.circ_P = new Circular_arc_data (*_data.circ_P); } else { opp_arc._data.hyper_P = NULL; } return (opp_arc); } /*! RWRW - Allow higher order derivatives. * Get the i'th order derivative by x of the conic at the point p=(x,y). * \param p The point where we derive. * \param i The order of the derivatives (either 1 or 2). * \param slope_numer The numerator of the slope. * \param slope_denom The denominator of the slope. * \pre i should be either 1 (first order) or 2 (second order). */ void derive_by_x_at (const Point_2& p, const int& i, CoNT& slope_numer, CoNT& slope_denom) const { // Make sure i is either 1 or 2. CGAL_precondition(i == 1 || i == 2); // Make sure p is contained in the arc. CGAL_precondition(contains_point(p)); // The derivative by x of the conic // C: {r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0} // at the point p=(x,y) is given by: // // 2r*x + t*y + u alpha // y' = - ---------------- = - ------- // 2s*y + t*x + v beta // const CoNT _two = 2; const CoNT sl_numer = _two*CoNT(_r)*p.x() + CoNT(_t)*p.y() + CoNT(_u); const CoNT sl_denom = _two*CoNT(_s)*p.y() + CoNT(_t)*p.x() + CoNT(_v); if (i == 1) { if (sl_denom > 0) { slope_numer = -sl_numer; slope_denom = sl_denom; } else { slope_numer = sl_numer; slope_denom = -sl_denom; } return; } // The second derivative is given by: // // s*alpha^2 - t*alpha*beta + r*beta^2 // y'' = -2 ------------------------------------- // beta^3 // const CoNT sl2_numer = CoNT(_s) * sl_numer * sl_numer - CoNT(_t) * sl_numer * sl_denom + CoNT(_r) * sl_denom * sl_denom; const CoNT sl2_denom = sl_denom * sl_denom * sl_denom; if (sl_denom > 0) // so sl2_denom > 0 as well ... { slope_numer = -_two *sl2_numer; slope_denom = sl2_denom; } else { slope_numer = _two *sl2_numer; slope_denom = -sl2_denom; } return; } /*! RWRW - Allow higher order derivatives. * Get the i'th order derivative by y of the conic at the point p=(x,y). * \param p The point where we derive. * \param i The order of the derivatives (either 1 or 2). * \param slope_numer The numerator of the slope. * \param slope_denom The denominator of the slope. * \pre i should be either 1 (first order) or 2 (second order). */ void derive_by_y_at (const Point_2& p, const int& i, CoNT& slope_numer, CoNT& slope_denom) const { // Make sure i is either 1 or 2. CGAL_precondition(i == 1 || i == 2); // Make sure p is contained in the arc. CGAL_precondition(contains_point(p)); // The derivative by y of the conic // C: {r*x^2 + s*y^2 + t*xy + u*x + v*y + w = 0} // at the point p=(x,y) is given by: // // 2s*y + t*x + v alpha // x' = - ---------------- = ------- // 2r*x + t*y + u beta // const CoNT _two = 2; const CoNT sl_numer = _two*CoNT(_s)*p.y() + CoNT(_t)*p.x() + CoNT(_v); const CoNT sl_denom = _two*CoNT(_r)*p.x() + CoNT(_t)*p.y() + CoNT(_u); if (i == 1) { if (sl_denom > 0) { slope_numer = -sl_numer; slope_denom = sl_denom; } else { slope_numer = sl_numer; slope_denom = -sl_denom; } return; } // The second derivative is given by: // // r*alpha^2 - t*alpha*beta + s*beta^2 // x'' = -2 ------------------------------------- // beta^3 // const CoNT sl2_numer = CoNT(_r) * sl_numer * sl_numer - CoNT(_t) * sl_numer * sl_denom + CoNT(_s) * sl_denom * sl_denom; const CoNT sl2_denom = sl_denom * sl_denom * sl_denom; if (sl_denom > 0) // so sl2_denom > 0 as well ... { slope_numer = -_two *sl2_numer; slope_denom = sl2_denom; } else { slope_numer = _two *sl2_numer; slope_denom = -sl2_denom; } return; } /*! * Calculate the intersection points with the given arc. * \param arc The arc to intersect. * \param ps The output intersection points. * This area must be allocated at the size of 4. * \param inter_list_P For caching purposes. * \pre The tow arcs do not lie on the same conic. * \return The number of the actual intersection points. */ int intersections_with (const Self& arc, Point_2* ps#ifdef CGAL_CONIC_ARC_USE_CACHING ,std::list<Intersections> *inter_list_P = NULL#endif ) const { // The two conics must not be the same. CGAL_precondition (! has_same_base_conic(arc)); // First make sure that (this->degree) is >= than (arc.degree). if ((arc._info & DEGREE_MASK) == DEGREE_2 && (_info & DEGREE_MASK) == DEGREE_1) { return (arc.intersections_with (*this, ps#ifdef CGAL_CONIC_ARC_USE_CACHING ,inter_list_P#endif )); } // Deal with vertical segments. if (arc.is_vertical_segment()) { if (is_vertical_segment()) { // Two vertical segments intersect only if they overlap. return (0); } // Find all points on our arc that have the same x coordinate as // the other vertical segment. int n_ys; Point_2 xps[2]; int j; int n = 0; n_ys = get_points_at_x (arc._source, xps); for (j = 0; j < n_ys; j++) { // Store this point only if it is contained on the other arc. if (arc.contains_point(xps[j])) { ps[n] = Point_2 (xps[j].x(), xps[j].y(), _conic_id, arc._conic_id); n++; } } return (n); } else if (is_vertical_segment()) { // Find all points on the other arc that have the same x coordinate as // our vertical segment. int n_ys; Point_2 xps[2]; int j; int n = 0; n_ys = arc.get_points_at_x (_source, xps); for (j = 0; j < n_ys; j++) { // Store this point only if it is contained on the other arc. if (contains_point(xps[j])) { ps[n] = Point_2 (xps[j].x(), xps[j].y(), _conic_id, arc._conic_id); n++; } } return (n); } // Find all intersection points between the two base conic curves. Point_2 ipts[4]; // The intersection points. int n_points = 0; // Their number. bool calc_points = true;#ifdef CGAL_CONIC_ARC_USE_CACHING Intersections inter; int k; if (inter_list_P != NULL && (_info & DEGREE_MASK) != DEGREE_1) { int id1 = _conic_id; int id2 = arc._conic_id; inter.id1 = id1 < id2 ? id1 : id2; inter.id2 = id1 > id2 ? id1 : id2; typename std::list<Intersections>::iterator iter; for (iter = inter_list_P->begin(); iter != inter_list_P->end(); iter++) { if ((*iter).id1 == inter.id1 && (*iter).id2 == inter.id2) { n_points = (*iter).n_points; for (k = 0; k < n_points; k++) ipts[k] = (*iter).ps[k]; calc_points = false; } } }#endif // (of ifdef CGAL_CONIC_ARC_USE_CACHING) if (calc_points) { // Find all potential x coordinates and y coordinates of the // intersection points. const CfNT _zero = 0; 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. if (_s == _zero && arc._s != _zero) { n_xs = arc._x_coordinates_of_intersections_with (*this, xs); } else { n_xs = _x_coordinates_of_intersections_with (arc, xs);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?