
    l0jT                        d Z ddlmZ ddlZddlZddlZddlmZ d Z	d Z
 ed          d	             Z G d
 de          Zd Zd Zd Zd Z	 d!dZ G d d          Z	 d"dZd#dZd Zd Zd$dZd Zd Zd%d ZdS )&uP   
A module providing some utility functions regarding Bézier path manipulation.
    )	lru_cacheN)_apic                    t          |          dk     rft          |          dk     rt          j        g           S |  |z  }d|cxk    rdk    rn nt          j        |g          nt          j        g           S ||z  d|z  | z  z
  }|dk     rt          j        g           S t          j        |          }|dk    r	d||z   z  }nd||z
  z  }g }t          |          dk    r|                    | |z             t          |          dk    r|                    ||z             t          j        |          }||dk    |dk    z           S )z,Real roots of c0 + c1*x + c2*x**2 in [0, 1].-q=r         g      )absnparraysqrtappendasarray)c0c1c2rootdisc	sqrt_discqrootss           T/home/wildlama/miniconda3/envs/lam/lib/python3.11/site-packages/matplotlib/bezier.py_quadratic_roots_in_01r      sG   
2wwr77U??8B<<sRx#$>>>>>>>>>rxrx||C7QVb[ Daxxx||I	QwwBN#BN#E
1vv~~R!V
2wwQVJuE%1*!,--    c                     t          j        | t                    } t          |           dz
  }|dk    r=t	          | |                   dk     r$|dz  }|dk    rt	          | |                   dk     $|dk    rt          j        g           S |dk    rK| d          | d         z  }d|cxk    rdk    rn nt          j        |g          nt          j        g           S |dk    r$t          | d         | d         | d                   }nvd}t          j        | |dd                   }t          j        |j                  |k     }||         j	        }|| k    |d|z   k    z  }t          j
        ||         dd          }t          j        |          S )	a  
    Find real roots of a polynomial in the interval [0, 1].

    For polynomials of degree <= 2, closed-form solutions are used.
    For higher degrees, `numpy.roots` is used as a fallback. In practice,
    matplotlib only ever uses cubic bezier curves and axis_aligned_extrema()
    differentiates, so we only ever find roots for degree <= 2.

    Parameters
    ----------
    coeffs : array-like
        Polynomial coefficients in ascending order:
        ``c[0] + c[1]*x + c[2]*x**2 + ...``
        Note this is the opposite convention from `numpy.roots`.

    Returns
    -------
    roots : ndarray
        Sorted array of real roots in [0, 1].
    )dtyper   r   r      g|=N)r
   r   floatlenr	   r   r   r   imagrealclipsort)	coeffsdegr   r   eps	all_roots	real_mask
real_rootsin_ranges	            r   _real_roots_in_01r+   +   s   * Ze,,,F f++/C
''c&+&&..q ''c&+&&.. axxx||	q	zF1I%#$>>>>>>>>>rxrx||C	&vay&)VAYGG HVCGG_--	F9>**S0	y).
3$&:S+@A
8,a3375>>r      )maxsizec                    d }t          j        | dz             dddf         }t          j        | dz             dddf         }d||z   z   |||          z  } || |          |z                      t                    S )a&  
    Compute the matrix for converting Bezier control points to polynomial
    coefficients for a curve of degree n.

    The matrix M is such that M @ control_points gives polynomial coefficients.
    Entry M[j, i] = C(n, j) * (-1)^(i+j) * C(j, i) where C is the binomial
    coefficient.
    c                 R     t          j        t          j                  | |          S N)r
   	vectorizemathcomb)nks     r   _combz _get_coeff_matrix.<locals>._combd   s     &r|DI&&q!,,,r   r   Nr   )r
   arangeastyper   )r4   r6   ji	prefactors        r   _get_coeff_matrixr<   Z   s    - - - 		!a%D!A
	!a%qqq!AQ%%1++-IE!QKK)#++E222r   c                       e Zd ZdS )NonIntersectingPathExceptionN)__name__
__module____qualname__ r   r   r>   r>   m   s        Dr   r>   c                    || z  ||z  z
  }||z  ||z  z
  }	|| }}
|| }}|
|z  ||z  z
  t                    dk     rt          d          || }}| |
}}fd||||fD             \  }}}}||z  ||	z  z   }||z  ||	z  z   }||fS )z
    Return the intersection between the line through (*cx1*, *cy1*) at angle
    *t1* and the line through (*cx2*, *cy2*) at angle *t2*.
    r   zcGiven lines do not intersect. Please verify that the angles are not equal or differ by 180 degrees.c              3   "   K   | ]	}|z  V  
d S r0   rB   ).0r5   ad_bcs     r   	<genexpr>z#get_intersection.<locals>.<genexpr>   s'      ::Aa%i::::::r   )r	   
ValueError)cx1cy1cos_t1sin_t1cx2cy2cos_t2sin_t2	line1_rhs	line2_rhsabcda_b_c_d_xyrF   s                       @r   get_intersectionr]   t   s     v|+Iv|+I F7qAF7qAEAEME
5zzE N O O 	O BRB::::"b"b)9:::NBB
Yi'A
Yi'Aa4Kr   c                 z    |dk    r| || |fS || }}| |}}||z  | z   ||z  |z   }
}	||z  | z   ||z  |z   }}|	|
||fS )z
    For a line passing through (*cx*, *cy*) and having an angle *t*, return
    locations of the two points located along its perpendicular line at the
    distance of *length*.
            rB   )cxcycos_tsin_tlengthrK   rL   rO   rP   x1y1x2y2s                r   get_normal_pointsri      su     ||2r2~UFFFVUFFf_r!6F?R#7Bf_r!6F?R#7Br2r>r   c                 B    | d d         d|z
  z  | dd          |z  z   }|S )Nr   r   rB   )betat	next_betas      r   _de_casteljau1rn      s/    SbS	QU#d122hl2Ir   c                     t          j        |           } | g}	 t          | |          } |                    |            t	          |           dk    rn:d |D             }d t          |          D             }||fS )u   
    Split a Bézier segment defined by its control points *beta* into two
    separate segments divided at *t* and return their control points.
    Tr   c                     g | ]
}|d          S )r   rB   rE   rk   s     r   
<listcomp>z&split_de_casteljau.<locals>.<listcomp>   s    ///Ta///r   c                     g | ]
}|d          S )r   rB   rq   s     r   rr   z&split_de_casteljau.<locals>.<listcomp>   s    ;;;t$r(;;;r   )r
   r   rn   r   r   reversed)rk   rl   	beta_list	left_beta
right_betas        r   split_de_casteljaurx      s    
 :dDIdA&&t99>>	
 0/Y///I;;x	':':;;;Jj  r   r_         ?{Gz?c                     | |          } | |          } ||          } ||          }||k    r||k    rt          d          	 t          j        |d         |d         z
  |d         |d         z
            |k     r||fS d||z   z  }	 | |	          }
 ||
          }||z  r|	}||
k    r||fS |
}n|	}||
k    r||fS |
}|}~)u  
    Find the intersection of the Bézier curve with a closed path.

    The intersection point *t* is approximated by two parameters *t0*, *t1*
    such that *t0* <= *t* <= *t1*.

    Search starts from *t0* and *t1* and uses a simple bisecting algorithm
    therefore one of the end points must be inside the path while the other
    doesn't. The search stops when the distance of the points parametrized by
    *t0* and *t1* gets smaller than the given *tolerance*.

    Parameters
    ----------
    bezier_point_at_t : callable
        A function returning x, y coordinates of the Bézier at parameter *t*.
        It must have the signature::

            bezier_point_at_t(t: float) -> tuple[float, float]

    inside_closedpath : callable
        A function returning True if a given point (x, y) is inside the
        closed path. It must have the signature::

            inside_closedpath(point: tuple[float, float]) -> bool

    t0, t1 : float
        Start parameters for the search.

    tolerance : float
        Maximal allowed distance between the final points.

    Returns
    -------
    t0, t1 : float
        The Bézier path parameters.
    z3Both points are on the same side of the closed pathTr   r         ?)r>   r
   hypot)bezier_point_at_tinside_closedpatht0t1	tolerancestartendstart_inside
end_insidemiddle_tmiddlemiddle_insides               r   *find_bezier_t_intersecting_with_closedpathr      s5   L b!!E

B

C$$U++L""3''Jz!!esll*AC C 	C) 8E!Hs1v%uQx#a&'899IEEr6M "r'?""8,,))&11-' 	)Bf}} 2vCCB 2vE(L3)r   c                       e Zd ZdZd Zd Z ej        dd          d             Ze	d             Z
e	d	             Ze	d
             Ze	d             Zd ZdS )BezierSegmentu*  
    A d-dimensional Bézier segment.

    A BezierSegment can be called with an argument, either a scalar or an array-like
    object, to evaluate the curve at that/those location(s).

    Parameters
    ----------
    control_points : (N, d) array
        Location of the *N* control points.
    c                     t          j        |           _         j        j        \   _         _        t          j         j                   _         fdt           j                  D             } j        j	        |z  j	         _
        d S )Nc                     g | ]S}t          j        j        d z
            t          j        |          t          j        j        d z
  |z
            z  z  TS )r   )r2   	factorial_N)rE   r:   selfs     r   rr   z*BezierSegment.__init__.<locals>.<listcomp>"  se     * * * !,,^A&&!a)H)HHJ * * *r   )r
   r   _cpointsshaper   _dr7   _ordersrangeT_px)r   control_pointscoeffs   `  r   __init__zBezierSegment.__init__  s    
>22=.y))* * * *..* * * MOe+.r   c                     t          j        |          }t           j                            d|z
  | j        ddd                   t           j                            || j                  z  | j        z  S )u)  
        Evaluate the Bézier curve at point(s) *t* in [0, 1].

        Parameters
        ----------
        t : (k,) array-like
            Points at which to evaluate the curve.

        Returns
        -------
        (k, d) array
            Value of the curve for each point in *t*.
        r   Nr   )r
   r   powerouterr   r   r   rl   s     r   __call__zBezierSegment.__call__'  s^     JqMMq1udl44R4&899(..DL11259X> 	>r   z3.11z/Call the BezierSegment object with an argument.)alternativec                 2    t           | |                    S )zX
        Evaluate the curve at a single point, returning a tuple of *d* floats.
        tupler   s     r   
point_at_tzBezierSegment.point_at_t9  s     TT!WW~~r   c                     | j         S )z The control points of the curve.)r   r   s    r   r   zBezierSegment.control_pointsA  s     }r   c                     | j         S )zThe dimension of the curve.)r   r   s    r   	dimensionzBezierSegment.dimensionF  s     wr   c                     | j         dz
  S )z@Degree of the polynomial. One less the number of control points.r   )r   r   s    r   degreezBezierSegment.degreeK  s     w{r   c                 ~    | j         }|dk    rt          j        dt                     t	          |          | j        z  S )u  
        The polynomial coefficients of the Bézier curve.

        .. warning:: Follows opposite convention from `numpy.polyval`.

        Returns
        -------
        (n+1, d) array
            Coefficients after expanding in polynomial basis, where :math:`n`
            is the degree of the Bézier curve and :math:`d` its dimension.
            These are the numbers (:math:`C_j`) such that the curve can be
            written :math:`\sum_{j=0}^n C_j t^j`.

        Notes
        -----
        The coefficients are calculated as

        .. math::

            {n \choose j} \sum_{i=0}^j (-1)^{i+j} {j \choose i} P_i

        where :math:`P_i` are the control points of the curve.
        
   zFPolynomial coefficients formula unstable for high order Bezier curves!)r   warningswarnRuntimeWarningr<   r   )r   r4   s     r   polynomial_coefficientsz%BezierSegment.polynomial_coefficientsP  sI    2 Kr66M 12@B B B ##d&999r   c                    | j         }|dk    r(t          j        g           t          j        g           fS | j        }t          j        d|dz             dddf         |dd         z  }g }g }t          |j                  D ]q\  }}t          |          }t          |          dk    rJ|	                    |           |	                    t          j
        t          |          |                     r|s(t          j        g           t          j        g           fS t          j        |          t          j        |          fS )a  
        Return the dimension and location of the curve's interior extrema.

        The extrema are the points along the curve where one of its partial
        derivatives is zero.

        Returns
        -------
        dims : array of int
            Index :math:`i` of the partial derivative which is zero at each
            interior extrema.
        dzeros : array of float
            Of same size as dims. The :math:`t` such that :math:`d/dx_i B(t) =
            0`
        r   Nr   )r   r
   r   r   r7   	enumerater   r+   r   r   fullconcatenate)	r   r4   CjdCjall_dimsr'   r:   pirs	            r   axis_aligned_extremaz"BezierSegment.axis_aligned_extremap  s$     K668B<<"--)i1q5!!!!!T'*RV3	su%% 	4 	4EAr!"%%A1vvzz  ###A 2 2333 	.8B<<"--~h''	)B)BBBr   N)r?   r@   rA   __doc__r   r   r   
deprecatedr   propertyr   r   r   r   r   rB   r   r   r   r     s        
 
/ / /> > >$ T_MO O O O O   X   X   X : : X:>"C "C "C "C "Cr   r   c                     t          |           t          fd||          \  }}t          | ||z   dz            \  }}||fS )ur  
    Split a Bézier curve into two at the intersection with a closed path.

    Parameters
    ----------
    bezier : (N, 2) array-like
        Control points of the Bézier segment. See `.BezierSegment`.
    inside_closedpath : callable
        A function returning True if a given point (x, y) is inside the
        closed path. See also `.find_bezier_t_intersecting_with_closedpath`.
    tolerance : float
        The tolerance for the intersection. See also
        `.find_bezier_t_intersecting_with_closedpath`.

    Returns
    -------
    left, right
        Lists of control points for the two Bézier segments.
    c                 4    t           |                     S r0   r   )rl   bzs    r   <lambda>z;split_bezier_intersecting_with_closedpath.<locals>.<lambda>  s    %1,, r   )r   g       @)r   r   rx   )bezierr   r   r   r   _left_rightr   s          @r   )split_bezier_intersecting_with_closedpathr     se    , 
v		B7 1YH H HFB 'vR2~>>ME6&=r   Fc           	      F   ddl m} |                                 }t          |          \  }} ||dd                   }|}	d}
d}|D ]U\  }}|}
|t	          |          dz  z  } ||dd                   |k    r t          j        |	dd         |g          } n|}	Vt          d          |                    d          }t          |||          \  }}t	          |          dk    r|j
        g}|j        |j
        g}nt	          |          d	k    r#|j        |j        g}|j        |j        |j        g}nQt	          |          d
k    r/|j        |j        |j        g}|j        |j        |j        |j        g}nt          d          |dd         }|dd         }| j        Y |t          j        | j        d|         |g                    } |t          j        || j        |d         g                    }n |t          j        | j        d|
         |g          t          j        | j        d|
         |g                    } |t          j        || j        |d         g          t          j        || j        |d         g                    }|r|s||}}||fS )z`
    Divide a path into two segments at the point where ``inside(x, y)`` becomes
    False.
    r   )PathNr   r   z*The path does not intersect with the patch)r   r      r   zThis should never be reached)pathr   iter_segmentsnextr   r
   r   rH   reshaper   LINETOMOVETOCURVE3CURVE4AssertionErrorcodesvertices)r   insider   reorder_inoutr   	path_iter
ctl_pointscommandbegin_insidectl_points_oldioldr:   bezier_pathbpleftright
codes_leftcodes_right
verts_leftverts_rightpath_inpath_outs                         r   split_path_inoutr     s   
 ""$$Iy//J6*RSS/**LND	A( G G
G	S__!!6*RSS/""l22..*=z)JKKKE#EFFF			W	%	%B;
FI KD%
4yyA~~k]
{DK0	Tak4;/
{DK=	Tak4;<
{DKdkJ;<<<abbJ(Kz$r~t}RaR'8*&EFFGG4T]1225F'GHHII $r~t}UdU';Z&HII~tz%4%'8*&EFFH H 4T]1225F'GHHTZ^'DEEG G  .\ .$gHr   c                 $     |dz   fd}|S )z
    Return a function that checks whether a point is in a circle with center
    (*cx*, *cy*) and radius *r*.

    The returned function has the signature::

        f(xy: tuple[float, float]) -> bool
    r   c                 8    | \  }}|z
  dz  |z
  dz  z   k     S )Nr   rB   )xyr[   r\   r`   ra   r2s      r   _fzinside_circle.<locals>._f  s,    1B1}B1},r11r   rB   )r`   ra   r   r   r   s   ``  @r   inside_circler     s:     
aB2 2 2 2 2 2 2 Ir   c                 V    || z
  ||z
  }}||z  ||z  z   dz  }|dk    rdS ||z  ||z  fS )Nr|   r   )r_   r_   rB   )x0y0re   rf   dxdyrV   s          r   get_cos_sinr     sJ    "Wb2gB	b27	r!AAvvx626>r   h㈵>c                     t          j        | |          }t          j        ||          }t          ||z
            }||k     rdS t          |t           j        z
            |k     rdS dS )a  
    Check if two lines are parallel.

    Parameters
    ----------
    dx1, dy1, dx2, dy2 : float
        The gradients *dy*/*dx* of the two lines.
    tolerance : float
        The angular tolerance in radians up to which the lines are considered
        parallel.

    Returns
    -------
    is_parallel
        - 1 if two lines are parallel in same direction.
        - -1 if two lines are parallel in opposite direction.
        - False otherwise.
    r   r   F)r
   arctan2r	   r   )dx1dy1dx2dy2r   theta1theta2dthetas           r   check_if_parallelr     sj    & ZS!!FZS!!F&!!F	q	Vbe^		y	(	(rur   c           
         | d         \  }}| d         \  }}| d         \  }}t          ||z
  ||z
  ||z
  ||z
            }|dk    r.t          j        d           t          ||||          \  }	}
|	|
}}n*t          ||||          \  }	}
t          ||||          \  }}t	          |||	|
|          \  }}}}t	          |||||          \  }}}}	 t          |||	|
||||          \  }}t          |||	|
||||          \  }}n0# t          $ r# d||z   z  d||z   z  }}d||z   z  d||z   z  }}Y nw xY w||f||f||fg}||f||f||fg}||fS )u   
    Given the quadratic Bézier control points *bezier2*, returns
    control points of quadratic Bézier lines roughly parallel to given
    one separated by *width*.
    r   r   r   r   z8Lines do not intersect. A straight line is used instead.r|   )r   r   warn_externalr   ri   r]   rH   )bezier2widthc1xc1ycmxcmyc2xc2yparallel_testrK   rL   rO   rP   c1x_leftc1y_left	c1x_right	c1y_rightc2x_leftc2y_left	c2x_right	c2y_rightcmx_leftcmy_left	cmx_right	cmy_right	path_left
path_rights                              r   get_parallelsr  .  s    qzHCqzHCqzHC%cCis&)Cis< <M F	H 	H 	H$S#sC88 %S#sC88$S#sC88 	#sFFE:: -Hh	9 	#sFFE:: -Hh	9
-h&.4h.4f> >(  0	9f06	906 @  @	99  	
 	
 	

 8h&'80C)D  9y()3)i2G+H 				
 H%H%H%'I i(i(i(*J j  s   2D *D/.D/c                 P    dd|z  | |z   z
  z  }dd|z  ||z   z
  z  }| |f||f||fgS )u   
    Find control points of the Bézier curve passing through (*c1x*, *c1y*),
    (*mmx*, *mmy*), and (*c2x*, *c2y*), at parametric values 0, 0.5, and 1.
    r|   r   rB   )r  r  mmxmmyr  r	  r  r  s           r   find_control_pointsr  x  sK    
 C39%
&C
C39%
&C#Jc
S#J//r   r|   c                    | d         \  }}| d         \  }}| d         \  }	}
t          ||||          \  }}t          |||	|
          \  }}t          ||||||z            \  }}}}t          |	|
||||z            \  }}}}||z   dz  ||z   dz  }}||	z   dz  ||
z   dz  }}||z   dz  ||z   dz  }}t          ||||          \  }}t          ||||||z            \  }} }!}"t          |||| ||          }#t          |||!|"||          }$|#|$fS )u   
    Being similar to `get_parallels`, returns control points of two quadratic
    Bézier lines having a width roughly parallel to given one separated by
    *width*.
    r   r   r   r|   )r   ri   r  )%r  r  w1wmw2r  r  r  r  c3xc3yrK   rL   rO   rP   r  r  r  r  c3x_leftc3y_left	c3x_right	c3y_rightc12xc12yc23xc23yc123xc123ycos_t123sin_t123
c123x_left
c123y_leftc123x_rightc123y_rightr  r  s%                                        r   make_wedged_bezier2r4    s    qzHCqzHCqzHC !c344NFF c344NFF 	#sFFEBJ?? -Hh	9 	#sFFEBJ?? -Hh	9 )r!C#I#3$D)r!C#I#3$D4K2%tr'95E %T4t<<Hh 	%(EBJGG 5J
K $Hh$.
$,h8 8I %Y	%0+%.	; ;J j  r   )r_   ry   rz   )rz   )rz   F)r   )ry   r|   r_   )r   	functoolsr   r2   r   numpyr
   
matplotlibr   r   r+   r<   rH   r>   r]   ri   rn   rx   r   r   r   r   r   r   r   r  r  r4  rB   r   r   <module>r8     s                      . . .:, , ,^ 23 3 3$	 	 	 	 	: 	 	 	  B  2  
! ! !& GKI) I) I) I)XAC AC AC AC AC AC AC ACJ .2   D: : : :z  &     <G! G! G!T0 0 00! 0! 0! 0! 0! 0!r   