§
    †Ûg÷H  ã                   ó  — 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      úG/granary/edev/quantum/lib/python3.11/site-packages/matplotlib/bezier.pyÚ_combr      sb   € ð 	ˆ1‚u€uØˆqÝˆAˆq�1‰u‰Œ€AÝ
Œ	�!�Q˜‘UÑÔ€AÝŒ7�A˜‘E˜A‘I˜q‘=Ñ!Ô!×(Ò(­Ñ-Ô-Ð-ó    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                 ó   •— g | ]}|‰z  ‘ŒS r   r   )Ú.0r   Úad_bcs     €r   ú
<listcomp>z$get_intersection.<locals>.<listcomp>9   s   ø€ Ð:Ð:Ð: A�a˜%‘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ð �F�7€q€AØ�F�7€q€Aà�‰E�A˜‘E‰M€EÝ
ˆ5�z„z�EÒÐÝð Nñ Oô Oð 	Oð ��ˆ€BØˆR�ˆ€BØ:Ð:Ð:Ð:¨"¨b°"°bÐ)9Ð:Ñ:Ô:�N€BˆˆB�à
ˆY‰˜˜i™Ñ'€AØ
ˆY‰˜˜i™Ñ'€Aàˆaˆ4€Kr   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   € ð �‚|€|Ø�2�r˜2ˆ~Ðà˜U˜FˆF€FØ�V˜UˆF€Fà�f‰_˜rÑ! 6¨F¡?°RÑ#7ˆ€BØ�f‰_˜rÑ! 6¨F¡?°RÑ#7ˆ€Bàˆr�2�rˆ>Ðr   c                 óB   — | d d…         d|z
  z  | dd …         |z  z   }|S )Néÿÿÿÿr   r   )ÚbetaÚtÚ	next_betas      r   Ú_de_casteljau1rH   Z   s/   € Ø�S�b�S”	˜Q ™UÑ# d¨1¨2¨2¤h°¡lÑ2€IØÐ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   r   z&split_de_casteljau.<locals>.<listcomp>k   s   € Ð/Ð/Ð/˜T��a”Ð/Ð/Ð/r   c                 ó   — g | ]
}|d          ‘ŒS )rD   r   rK   s     r   r   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_casteljaurT   _   s”   € õ
 Œ:�dÑÔ€DØ�€IðÝ˜d AÑ&Ô&ˆØ×Ò˜ÑÔÐÝˆt‰9Œ9˜Š>ˆ>Øð	ð
 0Ð/ YÐ/Ñ/Ô/€IØ;Ð;¥x°	Ñ':Ô':Ð;Ñ;Ô;€Jà�jÐ Ð r   r8   ç      ð?ç{®Gáz„?c                 óf  —  | |¦  «        } | |¦  «        } ||¦  «        } ||¦  «        }||k    r||k    rt          d¦  «        ‚	 t          j        |d         |d         z
  |d         |d         z
  ¦  «        |k     r||fS d||z   z  }	 | |	¦  «        }
 ||
¦  «        }||z  r|	}|
}n|	}|
}|}Œj)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_closedpathrf   q   s  € ðL Ð˜bÑ!Ô!€EØ
Ð
˜BÑ
Ô
€Cà$Ð$ UÑ+Ô+€LØ"Ð" 3Ñ'Ô'€Jà�zÒ!Ð! e¨s¢l lÝ*ØAñCô Cð 	Cð)õ Œ8�E˜!”H˜s 1œvÑ% u¨Q¤x°#°a´&Ñ'8Ñ9Ô9¸IÒEÐEØ�r�6ˆMð ˜"˜r™'‘?ˆØ"Ð" 8Ñ,Ô,ˆØ)Ð)¨&Ñ1Ô1ˆà˜-Ñ'ð 	)ØˆBØˆCˆCàˆBØˆEØ(ˆLð#)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   r   z*BezierSegment.__init__.<locals>.<listcomp>Ã   se   ø€ ð *ð *ð *àõ ” ¤¨!¡Ñ,Ô,Ý”^ AÑ&Ô&­¬¸¼À!¹Àa¹Ñ)HÔ)HÑHñJð *ð *ð *r   )r
   rM   Ú_cpointsÚshaperm   Ú_dr   Ú_ordersÚrangeÚTÚ_px)rn   Úcontrol_pointsÚcoeffs   `  r   Ú__init__zBezierSegment.__init__¿   sƒ   ø€ Ýœ
 >Ñ2Ô2ˆŒØœ=Ô.ÑˆŒ�”Ý”y ¤Ñ)Ô)ˆŒð*ð *ð *ð *å ¤™.œ.ð*ñ *ô *ˆð ”M”O eÑ+Ô.ˆŒˆˆ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
   rM   ÚpowerÚouterrr   ru   ©rn   rF   s     r   Ú__call__zBezierSegment.__call__È   s^   € õ ŒJ�q‰MŒMˆÝ”—’˜q 1™u d¤l°4°4°R°4Ô&8Ñ9Ô9Ý”(—.’.  D¤LÑ1Ô1ñ2Ø59´Xñ>ð 	>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   € õ �T�T˜!‘W”W‰~Œ~Ðr   c                 ó   — | j         S )z The control points of the curve.)ro   ©rn   s    r   rv   zBezierSegment.control_pointsà   s   € ð Œ}Ðr   c                 ó   — | j         S )zThe dimension of the curve.)rq   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   )rm   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ÚRuntimeWarningrv   r
   r   r   )rn   r   ÚPÚjr   Ú	prefactors         r   Úpolynomial_coefficientsz%BezierSegment.polynomial_coefficientsï   s©   € ð2 ŒKˆàˆrŠ6ˆ6ÝŒMð 1Ý2@ñBô Bð BàÔˆÝŒI�a˜‘c‰NŒN˜1˜1˜1˜d˜7Ô#ˆÝŒI�a˜‘c‰NŒN˜4   ˜7Ô#ˆØ˜1˜q™5‘M¥E¨!¨Q¡K¤KÑ/ˆ	Ý�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   Ú	enumeratert   ÚrootsrN   Ú	full_likeÚconcatenateÚisrealÚreal)
rn   r   ÚCjÚdCjÚdimsr“   r   ÚpiÚrÚin_ranges
             r   Úaxis_aligned_extremaz"BezierSegment.axis_aligned_extrema  s1  € ð  ŒKˆØ�Š6ˆ6Ý”8˜B‘<”<¥¤¨"¡¤Ð-Ð-ØÔ)ˆÝŒi˜˜1˜Q™3ÑÔ    4 Ô(¨2¨a¨b¨b¬6Ñ1ˆØˆØˆÝ˜sœuÑ%Ô%ð 	,ð 	,‰EˆAˆrÝ”˜˜D˜D˜b˜DœÑ"Ô"ˆAØ�LŠL˜‰OŒOˆOØ�KŠK�œ Q¨Ñ*Ô*Ñ+Ô+Ð+Ð+Ý”˜uÑ%Ô%ˆÝŒ~˜dÑ#Ô#ˆÝ”9˜UÑ#Ô# u°¢zÑ2°e¸q²jÑAˆØ�HŒ~�rœw u™~œ~¨hÔ7Ð7Ð7r   N)r   r   r   Ú__doc__rx   r}   r€   Úpropertyrv   r„   r†   r�   rž   r   r   r   rh   rh   µ   sÇ   € € € € € ðð ð/ð /ð /ð>ð >ð >ð$ð ð ð ðð ñ „Xðð ðð ñ „Xðð ðð ñ „Xðð ð!+ð !+ñ „Xð!+ðF8ð 8ð 8ð 8ð 8r   rh   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       @)rh   r€   rf   rT   )	Úbezierr[   r^   ÚbzrZ   r\   r]   Ú_leftÚ_rights	            r   Ú)split_bezier_intersecting_with_closedpathr¦   4  sc   € õ, 
�vÑ	Ô	€BØœÐå7ØÐ,¸	ðCñ Cô C�F€Bˆõ ' v°°R±¸2©~Ñ>Ô>�M€Eˆ6Ø�&ˆ=Ð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}n‡t	          |¦  «        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   )ÚPathéþÿÿÿNr   é   z*The path does not intersect with the patch)rD   rª   é   é   zThis should never be reached)Úpathr¨   Úiter_segmentsÚnextrO   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Ê   W  sæ  € ð
 ÐÐÐÐÐØ×"Ò"Ñ$Ô$€Iå˜y™/œ/Ñ€J�Ø�6˜* R S Sœ/Ñ*Ô*€Là€Nà€DØ	€Aà(ð Gð GÑˆ
�GØˆØ	�S�‰_Œ_ Ñ!Ñ!ˆØˆ6�*˜R˜S˜S”/Ñ"Ô" lÒ2Ð2Ýœ.¨.¸¸¸Ô*=¸zÐ)JÑKÔKˆKØˆEØ#ˆˆåÐEÑFÔFÐFà	×	Ò	˜WÑ	%Ô	%€BÝ;Ø
ˆF�Iñô �K€Dˆ%å
ˆ4�y„y�A‚~€~Ø”k�]ˆ
Ø”{ D¤KÐ0ˆˆÝ	ˆT‰Œ�aŠˆØ”k 4¤;Ð/ˆ
Ø”{ D¤K°´Ð=ˆˆÝ	ˆT‰Œ�aŠˆØ”k 4¤;°´Ð<ˆ
Ø”{ D¤K°´¸d¼kÐJˆˆåÐ;Ñ<Ô<Ð<à�a�b�b”€JØ˜˜˜”(€Kà„zÐØ�$•r”~ t¤}°R°a°RÔ'8¸*Ð&EÑFÔFÑGÔGˆØ�4�œ¨°T´]À1À2À2Ô5FÐ'GÑHÔHÑIÔIˆˆð �$•r”~ t¤}°U°d°UÔ';¸ZÐ&HÑIÔIÝ”~ t¤z°%°4°%Ô'8¸*Ð&EÑFÔFñHô Hˆð �4�œ¨°T´]À1À2À2Ô5FÐ'GÑHÔHÝœ¨°T´ZÀÀÀ´^Ð'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 )NrX   r   )r8   r8   r   )Úx0Úy0r>   r?   ÚdxÚdyr/   s          r   Úget_cos_sinrÖ   §  sJ   € Ø�"‰W�b˜2‘gˆ€BØ	ˆb‰�2˜‘7Ñ	˜rÑ!€AàˆA‚v€vØˆxØ�‰6�2˜‘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Ý	ˆV•b”e‰^Ñ	Ô	˜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.rX   )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  € ð �qŒz�H€CˆØ�qŒz�H€CˆØ�qŒz�H€Cˆå% c¨C¡i°°s±Ø&)¨C¡i°°s±ñ<ô <€Mð ˜ÒÐÝÔØFñ	Hô 	Hð 	Hå$ S¨#¨s°CÑ8Ô8‰ˆ�Ø �ˆˆõ % S¨#¨s°CÑ8Ô8‰ˆ�Ý$ S¨#¨s°CÑ8Ô8‰ˆ�õ 	˜#˜s F¨F°EÑ:Ô:ñ -€Hˆh˜	 9õ 	˜#˜s F¨F°EÑ:Ô:ñ -€Hˆh˜	 9ð
Ý-¨h¸À&Ø.4°hÀØ.4°fñ>ô >Ñˆ�(õ  0°	¸9ÀfØ06¸	À9Ø06¸ñ @ô  @Ñˆ	�9�9øõ ð 	
ð 	
ð 	
ð
 �8˜hÑ&Ñ'¨°¸8Ñ0CÑ)Dð ˆð �9˜yÑ(Ñ)¨3°)¸iÑ2GÑ+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.
    rX   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   rX   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ª   rX   )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…  € ð �qŒz�H€CˆØ�qŒz�H€CˆØ�qŒz�H€Cˆõ !  c¨3°Ñ4Ô4�N€FˆFÝ   c¨3°Ñ4Ô4�N€FˆFõ 	˜#˜s F¨F°E¸B±JÑ?Ô?ñ -€Hˆh˜	 9õ 	˜#˜s F¨F°E¸B±JÑ?Ô?ñ -€Hˆh˜	 9ð ˜‘)˜rÑ! C¨#¡I°Ñ#3ˆ$€DØ˜‘)˜rÑ! C¨#¡I°Ñ#3ˆ$€DØ˜4‘K 2Ñ%¨¨t©°rÑ'9ˆ5€Eõ % T¨4°°tÑ<Ô<Ñ€Hˆhõ 	˜% ¨°(¸EÀB¹JÑGÔGñ 5€J�
˜K¨õ $ H¨hØ$.°
Ø$,¨hñ8ô 8€Iõ % Y°	Ø%0°+Ø%.°	ñ;ô ;€Jð �jÐ Ð r   )r8   rU   rV   )rV   )rV   F)r×   )rU   rX   r8   )rŸ   Ú	functoolsr   rk   r‰   Únumpyr
   Ú
matplotlibr   Ú	vectorizer   r!   r   r6   rB   rH   rT   rf   rh   r¦   rÊ   rÐ   rÖ   rá   rû   rÿ   r  r   r   r   ú<module>r     sá  ððð ð  Ð Ð Ð Ð Ð Ø €€€Ø €€€à Ð Ð Ð à Ð Ð Ð Ð Ð ð „Ø
€�3ÐÑÔð.ð .ñ Ôñ „ð.ð	ð 	ð 	ð 	ð 	 :ñ 	ô 	ð 	ðð ð ðBð ð ð2ð ð ð
!ð !ð !ð& GKðA)ð A)ð A)ð A)ðH|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   