)Uc@s(dZddlZddlmZddlmZddlmZddl Z dZ dZ dZ d Z d d d d ZdddYZd dZd d d dZd edZdZdZddZdZddZdZd dd dZdZdZdS(sO A module providing some utility functions regarding bezier path manipulation. iN(tsqrt(tPath(txorcCs||||}||||} || } } || } } | | | | }|dkrmtdn| | }}| | }}g||||gD]}||^q\}}}}|||| }|||| }||fS(s return a intersecting point between a line through (cx1, cy1) and having angle t1 and a line through (cx2, cy2) and angle t2. gsGiven lines do not intersect(t ValueError(tcx1tcy1tcos_t1tsin_t1tcx2tcy2tcos_t2tsin_t2t line1_rhst line2_rhstatbtctdtad_bcta_tb_tc_td_tktxty((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytget_intersections  5c Cs|dkr||||fS|| }}| |}}||||||} } ||||||} } | | | | fS(s For a line passing through (*cx*, *cy*) and having a angle *t*, return locations of the two points located along its perpendicular line at the distance of *length*. g(( tcxtcytcos_ttsin_ttlengthRRR R tx1ty1tx2ty2((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytget_normal_points1s cCs"|d d||d|}|S(Nii((tbetattt next_beta((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt_de_casteljau1NscCstj|}|g}x<trVt||}|j|t|dkrPqqWg|D]}|d^q^}gt|D]}|d^q}||fS(ssplit a bezier segment defined by its controlpoints *beta* into two separate segment divided at *t* and return their control points. iii(tnptasarraytTrueR(tappendtlentreversed(R%R&t beta_listt left_betat right_beta((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytsplit_de_casteljauRs   #gg?g{Gz?c Cs||}||}||}||}t||sNtdnx|d|dd|d|dd|dkr||fSd||} || } || } t|| r| }| }| }qQ| }| }| }qQdS(s$ Find a parameter t0 and t1 of the given bezier path which bounds the intersecting points with a provided closed path(*inside_closedpath*). Search starts from *t0* and *t1* and it uses a simple bisecting algorithm therefore one of the end point must be inside the path while the orther doesn't. The search stop when |t0-t1| gets smaller than the given tolerence. value for - bezier_point_at_t : a function which returns x, y coordinates at *t* - inside_closedpath : return True if the point is insed the path s6the segment does not seemed to intersect with the pathiiig?N(RR( tbezier_point_at_ttinside_closedpathtt0tt1t tolerencetstarttendt start_insidet end_insidetmiddle_ttmiddlet middle_inside((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt*find_bezier_t_intersecting_with_closedpathis&    4    t BezierSegmentcBsqeZdZiejddgd6ejdddgd6ejddddgd6ZdZdZRS( s: A simple class of a 2-dimensional bezier segment g?ig@ig@icCst|}tj||_tj|d}tj|}|dddf}|dddf}|||_|||_dS(s *control_points* : location of contol points. It needs have a shpae of n * 2, where n is the order of the bezier line. 1<= n <= 3 is supported. iNi( R-R)taranget_ordersR@t _binom_coeffR*t_pxt_py(tselftcontrol_pointst_ot_coefft_control_pointstxxtyy((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt__init__s  cCsutjd||jddd}tj||j}||}t||j}t||j}||fS(sevaluate a point at tg?Ni(R)tpowerRBtsumRDRE(RFR&tone_minus_t_powerstt_powerstttt_xt_y((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt point_at_ts & (t__name__t __module__t__doc__R)tarrayRCRMRU(((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyR@s  c CsWt|}|j}t||d|\}}t|||d\}}||fS(s bezier : control points of the bezier segment inside_closedpath : a function which returns true if the point is inside the path R7g@(R@RUR?R2( tbezierR4R7tbzR3R5R6t_leftt_right((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt)split_bezier_intersecting_with_closedpaths  c sG|\fd}t||d|d|d|dS(s Find a radius r (centered at *xy*) between *rmin* and *rmax* at which it intersect with the path. inside_closedpath : function cx, cy : center cos_t, sin_t : cosine and sine for the angle rmin, rmax : cs||fS(N((tr(RRRR(sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt_fsR5R6R7N(R?(R4txyRRtrmintrmaxR7R`((RRRRsD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt find_r_to_boundary_of_closedpaths  cCs|j}|j\}}||d}d}|} tj} d} d} xd|D]\\}}| } | t|d7} ||d|kr| | d|g}Pn|} qVW|dkrtdnt|ddd|ddd} t| ||\}}t|dkrEt j g}t j t j g}nt|dkrt j t j g}t j t j t j g}nTt|dkrt j t j t j g}t j t j t j t j g}n t|d}|}|jdkr9t | |j| |g}t | ||j| g}njt | |j| |g| |j| |g}t | ||j| g| ||j| g}|r|tkr||}}n||fS( sW divide a path into two segment at the point where inside(x, y) becomes False. iiiis2The path does not seem to intersect with the patchNii(t iter_segmentstnexttNoneR)t concatenateR-RtzipR^RtLINETOtMOVETOtCURVE3tCURVE4tcodestverticestFalse(tpathtinsideR7t reorder_inoutt path_itert ctl_pointstcommandt begin_insidet bezier_pathtctl_points_oldtconcattioldtitbptlefttrightt codes_leftt codes_rightt verts_leftt verts_righttpath_intpath_out((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytsplit_path_inoutsV    ) !  "cs#|dfd}|S(Nics*|\}}|d|dkS(Ni((RaRR(RRtr2(sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyR`9s ((RRR_R`((RRRsD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt inside_circle7s cCs=||||}}||||d}||||fS(Ng?((tx0ty0R R!tdxtdyR((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt get_cos_sinBsgh㈵>cCsotj||}tj||}tj||}||krGdStj|tj|krgdStSdS(s returns * 1 if two lines are parralel in same direction * -1 if two lines are parralel in opposite direction * 0 otherwise iiN(R)tarctan2tabstpiRp(tdx1tdy1tdx2tdy2R7ttheta1ttheta2tdtheta((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytcheck_if_parallelGs c Cs|d\}}|d\}}|d\}}t||||||||}|dkrtjdt||||\} } | | } } n6t||||\} } t||||\} } t||| | |\} }}}t||| | |\}}}}|dkr`d| |d||}}d||d||}}nNt| || | ||| | \}}t||| | ||| | \}}| |f||f||fg}||f||f||fg}||fS(s Given the quadraitc bezier control points *bezier2*, returns control points of quadrativ bezier lines roughly parralel to given one separated by *width*. iiiis8Lines do not intersect. A straight line is used instead.g?(RtwarningstwarnRR$R(tbezier2twidthtc1xtc1ytcmxtcmytc2xtc2yt parallel_testRRR R tc1x_lefttc1y_leftt c1x_rightt c1y_righttc2x_lefttc2y_leftt c2x_rightt c2y_righttcmx_lefttcmy_leftt cmx_rightt cmy_rightt path_leftt path_right((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyt get_parallelsXs, %  $$  !!g?cCs|d\}}|d\}}|d\}}||} } ||} } t| | d| | d} | | | | | | }}t| | |||\}}}}||d||d}}||d||d}}t||d||d} ||| ||| }}t||||||\}}}}||f||f||fg}||f||f||fg}||fS(s Being similar to get_parallels, returns control points of two quadrativ bezier lines having a width roughly parralel to given one separated by *width*. iiig@(RR$(RRt shrink_factortxx1tyy1txx2tyy2txx3tyy3RRRRtdistRRR R!R"R#txx12tyy12txx23tyy23txm1tym1txm2tym2tl_plustl_minus((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytmake_wedged_bezier2s    $ (!!cCsKdd|||}dd|||}||f||f||fgS(s Find control points of the bezier line throught c1, mm, c2. We simply assume that c1, mm, c2 which have parameteric value 0, 0.5, and 1. g?i((RRtmmxtmmyRRRR((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pytfind_control_pointssc%Cs|d\}}|d\}}|d\} } t||||\} } t||| | \} }t||| | ||\}}}}t| | | |||\}}}}||d||d}}|| d|| d}}||d||d}}t||||\}}t||||||\}} }!}"t|||| ||}#t|||!|"||}$|#|$fS(s Being similar to get_parallels, returns control points of two quadrativ bezier lines having a width roughly parralel to given one separated by *width*. iiig?(RR$R(%RRtw1twmtw2RRRRtc3xtc3yRRR R RRRRtc3x_lefttc3y_leftt c3x_rightt c3y_righttc12xtc12ytc23xtc23ytc123xtc123ytcos_t123tsin_t123t c123x_leftt c123y_leftt c123x_rightt c123y_rightRR((sD/opt/alt/python27/lib64/python2.7/site-packages/matplotlib/bezier.pyRs&(((    cCsf|j}|dkr^tj|jjd d}|jtjtj |ds0     1* G   @ ! 6