
    P/PhiJ                        d Z ddlmZ ddlZddlZddlZddlmZ ej	         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)_api   )maxsizec                     || k    rdS t          || |z
            }t          j        d|dz             }t          j        | dz   |z
  |z                                t
                    S )Nr      )minnparangeprodastypeint)nkis      Q/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/matplotlib/bezier.py_combr      sb     	1uuqAq1uA
	!QUA7AEAIq=!!((---    c                       e Zd ZdS )NonIntersectingPathExceptionN)__name__
__module____qualname__ r   r   r   r      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*.
    g-q=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 )Nr   ).0r   ad_bcs     r   	<genexpr>z#get_intersection.<locals>.<genexpr>9   s'      ::Aa%i::::::r   )abs
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yr   s                       @r   get_intersectionr6       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*.
            r   )cxcycos_tsin_tlengthr$   r%   r(   r)   x1y1x2y2s                r   get_normal_pointsrB   A   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   )betat	next_betas      r   _de_casteljau1rH   Z   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   r   r   rE   s     r   
<listcomp>z&split_de_casteljau.<locals>.<listcomp>k   s    ///Ta///r   c                     g | ]
}|d          S )rD   r   rK   s     r   rL   z&split_de_casteljau.<locals>.<listcomp>l   s    ;;;t$r(;;;r   )r
   asarrayrH   appendlenreversed)rE   rF   	beta_list	left_beta
right_betas        r   split_de_casteljaurU   _   s    
 :dDIdA&&t99>>	
 0/Y///I;;x	':':;;;Jj  r   r8         ?{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_closedpathrg   q   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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.

    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   )math	factorial_N)r   r   selfs     r   rL   z*BezierSegment.__init__.<locals>.<listcomp>   se     * * * !,,^A&&!a)H)HHJ * * *r   )r
   rN   _cpointsshapern   _dr   _ordersrangeT_px)ro   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   NrD   )r
   rN   powerouterrs   rv   ro   rF   s     r   __call__zBezierSegment.__call__   s^     JqMMq1udl44R4&899(..DL11259X> 	>r   c                 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_t   s     TT!WW~~r   c                     | j         S )z The control points of the curve.)rp   ro   s    r   rw   zBezierSegment.control_points   s     }r   c                     | j         S )zThe dimension of the curve.)rr   r   s    r   	dimensionzBezierSegment.dimension   s     wr   c                     | j         dz
  S )z@Degree of the polynomial. One less the number of control points.r   )rn   r   s    r   degreezBezierSegment.degree   s     w{r   c                 @   | j         }|dk    rt          j        dt                     | j        }t          j        |dz             dddf         }t          j        |dz             dddf         }d||z   z  t          ||          z  }t          ||          |z  |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   NrD   )r   warningswarnRuntimeWarningrw   r
   r   r   )ro   r   Pjr   	prefactors         r   polynomial_coefficientsz%BezierSegment.polynomial_coefficients   s    2 Kr66M 12@B B BIacNN111d7#IacNN47#1q5ME!QKK/	Q{{Y&**r   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 ]_\  }}t          j        |ddd                   }|                    |           |                    t          j	        ||                     `t          j
        |          }t          j
        |          }t          j        |          |dk    z  |dk    z  }	||	         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   NrD   r   )r   r
   arrayr   r   	enumerateru   rootsrO   	full_likeconcatenateisrealreal)
ro   r   CjdCjdimsr   r   pirin_ranges
             r   axis_aligned_extremaz"BezierSegment.axis_aligned_extrema  s1     K668B<<"--)i1Q34(2abb61su%% 	, 	,EArDDbD""ALLOOOKKQ**++++u%%~d##9U##uz2eqjAH~rwu~~h777r   N)r   r   r   __doc__ry   r~   r   propertyrw   r   r   r   r   r   r   r   ri   ri      s         / / /> > >$     X   X   X !+ !+ X!+F8 8 8 8 8r   ri   c                     t          |           }|j        }t          |||          \  }}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.
    )r_   g       @)ri   r   rg   rU   )	bezierr\   r_   bzr[   r]   r^   _left_rights	            r   )split_bezier_intersecting_with_closedpathr   <  sc    , 
v		B7,	C C C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      z*The path does not intersect with the patch)rD   r         zThis should never be reached)pathr   iter_segmentsnextrP   r
   r   r!   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   r   )xyr4   r5   r9   r:   r2s      r   _fzinside_circle.<locals>._f  s,    1B1}B1},r11r   r   )r9   r:   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 )NrY   r   )r8   r8   r   )x0y0r>   r?   dxdyr/   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   rD   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   rD   z8Lines do not intersect. A straight line is used instead.rY   )r   r   warn_externalr   rB   r6   r!   )bezier2widthc1xc1ycmxcmyc2xc2yparallel_testr$   r%   r(   r)   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.
    rY   r   r   )r   r   mmxmmyr   r   r   r   s           r   find_control_pointsr      sK    
 C39%
&C
C39%
&C#Jc
S#J//r   rY   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   rY   )r   rB   r   )%r   r   w1wmw2r   r   r   r   c3xc3yr$   r%   r(   r)   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  *  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   )r8   rV   rW   )rW   )rW   F)r   )rV   rY   r8   )r   	functoolsr   rl   r   numpyr
   
matplotlibr   	vectorizer   r!   r   r6   rB   rH   rU   rg   ri   r   r   r   r   r   r   r   r  r   r   r   <module>r     s                       
3. .  .	 	 	 	 	: 	 	 	  B  2  
! ! !& GKI) I) I) I)X|8 |8 |8 |8 |8 |8 |8 |8@ .2   F: : : :z  &     <G! G! G!T0 0 00! 0! 0! 0! 0! 0!r   