1:45 PM 11/12/2025 ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!
Warning: Undefined variable $authorization in C:\xampp\htdocs\demo\fi.php on line 57

Warning: Undefined variable $translation in C:\xampp\htdocs\demo\fi.php on line 118

Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\demo\fi.php on line 119

Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\demo\fi.php on line 120

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 247

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 248

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 249

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 250

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 251

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 252
// Copyright (c) 2006,2007,2009,2010,2011 Tel-Aviv University (Israel). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v6.1/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Bezier_curve_2.h $ // $Id: include/CGAL/Arr_geometry_traits/Bezier_curve_2.h b26b07a1242 $ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Ron Wein // Iddo Hanniel #ifndef CGAL_BEZIER_CURVE_2_H #define CGAL_BEZIER_CURVE_2_H #include /*! \file * Header file for the _Bezier_curve_2 class. */ #include #include #include #include #include #include #include #include #include namespace CGAL { /*! \class _Bezier_curve_2 * Representation of a Bezier curve, specified by (n+1) control points * p_0, ... , p_n that define the curve (X(t), Y(t)) for 0 <= t <= 1, * where X(t) and Y(t) are polynomials of degree n. * * The class is templated with three parameters: * Rat_kernel A geometric kernel, where Alg_kernel::FT is the number type * for the coordinates of control points (and subsequently also for * the polynomial coefficients). This number type must be the same * as Nt_traits::Rational. * Alg_kernel A geometric kernel, where Alg_kernel::FT is a number type * for representing algebraic numbers. This number type must be the * same as Nt_traits::Algebraic. * Nt_traits A traits class that defines the Integer, Rational and Algebraic * number-types, as well as the Polynomial class (a polynomial with * integer coefficients) and enables performing various operations * on objects of these types. * Bounding_traits A traits class for filtering the exact computations. */ // Forward declaration: template class _Bezier_curve_2; template class _Bezier_curve_2_rep { friend class _Bezier_curve_2; public: typedef RatKernel_ Rat_kernel; typedef AlgKernel_ Alg_kernel; typedef NtTraits_ Nt_traits; typedef BoundingTraits_ Bounding_traits; typedef typename Rat_kernel::Point_2 Rat_point_2; typedef typename Alg_kernel::Point_2 Alg_point_2; typedef typename Nt_traits::Integer Integer; typedef typename Nt_traits::Rational Rational; typedef typename Nt_traits::Algebraic Algebraic; typedef typename Nt_traits::Polynomial Polynomial; private: typedef std::deque Control_point_vec; Control_point_vec _ctrl_pts; /*!< The control points (we prefer deque to a vector, as it enables push_front()). */ Bbox_2 _bbox; /*!< A bounding box for the curve. */ bool _no_self_inter; /*!< Whether the curve surely has no self intersections. */ /// \name Lazily-evaluated values of the polynomials B(t) = (X(t), Y(t)). //@{ // X(t) is given by *p_polyX(t) / _normX: mutable Polynomial *p_polyX; // The polynomial for x. mutable Integer *p_normX; // Normalizing factor for y. // Y(t) is given by _polyY(t) / _normY: mutable Polynomial *p_polyY; // The polynomial for y. mutable Integer *p_normY; // Normalizing factor for y. //@} public: /*! constructs default. */ _Bezier_curve_2_rep () : _no_self_inter (true), p_polyX(nullptr), p_normX(nullptr), p_polyY(nullptr), p_normY(nullptr) {} /*! constructs copy (isn't really used). */ _Bezier_curve_2_rep (const _Bezier_curve_2_rep& other) : _ctrl_pts(other._ctrl_pts), _bbox(other._bbox), _no_self_inter(other._no_self_inter), p_polyX(nullptr), p_normX(nullptr), p_polyY(nullptr), p_normY(nullptr) { if (other.p_polyX != nullptr) p_polyX = new Polynomial(*(other.p_polyX)); if (other.p_polyY != nullptr) p_polyY = new Polynomial(*(other.p_polyY)); if (other.p_normX != nullptr) p_normX = new Integer(*(other.p_normX)); if (other.p_normY != nullptr) p_normY = new Integer(*(other.p_normY)); } /*! constructs from a given range of control points. * \param pts_begin An iterator pointing to the first point in the range. * \param pts_end A past-the-end iterator for the range. * \pre The value-type of the input iterator must be Rat_kernel::Point_2. * It is forbidden to specify two identical consecutive control points. */ template _Bezier_curve_2_rep (InputIterator pts_begin, InputIterator pts_end) : p_polyX(nullptr), p_normX(nullptr), p_polyY(nullptr), p_normY(nullptr) { // Copy the control points and compute their bounding box. const int pts_size = static_cast(std::distance (pts_begin, pts_end)); double x, y; double x_min = 0, x_max = 0; double y_min = 0, y_max = 0; int k; CGAL_precondition_msg (pts_size > 1, "There must be at least 2 control points."); _ctrl_pts.resize (pts_size); for (k = 0; pts_begin != pts_end; ++pts_begin, k++) { //SL: According to the fact that all operations are based on polynomials // duplicated control points can be allowed. // // Make sure that we do not have two identical consecutive control // // points. // CGAL_precondition_msg // (k == 0 || ! equal (*pts_begin, _ctrl_pts[k - 1]), // "Two consecutive control points must not be identical."); // Copy the current control point. _ctrl_pts[k] = *pts_begin; // Update the bounding box, if necessary. x = CGAL::to_double (pts_begin->x()); y = CGAL::to_double (pts_begin->y()); if (k == 0) { x_min = x_max = x; y_min = y_max = y; } else { if (x < x_min) x_min = x; else if (x > x_max) x_max = x; if (y < y_min) y_min = y; else if (y > y_max) y_max = y; } } // Construct the bounding box. _bbox = Bbox_2 (x_min, y_min, x_max, y_max); // Use the bounding traits to determine whether the curve surely has // not self intersections. Bounding_traits bound_tr; _no_self_inter = ! bound_tr.may_have_self_intersections (_ctrl_pts); } /*! destructs. */ ~_Bezier_curve_2_rep () { if (p_polyX != nullptr) delete p_polyX; if (p_normX != nullptr) delete p_normX; if (p_polyY != nullptr) delete p_polyY; if (p_normY != nullptr) delete p_normY; } /// \name Access the polynomials (lazily evaluated). //@{ /*! checks if the polynomials are already constructed. */ bool has_polynomials () const { return (p_polyX != nullptr && p_normX != nullptr && p_polyY != nullptr && p_normY != nullptr); } /*! obtains the polynomial X(t). */ const Polynomial& x_polynomial () const { if (p_polyX == nullptr) _construct_polynomials (); return (*p_polyX); } /*! obtains the normalizing factor for X(t). */ const Integer& x_norm () const { if (p_normX == nullptr) _construct_polynomials (); return (*p_normX); } /*! obtains the polynomial Y(t). */ const Polynomial& y_polynomial () const { if (p_polyY == nullptr) _construct_polynomials (); return (*p_polyY); } /*! obtains the normalizing factor for Y(t). */ const Integer& y_norm () const { if (p_normY == nullptr) _construct_polynomials (); return (*p_normY); } //@} private: /*! construct the representation of X(t) and Y(t). * The function is declared as "const" as it changes only mutable members. */ void _construct_polynomials () const; /*! computes the value of n! / (j! k! (n-k-j)!). */ Integer _choose (int n, int j, int k) const; }; template class _Bezier_curve_2 : public Handle_for<_Bezier_curve_2_rep > { public: typedef RatKernel_ Rat_kernel; typedef AlgKernel_ Alg_kernel; typedef NtTraits_ Nt_traits; typedef BoundingTraits_ Bounding_traits; typedef _Bezier_curve_2 Self; private: typedef _Bezier_curve_2_rep Bcv_rep; typedef Handle_for Bcv_handle; typedef typename Bcv_rep::Control_point_vec Control_pt_vec; public: typedef typename Bcv_rep::Rat_point_2 Rat_point_2; typedef typename Bcv_rep::Alg_point_2 Alg_point_2; typedef typename Bcv_rep::Integer Integer; typedef typename Bcv_rep::Rational Rational; typedef typename Bcv_rep::Algebraic Algebraic; typedef typename Bcv_rep::Polynomial Polynomial; typedef typename Control_pt_vec::const_iterator Control_point_iterator; public: /*!constructs default. */ _Bezier_curve_2 () : Bcv_handle (Bcv_rep()) {} /*! constructs copy. */ _Bezier_curve_2 (const Self& bc) : Bcv_handle (bc) {} /*! constructs from a given range of control points. * \param pts_begin An iterator pointing to the first point in the range. * \param pts_end A past-the-end iterator for the range. * \pre The value-type of the input iterator must be Rat_kernel::Point_2. * It is forbidden to specify two identical consecutive control points. */ template _Bezier_curve_2 (InputIterator pts_begin, InputIterator pts_end) : Bcv_handle (Bcv_rep (pts_begin, pts_end)) {} /*! assigns. */ Self& operator= (const Self& bc) { if (this == &bc || this->identical (bc)) return (*this); Bcv_handle::operator= (bc); return (*this); } /*! obtains a unique curve ID (based on the actual representation pointer). */ size_t id () const { return (reinterpret_cast (this->ptr())); } /*! obtains the polynomial for the x-coordinates of the curve. */ const Polynomial& x_polynomial () const { return (this->_rep().x_polynomial()); } /*! obtains the normalizing factor for the x-coordinates. */ const Integer& x_norm () const { return (this->_rep().x_norm()); } /*! obtains the polynomial for the y-coordinates of the curve. */ const Polynomial& y_polynomial () const { return (this->_rep().y_polynomial()); } /*! obtains the normalizing factor for the y-coordinates. */ const Integer& y_norm () const { return (this->_rep().y_norm()); } /*! obtains the number of control points inducing the Bezier curve. */ unsigned int number_of_control_points () const { return static_cast((this->_rep()._ctrl_pts.size())); } /*! obtains the i-th control point. * \pre i must be between 0 and n - 1, where n is the number of control * points. */ const Rat_point_2& control_point (unsigned int i) const { CGAL_precondition (i < number_of_control_points()); return ((this->_rep()._ctrl_pts)[i]); } /*! obtains an iterator for the first control point. */ Control_point_iterator control_points_begin () const { return (this->_rep()._ctrl_pts.begin()); } /*! obtains a past-the-end iterator for control points. */ Control_point_iterator control_points_end () const { return (this->_rep()._ctrl_pts.end()); } /*! checks if both curve handles refer to the same object. */ bool is_same (const Self& bc) const { return (this->identical (bc)); } /*! computes a point of the Bezier curve given a rational t-value. * \param t The given t-value. * \return The point B(t). */ Rat_point_2 operator() (const Rational& t) const; /*! computes a point of the Bezier curve given an algebraic t-value. * \param t The given t-value. * \return The point B(t). */ Alg_point_2 operator() (const Algebraic& t) const; /*! samples a portion of the curve (for drawing purposes, etc.). * \param t_start The t-value to start with. * \param t_end The t-value to end at. * \param n_samples The required number of samples. * \param oi Output: An output iterator for the samples. The value-type of * this iterator must be std::pair. * \return A past-the-end iterator for the samples. */ template OutputIterator sample (const double& t_start, const double& t_end, unsigned int n_samples, OutputIterator oi) const { // Convert the coordinates of the control points to doubles. typedef Simple_cartesian App_kernel; typedef App_kernel::Point_2 App_point_2; const unsigned int n_pts = number_of_control_points(); std::vector app_ctrl_pts (n_pts); unsigned int k; for (k = 0; k < n_pts; k++) { const Rat_point_2& pt = control_point(k); app_ctrl_pts[k] = App_point_2 (CGAL::to_double (pt.x()), CGAL::to_double (pt.y())); } // Sample the approximated curve. const unsigned int n = (n_samples >= 2) ? n_samples : 2; const double delta_t = (t_end - t_start) / (n - 1); App_point_2 p; for (k = 0; k < n; k++) { p = point_on_Bezier_curve_2 (app_ctrl_pts.begin(), app_ctrl_pts.end(), t_start + k * delta_t); *oi = std::make_pair (p.x(), p.y()); ++oi; } return (oi); } /*! computes all parameter values t such that the x-coordinate of B(t) is x0. * Note that the function does not return only values between 0 and 1, so * the output t-values may belong to the imaginary continuation of the curve. * \param x0 The given x-coordinate. * \param oi Output: An output iterator for the t-values. * \return A past-the-end iterator. */ template OutputIterator get_t_at_x (const Rational& x0, OutputIterator oi) const { return (_solve_t_values (this->_rep().x_polynomial(), this->_rep().x_norm(), x0, oi)); } /*! computes all parameter values t such that the y-coordinate of B(t) is y0. * Note that the function does not return only values between 0 and 1, so * the output t-values may belong to the imaginary continuation of the curve. * \param y0 The given y-coordinate. * \param oi Output: An output iterator for the t-values. * \return A past-the-end iterator. */ template OutputIterator get_t_at_y (const Rational& y0, OutputIterator oi) const { return (_solve_t_values (this->_rep().y_polynomial(), this->_rep().y_norm(), y0, oi)); } /*! checks if the two curves have the same support. */ bool has_same_support (const Self& bc) const; /*! obtains the bounding box of the curve. */ const Bbox_2& bbox () const { return (this->_rep()._bbox); } /*! checks if the curve contains not self intersections. * Note that there may not be any self intersections even if the * function returns true (but not vice versa). */ bool has_no_self_intersections () const { return (this->_rep()._no_self_inter); } private: // Get the representation. inline const Bcv_rep& _rep () const { return (*(this->ptr())); } inline Bcv_rep& _rep () { return (*(this->ptr())); } /*! computes all parameter values t, such that P(t) = val. * \param poly The polynomial. * \param norm Its normalizing factor. * \param val The required value. * \param oi Output: An output iterator for the t-values. * \return A past-the-end iterator. */ template OutputIterator _solve_t_values (const Polynomial& poly, const Integer& norm, const Rational& val, OutputIterator oi) const { // Construct the polynomial P(t) - val = 0: Nt_traits nt_traits; const Integer numer = nt_traits.numerator (val); const Integer denom = nt_traits.denominator (val); const int deg = nt_traits.degree (poly); if (deg <=0 ) return oi; Integer *coeffs = new Integer [deg + 1]; int k; for (k = 1; k <= deg; k++) { coeffs[k] = nt_traits.get_coefficient (poly, k) * denom; } coeffs[0] = nt_traits.get_coefficient (poly, 0) * denom - numer * norm; // Solve the polynomial and obtain the t-values. OutputIterator end = nt_traits.compute_polynomial_roots (nt_traits.construct_polynomial (coeffs, deg), oi); delete[] coeffs; return (end); } }; /*! exports a Bezier curves. */ template std::ostream& operator<< (std::ostream& os, const _Bezier_curve_2 & bc) { const unsigned int n = bc.number_of_control_points(); unsigned int k; os << n; for (k = 0; k < n; k++) os << " " << bc.control_point(k); return (os); } /*! imports a Bezier curves. */ template std::istream& operator>> (std::istream& is, _Bezier_curve_2 & bc) { // Read the number of control points. unsigned int n; is >> n; // Read the control points. std::vector ctrl_pts (n); unsigned int k; for (k = 0; k < n; k++) is >> ctrl_pts[k]; // Set the Bezier curve. bc = _Bezier_curve_2 (ctrl_pts.begin(), ctrl_pts.end()); return (is); } // --------------------------------------------------------------------------- // Construct the representation of X(t) and Y(t). // template void _Bezier_curve_2_rep::_construct_polynomials () const { const int n = static_cast(_ctrl_pts.size() - 1); Rational *coeffsX = new Rational [n + 1]; Rational *coeffsY = new Rational [n + 1]; const Rational rat_zero = Rational (0); int j, k; CGAL_precondition_msg (n > 0, "There must be at least 2 control points."); for (j = 0; j <= n; j++) coeffsX[j] = coeffsY[j] = rat_zero; // Compute the rational coefficients, given by the formula: // // n // ***** // * * / n \ k n-k // (X(t), Y(t)) = * p_k ( ) t (1 - t) // * * \ k / // ***** // k=0 // Rational px, py; Integer n_over_k_j; bool even_exp; typename Control_point_vec::const_iterator pts_begin = _ctrl_pts.begin(); typename Control_point_vec::const_iterator pts_end = _ctrl_pts.end(); for (k = 0; pts_begin != pts_end; ++pts_begin, k++) { px = pts_begin->x(); py = pts_begin->y(); // By simplifying (1 - t)^(n-k) we obtain that the k-th expression of // the above sum is given by: // // n-k // ***** // * * j n! j+k // * (-1) p_k ---------------- t // * * j! k! (n-k-j)! // ***** // j=0 // even_exp = true; for (j = 0; j <= n - k; j++) { n_over_k_j = _choose (n, k, j); if (even_exp) { // We should add the current values to the coefficients of the // monomial t^(n_j). coeffsX[j + k] += px * n_over_k_j; coeffsY[j + k] += py * n_over_k_j; } else { // We should subtract the current values from the coefficients of the // monomial t^(n_j). coeffsX[j + k] -= px * n_over_k_j; coeffsY[j + k] -= py * n_over_k_j; } // As we increment j, negate the "even" flag for the exponent (n-j). even_exp = !even_exp; } // loop on j. } // loop on k. // Convert the rational polynomials to polynomials with rational // coefficients (plus normalizing factors). Nt_traits nt_traits; p_polyX = new Polynomial; p_normX = new Integer; p_polyY = new Polynomial; p_normY = new Integer; nt_traits.construct_polynomial (coeffsX, n, *p_polyX, *p_normX); delete[] coeffsX; nt_traits.construct_polynomial (coeffsY, n, *p_polyY, *p_normY); delete[] coeffsY; // CGAL_assertion (nt_traits.degree (*p_polyX) >= 0); // CGAL_assertion (nt_traits.degree (*p_polyY) >= 0); return; } // --------------------------------------------------------------------------- // Compute the value of n! / (j! k! (n-k-j)!). // template typename _Bezier_curve_2_rep::Integer _Bezier_curve_2_rep::_choose (int n, int j, int k) const { Integer reduced_fact = 1; Integer j_fact = 1, k_fact = 1; int i; for (i = n - k - j + 1; i <= n; i++) reduced_fact *= Integer (i); for (i = 2; i <= j; i++) j_fact *= Integer (i); for (i = 2; i <= k; i++) k_fact *= Integer (i); return (CGAL::div (reduced_fact, (j_fact * k_fact))); } // --------------------------------------------------------------------------- // Compute a point on the Bezier curve B(t) given a rational t-value. // template typename _Bezier_curve_2::Rat_point_2 _Bezier_curve_2::operator() (const Rational& t) const { // Check for external t values (either 0 or 1). const CGAL::Sign sign_t = CGAL::sign (t); CGAL_precondition (sign_t != NEGATIVE); if (sign_t == ZERO) { // If t is 0, simply return the first control point. return (this->_rep()._ctrl_pts[0]); } Comparison_result res = CGAL::compare (t, Rational(1)); CGAL_precondition (res != LARGER); if (res == EQUAL) { // If t is 1, simply return the first control point. return (this->_rep()._ctrl_pts[this->_rep()._ctrl_pts.size() - 1]); } // Evaluate the point for 0 < t < 1. if (! this->_rep().has_polynomials()) { // Use de Casteljau's algorithm to evaluate the polynomial at t. return (point_on_Bezier_curve_2 (this->_rep()._ctrl_pts.begin(), this->_rep()._ctrl_pts.end(), t)); } // Compute the x and y coordinates using the X(t), Y(t) polynomials. Rational x, y; Nt_traits nt_traits; x = nt_traits.evaluate_at (this->_rep().x_polynomial(), t) / Rational (this->_rep().x_norm(), 1); y = nt_traits.evaluate_at (this->_rep().y_polynomial(), t) / Rational (this->_rep().y_norm(), 1); // Return the point. return (Rat_point_2 (x, y)); } // --------------------------------------------------------------------------- // Compute a point on the Bezier curve B(t) given an algebraic t-value. // template typename _Bezier_curve_2::Alg_point_2 _Bezier_curve_2::operator() (const Algebraic& t) const { // Check for external t values (either 0 or 1). Nt_traits nt_traits; const CGAL::Sign sign_t = CGAL::sign (t); CGAL_precondition (sign_t != NEGATIVE); if (sign_t == ZERO) { // If t is 0, simply return the first control point. const Rat_point_2& p_0 = this->_rep()._ctrl_pts[0]; return (Alg_point_2 (nt_traits.convert (p_0.x()), nt_traits.convert (p_0.y()))); } Comparison_result res = CGAL::compare (t, Algebraic(1)); CGAL_precondition (res != LARGER); if (res == EQUAL) { // If t is 1, simply return the first control point. const Rat_point_2& p_n = this->_rep()._ctrl_pts[this->_rep()._ctrl_pts.size() - 1]; return (Alg_point_2 (nt_traits.convert (p_n.x()), nt_traits.convert (p_n.y()))); } // The t-value is between 0 and 1: Compute the x and y coordinates. const Algebraic x = nt_traits.evaluate_at (this->_rep().x_polynomial(), t)/ nt_traits.convert (this->_rep().x_norm()); const Algebraic y = nt_traits.evaluate_at (this->_rep().y_polynomial(), t)/ nt_traits.convert (this->_rep().y_norm()); return (Alg_point_2 (x, y)); } // --------------------------------------------------------------------------- // Check if the two curves have the same support. // template bool _Bezier_curve_2::has_same_support (const Self& bc) const { // If one curve is of degree d1 and the other of degree d2, there can be // at most d1*d2 intersection points between them. const int deg1 = number_of_control_points() - 1; const int deg2 = bc.number_of_control_points() - 1; const int n_samples = deg1*deg2; Rat_point_2 p1; int k; for (k = 0; k <= n_samples; k++) { // Compute p1 = B1(k/n_samples), where B1 is (*this) curve. if (k == 0) p1 = (this->_rep()._ctrl_pts[0]); else if (k == 1) p1 = (this->_rep()._ctrl_pts[this->_rep()._ctrl_pts.size() - 1]); else p1 = this->operator() (Rational (k, n_samples)); // Get all t-values such that the x-coordinate of B2(t) equals x1, // and check if there exists a t-value such that the y-coordinate of // b2(t) equals the y-coordinate of p1. std::list t_vals; typename std::list::const_iterator t_iter; Nt_traits nt_traits; const Algebraic& y1 = nt_traits.convert (p1.y()); bool eq_y = false; bc.get_t_at_x (p1.x(), std::back_inserter(t_vals)); for (t_iter = t_vals.begin(); t_iter != t_vals.end(); ++t_iter) { const Alg_point_2& p2 = bc (*t_iter); if (CGAL::compare (y1, p2.y()) == CGAL::EQUAL) { eq_y = true; break; } } // If we found a point on B1 which is not of B2, the two curves do not // have the same support. if (! eq_y) return (false); } // If we reached here, we found (d1*d2 + 1) common points of B1 and B2. // This means they have the same support. return (true); } } // namespace CGAL #endif