
    
3jT                         S r SSKJr  SSKrSSKrSSKrSSKJr  S r	S r
\" SS9S	 5       r " S
 S\5      rS rS rS rS r SS jr " S S5      r SS jrSS jrS rS rSS jrS rS rSS jrg) uP   
A module providing some utility functions regarding Bézier path manipulation.
    )	lru_cacheN)_apic                 j   [        U5      S:  ah  [        U5      S:  a  [        R                  " / 5      $ U * U-  nSUs=::  a  S::  a  O  O[        R                  " U/5      $ [        R                  " / 5      $ X-  SU-  U -  -
  nUS:  a  [        R                  " / 5      $ [        R                  " U5      nUS:  a  SX-   -  nOSX-
  -  n/ n[        U5      S:  a  UR	                  X-  5        [        U5      S:  a  UR	                  Xb-  5        [        R
                  " U5      nXwS:  U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           K/home/wildlama/miniconda3/lib/python3.13/site-packages/matplotlib/bezier.py_quadratic_roots_in_01r      s	   
2wr7U?88B<sRx#$>>rxxCrxx|C7QVb[ Daxxx|I	QwBN#BN#E
1v~RV
2wQVJJuE1*!,--    c                    [         R                  " U [        S9n [        U 5      S-
  nUS:  a/  [	        X   5      S:  a  US-  nUS:  a  [	        X   5      S:  a  M  US::  a  [         R
                  " / 5      $ US:X  aI  U S   * U S   -  nSUs=::  a  S::  a  O  O[         R
                  " U/5      $ [         R
                  " / 5      $ US:X  a  [        U S   U S   U S   5      nOvSn[         R                  " XSS2   5      n[         R                  " UR                  5      U:  nXV   R                  nXt* :  USU-   :*  -  n[         R                  " Xx   SS5      n[         R                  " U5      $ )	aP  
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+   +   sP   * ZZe,F f+/C
'c&+&.q 'c&+&. axxx|	q	zF1I%#$>>rxxCrxx|C	&vay&)VAYG HHVGG_-	FF9>>*S0	)..
$&:S+@A
,a3775>r      )maxsizec                     S n[         R                  " U S-   5      SS2S4   n[         R                  " U S-   5      SSS24   nSX2-   -  U" X#5      -  nU" X5      U-  R                  [        5      $ )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                 V    [         R                  " [        R                  5      " X5      $ N)r
   	vectorizemathcomb)nks     r   _comb _get_coeff_matrix.<locals>._combd   s    ||DII&q,,r   r   Nr   )r
   arangeastyper   )r4   r6   ji	prefactors        r   _get_coeff_matrixr=   Z   sm    - 			!a%D!A
		!a%q!A%+-I!K)#++E22r   c                       \ rS rSrSrg)NonIntersectingPathExceptionm    N)__name__
__module____qualname____firstlineno____static_attributes__rA   r   r   r?   r?   m   s    r   r?   c                    ^ X0-  X!-  -
  nXt-  Xe-  -
  n	X2* pXv* pX-  X-  -
  m[        T5      S:  a  [        S5      eX* pU* U
nnU4S jXUU4 5       u  pnnX-  X-  -   nUU-  UU	-  -   nUU4$ )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   ,   >#    U  H	  oT-  v   M     g 7fr0   rA   ).0r5   ad_bcs     r   	<genexpr>#get_intersection.<locals>.<genexpr>   s     :)9A%i)9s   )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yrJ   s                       @r   get_intersectionrb   t   s     v|+Iv|+I 7q7qEAEME
5zE N O 	O RB:""b)9:NBB
'A
Yi'Aa4Kr   c                 `    US:X  a  XX4$ X2* peU* UpXE-  U -   XF-  U-   pXG-  U -   XH-  U-   pXX4$ )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*.
        rA   )cxcycos_tsin_tlengthrP   rQ   rT   rU   x1y1x2y2s                r   get_normal_pointsrn      sY     |r~FFVUF_r!6?R#7_r!6?R#72>r   c                 .    U S S SU-
  -  U SS  U-  -   nU$ )Nr   r   rA   )betat	next_betas      r   _de_casteljau1rs      s+    Sb	QU#d12hl2Ir   c                    [         R                  " U 5      n U /n [        X5      n UR                  U 5        [	        U 5      S:X  a  OM.  U V s/ s H  o S   PM	     nn [        U5       V s/ s H  o S   PM	     nn X44$ s  sn f s  sn f )u   
Split a Bézier segment defined by its control points *beta* into two
separate segments divided at *t* and return their control points.
r   r   r   )r
   r   rs   r   r   reversed)rp   rq   	beta_list	left_beta
right_betas        r   split_de_casteljaury      s    
 ::dDI
d&t9>	 
 &//YTaYI/'/	':;':tr(':J;   0;s   A=*Bc                 H   U " U5      nU " U5      nU" U5      nU" U5      nXx:X  a  XV:w  a  [        S5      e [        R                  " US   US   -
  US   US   -
  5      U:  a  X#4$ SX#-   -  n	U " U	5      n
U" U
5      nX{-  (       a  U	nXj:X  a  X#4$ U
nOU	nXZ:X  a  X#4$ U
nUnMm  )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 pathr   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      s    L b!E
B
C$U+L"3'J!el*AC 	C  88E!Hs1v%uQx#a&'89IE6M "'?"8,)&1'B} vCB vE(L3 r   c                       \ rS rSrSrS rS r\R                  " SSS9S 5       r	\
S	 5       r\
S
 5       r\
S 5       r\
S 5       rS rSrg)BezierSegmenti  u
  
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           	      ,   [         R                  " U5      U l        U R                  R                  u  U l        U l        [         R                  " U R                  5      U l        [        U R                  5       Vs/ s Hd  n[        R                  " U R                  S-
  5      [        R                  " U5      [        R                  " U R                  S-
  U-
  5      -  -  PMf     nnU R                  R                  U-  R                  U l        g s  snf )Nr   )r
   r   _cpointsshape_N_dr8   _ordersranger2   	factorialT_px)selfcontrol_pointsr;   coeffs       r   __init__BezierSegment.__init__  s    

>2==..yy)  .*(Q !,^^A&!a)HHJ( 	 * MMOOe+..*s   ;A+Dc                    [         R                  " U5      n[         R                  R                  SU-
  U R                  SSS2   5      [         R                  R                  XR                  5      -  U R
                  -  $ )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   rq   s     r   __call__BezierSegment.__call__'  s^     JJqMq1udll4R4&89((..LL1259XX> 	>r   z3.11z/Call the BezierSegment object with an argument.)alternativec                 $    [        U " U5      5      $ )zH
Evaluate the curve at a single point, returning a tuple of *d* floats.
tupler   s     r   
point_at_tBezierSegment.point_at_t9  s     T!W~r   c                     U R                   $ )z The control points of the curve.)r   r   s    r   r   BezierSegment.control_pointsA  s     }}r   c                     U R                   $ )zThe dimension of the curve.)r   r   s    r   	dimensionBezierSegment.dimensionF  s     wwr   c                      U R                   S-
  $ )z@Degree of the polynomial. One less the number of control points.r   )r   r   s    r   degreeBezierSegment.degreeK  s     ww{r   c                     U R                   nUS:  a  [        R                  " S[        5        [	        U5      U R
                  -  $ )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_coefficients%BezierSegment.polynomial_coefficientsP  s?    2 KKr6MM 12@B #d&9&999r   c                    U R                   nUS::  a,  [        R                  " / 5      [        R                  " / 5      4$ U R                  n[        R                  " SUS-   5      SS2S4   USS -  n/ n/ n[        UR                  5       Ha  u  pg[        U5      n[        U5      S:  d  M!  UR                  U5        UR                  [        R                  " [        U5      U5      5        Mc     U(       d,  [        R                  " / 5      [        R                  " / 5      4$ [        R                  " U5      [        R                  " U5      4$ )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   r8   	enumerater   r+   r   r   fullconcatenate)	r   r4   CjdCjall_dimsr'   r;   pirs	            r   axis_aligned_extrema"BezierSegment.axis_aligned_extremap  s      KK688B<"--))ii1q5!!T'*RV3	suu%EA!"%A1vz  #A 23	 & 88B<"--~~h'	)BBBr   )r   r   r   r   r   N)rB   rC   rD   rE   __doc__r   r   r   
deprecatedr   propertyr   r   r   r   r   rF   rA   r   r   r   r     s    
/>$ 
__MOO       : :>"Cr   r   c                 f   ^ [        U 5      m[        U4S jXS9u  p4[        XU-   S-  5      u  pVXV4$ )u2  
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                 &   > [        T" U 5      5      $ r0   r   )rq   bzs    r   <lambda>;split_bezier_intersecting_with_closedpath.<locals>.<lambda>  s    %1,r   )r   g       @)r   r   ry   )bezierr~   r   r   r   _left_rightr   s          @r   )split_bezier_intersecting_with_closedpathr     s@    , 
v	B7 1HFB 'vR2~>ME=r   c           	      r   SSK Jn  U R                  5       n[        U5      u  pgU" USS 5      nUn	Sn
SnU HF  u  pgUn
U[	        U5      S-  -  nU" USS 5      U:w  a  [
        R                  " U	SS U/5      n  OUn	MH     [        S5      eUR                  S5      n[        XU5      u  p[	        U5      S:X  a&  UR                  /nUR                  UR                  /nO[	        U5      S	:X  a<  UR                  UR                  /nUR                  UR                  UR                  /nOl[	        U5      S
:X  aR  UR                  UR                  UR                  /nUR                  UR                  UR                  UR                  /nO[        S5      eUSS nUSS nU R                  cW  U" [
        R                  " U R                   SU U/5      5      nU" [
        R                  " UU R                   US /5      5      nOU" [
        R                  " U R                   SU
 U/5      [
        R                  " U R                  SU
 U/5      5      nU" [
        R                  " UU R                   US /5      [
        R                  " UU R                  US /5      5      nU(       a  U(       d  UUnnUU4$ )zT
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   rM   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     sy   
 ""$Iy/J*RS/*LND	A(
	S_!!*RS/"l2...*=z)JKK#  ) EFF			W	%B;
IKD
4yA~kk]
{{DKK0	Takk4;;/
{{DKK=	Takk4;;<
{{DKKdkkJ;<<abJ(Kzzr~~t}}Ra'8*&EFGT]]125F'GHI r~~t}}Ud';Z&HI~~tzz%4'8*&EFH T]]125F'GHTZZ^'DEG \$gHr   c                 &   ^ ^^ US-  mU UU4S jnU$ )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                 4   > U u  pUT-
  S-  UT-
  S-  -   T:  $ )Nr   rA   )xyr`   ra   re   rf   r2s      r   _finside_circle.<locals>._f  s*    B1}B1},r11r   rA   )re   rf   r   r   r   s   ``  @r   inside_circler     s     
aB2 Ir   c                 F    X -
  X1-
  pTXD-  XU-  -   S-  nUS:X  a  gXF-  XV-  4$ )Nr{   r   )rd   rd   rA   )x0y0rj   rk   dxdyr[   s          r   get_cos_sinr     s8    Wbg	27	r!AAv626>r   c                     [         R                  " X5      n[         R                  " X#5      n[        XV-
  5      nXt:  a  g[        U[         R                  -
  5      U:  a  gg)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    sP    & ZZ!FZZ!F!F	Vbee^	y	(r   c           
         U S   u  p#U S   u  pEU S   u  pg[        X$-
  X5-
  XF-
  XW-
  5      nUS:X  a'  [        R                  " S5        [        X#Xg5      u  pXpO[        X#XE5      u  p[        XEXg5      u  p[	        X#XU5      u  pnn[	        XgXU5      u  nnnn [        XU	U
UUX5      u  nn[        UUU	U
UUX5      u  nnX4UU4UU4/nUU4UU4UU4/nUU4$ ! [         a#    SUU-   -  SUU-   -  nnSUU-   -  SUU-   -  nn NEf = f)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   rn   rb   rM   )bezier2widthc1xc1ycmxcmyc2xc2yparallel_testrP   rQ   rT   rU   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%ci&)i<M F	H$Ss8 %Ss8$Ss8 	#FE: -H	9 	#FE: -Hh	9
-h&.4h.4>(  0	9f06	906 @	9  %H%H%'I i(i(i(*J j  )  	

 8h&'80C)D  9y()3)i2G+H 	9	
s   'C *DDc                 F    SSU-  X-   -
  -  nSSU-  X-   -
  -  nX4Xg4XE4/$ )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   rA   )r  r  mmxmmyr  r  r  r  s           r   find_control_pointsr$  x  sA    
 C39%
&C
C39%
&CJ
SJ//r   c                    U S   u  pVU S   u  pxU S   u  p[        XVXx5      u  p[        XxX5      u  p[        XVXX-  5      u  nnnn[        XXX-  5      u  nnnnXW-   S-  Xh-   S-  nnXy-   S-  X-   S-  nnUU-   S-  UU-   S-  nn[        UUUU5      u  nn[        UUUUX-  5      u  nn n!n"[        UUUU UU5      n#[        UUU!U"UU5      n$U#U$4$ )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   rn   r$  )%r	  r
  w1wmw2r  r  r  r  c3xc3yrP   rQ   rT   rU   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_bezier2r;    sA    qzHCqzHCqzHC !34NF 34NF 	#FEJ? -Hh	9 	#FEJ? -Hh	9 )r!CI#3$D)r!CI#3$D4K2%tr'95E %T4t<Hh 	%(EJG 5J
K $Hh$.
$,h8I %Y	%0+%.	;J j  r   )rd         ?{Gz?)r=  )r=  F)gh㈵>)r<  r{   rd   )r   	functoolsr   r2   r   numpyr
   
matplotlibr   r   r+   r=   rM   r?   rb   rn   rs   ry   r   r   r   r   r   r   r  r   r$  r;  rA   r   r   <module>rA     s         .:,^ 23 3$	: 	B2
!& GKI)XAC ACJ .2D:z&<G!T00!r   