Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
3 2øªj€•ã@s6dZddlmZmZmZddlmZddlZddlm Z e dddd gƒZ d d d d ddddddddddddddddddd d!d"gZ dhd$d„Z d%d&„Z d'd(„Zdid)d„Zd*Zd+Zd,d-„Zd.d/„Zd0d„Zd1d„Zd2d „Zd3d „Zd4d„Zd5d „Zd6d „Zd7d„Zd8d„Zd9d„Zd:d„Zd;d„Zd„Z!d?d@„Z"ddAlm#Z#m$Z$m%Z%m&Z&e#fdBd„Z'dCd„Z(dDdE„Z)dFdG„Z*dHdI„Z+dJdK„Z,dLd„Z-dMd„Z.dNd„Z/dOd„Z0dPdQ„Z1dRdS„Z2dTd„Z3dUdV„Z4dWdX„Z5dYd „Z6dZd[„Z7d\d]„Z8djd_d`„Z9dad!„Z:dbd"„Z;dcdd„Zdgk�r2ddl?Z?ddl@Z@e?jAe@jBƒjCƒdS)kzNfontTools.misc.bezierTools.py -- tools for working with Bezier path segments. é)Ú calcBoundsÚsectRectÚrectArea)ÚIdentityN)Ú namedtupleÚ IntersectionÚptÚt1Út2ÚapproximateCubicArcLengthÚapproximateCubicArcLengthCÚapproximateQuadraticArcLengthÚapproximateQuadraticArcLengthCÚcalcCubicArcLengthÚcalcCubicArcLengthCÚcalcQuadraticArcLengthÚcalcQuadraticArcLengthCÚcalcCubicBoundsÚcalcQuadraticBoundsÚ splitLineÚsplitQuadraticÚ splitCubicÚsplitQuadraticAtTÚ splitCubicAtTÚsolveQuadraticÚ solveCubicÚquadraticPointAtTÚ cubicPointAtTÚ linePointAtTÚsegmentPointAtTÚlineLineIntersectionsÚcurveLineIntersectionsÚcurveCurveIntersectionsÚsegmentSegmentIntersectionsç{®Gázt?cCs tt|Žt|Žt|Žt|Ž|ƒS)aÄCalculates the arc length for a cubic Bezier segment. Whereas :func:`approximateCubicArcLength` approximates the length, this function calculates it by "measuring", recursively dividing the curve until the divided segments are shorter than ``tolerance``. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. tolerance: Controls the precision of the calcuation. Returns: Arc length value. )rÚcomplex)Úpt1Úpt2Úpt3Úpt4Ú tolerance©r+ú?/tmp/pip-build-_d5lkt3n/fonttools/fontTools/misc/bezierTools.pyr*scCs\|d|||d}||||d}|||d|||f|||||d|ffS)NégÀ?gà?r+)Úp0Úp1Úp2Úp3ZmidZderiv3r+r+r,Ú_split_cubic_into_two=sr2c Cszt||ƒ}t||ƒt||ƒt||ƒ}|||krH||dSt||||ƒ\}}t|f|žŽt|f|žŽSdS)Ngà?)Úabsr2Ú_calcCubicArcLengthCRecurse) Úmultr.r/r0r1ÚarchZboxZoneZtwor+r+r,r4Fs $  r4cCsdd|}t|||||ƒS)zôCalculates the arc length for a cubic Bezier segment. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. tolerance: Controls the precision of the calcuation. Returns: Arc length value. gð?gø?)r4)r&r'r(r)r*r5r+r+r,rRs ég»½×Ùß|Û=cCs||jƒjS)N)Ú conjugateÚreal)Úv1Úv2r+r+r,Ú_dotdsr<cCs(|tj|ddƒdtj|ƒdS)Néé)ÚmathÚsqrtÚasinh)Úxr+r+r,Ú _intSecAtanhsrCcCstt|Žt|Žt|ŽƒS)ažCalculates the arc length for a quadratic Bezier segment. Args: pt1: Start point of the Bezier as 2D tuple. pt2: Handle point of the Bezier as 2D tuple. pt3: End point of the Bezier as 2D tuple. Returns: Arc length value. Example:: >>> calcQuadraticArcLength((0, 0), (0, 0), (0, 0)) # empty segment 0.0 >>> calcQuadraticArcLength((0, 0), (50, 0), (80, 0)) # collinear points 80.0 >>> calcQuadraticArcLength((0, 0), (0, 50), (0, 80)) # collinear points vertical 80.0 >>> calcQuadraticArcLength((0, 0), (50, 20), (100, 40)) # collinear points 107.70329614269008 >>> calcQuadraticArcLength((0, 0), (0, 100), (100, 0)) 154.02976155645263 >>> calcQuadraticArcLength((0, 0), (0, 50), (100, 0)) 120.21581243984076 >>> calcQuadraticArcLength((0, 0), (50, -10), (80, 50)) 102.53273816445825 >>> calcQuadraticArcLength((0, 0), (40, 0), (-40, 0)) # collinear points, control point outside 66.66666666666667 >>> calcQuadraticArcLength((0, 0), (40, 0), (0, 0)) # collinear points, looping back 40.0 )rr%)r&r'r(r+r+r,rns cCsÞ||}||}||}|d}t|ƒ}|dkr>> calcQuadraticBounds((0, 0), (50, 100), (100, 0)) (0, 0, 100, 50.0) >>> calcQuadraticBounds((0, 0), (100, 0), (100, 100)) (0.0, 0.0, 100, 100) g@rcsTg|]L}d|kodknrˆ||ˆ|ˆˆ||ˆ|ˆf‘qS)rr>r+)Ú.0Út)ÚaxÚayÚbxÚbyÚcxÚcyr+r,ú þsz'calcQuadraticBounds..)ÚcalcQuadraticParametersÚappendr)r&r'r(Zax2Zay2ÚrootsÚpointsr+)rNrOrPrQrRrSr,rãs cCstt|Žt|Žt|Žt|ŽƒS)a®Approximates the arc length for a cubic Bezier segment. Uses Gauss-Lobatto quadrature with n=5 points to approximate arc length. See :func:`calcCubicArcLength` for a slower but more accurate result. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. Returns: Arc length value. Example:: >>> approximateCubicArcLength((0, 0), (25, 100), (75, 100), (100, 0)) 190.04332968932817 >>> approximateCubicArcLength((0, 0), (50, 0), (100, 50), (100, 100)) 154.8852074945903 >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (150, 0)) # line; exact result should be 150. 149.99999999999991 >>> approximateCubicArcLength((0, 0), (50, 0), (100, 0), (-50, 0)) # cusp; exact result should be 150. 136.9267662156362 >>> approximateCubicArcLength((0, 0), (50, 0), (100, -50), (-50, 0)) # cusp 154.80848416537057 )r r%)r&r'r(r)r+r+r,r sc Cs”t||ƒd}td|d|d|d|ƒ}t||||ƒd}td|d|d|d|ƒ}t||ƒd}|||||S) z¹Approximates the arc length for a cubic Bezier segment. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as complex numbers. Returns: Arc length value. g333333Ã?g�c’‰1ãá?g8Ø5$t×Ô?guÁ|Yù¿Ê?gæâ#$ï˜?gÑ?g�c’‰1ãá¿gæâ#$)r3) r&r'r(r)rKr:r;Zv3Úv4r+r+r,r #s""c sªt||||ƒ\\‰‰\‰‰\‰‰\‰‰ˆd}ˆd}ˆd}ˆd}dd„t||ˆƒDƒ}dd„t||ˆƒDƒ} || } ‡‡‡‡‡‡‡‡fdd„| Dƒ||g} t| ƒS)aXCalculates the bounding rectangle for a quadratic Bezier segment. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. Returns: A four-item tuple representing the bounding rectangle ``(xMin, yMin, xMax, yMax)``. Example:: >>> calcCubicBounds((0, 0), (25, 100), (75, 100), (100, 0)) (0, 0, 100, 75.0) >>> calcCubicBounds((0, 0), (50, 0), (100, 50), (100, 100)) (0.0, 0.0, 100, 100) >>> print("%f %f %f %f" % calcCubicBounds((50, 0), (0, 100), (100, 100), (50, 0))) 35.566243 0.000000 64.433757 75.000000 g@g@cSs(g|] }d|kodknr|‘qS)rr>r+)rLrMr+r+r,rT_sz#calcCubicBounds..cSs(g|] }d|kodknr|‘qS)rr>r+)rLrMr+r+r,rT`scs\g|]T}ˆ|||ˆ||ˆ|ˆˆ|||ˆ||ˆ|ˆf‘qSr+r+)rLrM)rNrOrPrQrRrSÚdxÚdyr+r,rTds)ÚcalcCubicParametersrr) r&r'r(r)Zax3Zay3Zbx2Zby2ZxRootsZyRootsrWrXr+)rNrOrPrQrRrSrZr[r,rGs& cCs¨|\}}|\}}||}||} |} |} || f|} | dkrF||fgS|| | f|| } d| koldknrš|| | | | | f}||f||fgS||fgSdS)a Split a line at a given coordinate. Args: pt1: Start point of line as 2D tuple. pt2: End point of line as 2D tuple. where: Position at which to split the line. isHorizontal: Direction of the ray splitting the line. If true, ``where`` is interpreted as a Y coordinate; if false, then ``where`` is interpreted as an X coordinate. Returns: A list of two line segments (each line segment being two 2D tuples) if the line was successfully split, or a list containing the original line. Example:: >>> printSegments(splitLine((0, 0), (100, 100), 50, True)) ((0, 0), (50, 50)) ((50, 50), (100, 100)) >>> printSegments(splitLine((0, 0), (100, 100), 100, True)) ((0, 0), (100, 100)) >>> printSegments(splitLine((0, 0), (100, 100), 0, True)) ((0, 0), (0, 0)) ((0, 0), (100, 100)) >>> printSegments(splitLine((0, 0), (100, 100), 0, False)) ((0, 0), (0, 0)) ((0, 0), (100, 100)) >>> printSegments(splitLine((100, 0), (0, 0), 50, False)) ((100, 0), (50, 0)) ((50, 0), (0, 0)) >>> printSegments(splitLine((0, 100), (0, 0), 50, True)) ((0, 100), (0, 50)) ((0, 50), (0, 0)) rr>Nr+)r&r'ÚwhereÚ isHorizontalZpt1xZpt1yZpt2xZpt2yrNrOrPrQrGrMZmidPtr+r+r,rms$  c Csbt|||ƒ\}}}t|||||||ƒ}tdd„|Dƒƒ}|sP|||fgSt|||f|žŽS)aSplit a quadratic Bezier curve at a given coordinate. Args: pt1,pt2,pt3: Control points of the Bezier as 2D tuples. where: Position at which to split the curve. isHorizontal: Direction of the ray splitting the curve. If true, ``where`` is interpreted as a Y coordinate; if false, then ``where`` is interpreted as an X coordinate. Returns: A list of two curve segments (each curve segment being three 2D tuples) if the curve was successfully split, or a list containing the original curve. Example:: >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 150, False)) ((0, 0), (50, 100), (100, 0)) >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, False)) ((0, 0), (25, 50), (50, 50)) ((50, 50), (75, 50), (100, 0)) >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, False)) ((0, 0), (12.5, 25), (25, 37.5)) ((25, 37.5), (62.5, 75), (100, 0)) >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 25, True)) ((0, 0), (7.32233, 14.6447), (14.6447, 25)) ((14.6447, 25), (50, 75), (85.3553, 25)) ((85.3553, 25), (92.6777, 14.6447), (100, -7.10543e-15)) >>> # XXX I'm not at all sure if the following behavior is desirable: >>> printSegments(splitQuadratic((0, 0), (50, 100), (100, 0), 50, True)) ((0, 0), (25, 50), (50, 50)) ((50, 50), (50, 50), (50, 50)) ((50, 50), (75, 50), (100, 0)) css*|]"}d|kodknr|VqdS)rr>Nr+)rLrMr+r+r,ú Ísz!splitQuadratic..)rUrÚsortedÚ_splitQuadraticAtT) r&r'r(r]r^rGrHÚcÚ solutionsr+r+r,r¦s# c Cspt||||ƒ\}}}} t||||||| ||ƒ} tdd„| Dƒƒ} | s\||||fgSt|||| f| žŽS)aÞSplit a cubic Bezier curve at a given coordinate. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. where: Position at which to split the curve. isHorizontal: Direction of the ray splitting the curve. If true, ``where`` is interpreted as a Y coordinate; if false, then ``where`` is interpreted as an X coordinate. Returns: A list of two curve segments (each curve segment being four 2D tuples) if the curve was successfully split, or a list containing the original curve. Example:: >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 150, False)) ((0, 0), (25, 100), (75, 100), (100, 0)) >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 50, False)) ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) >>> printSegments(splitCubic((0, 0), (25, 100), (75, 100), (100, 0), 25, True)) ((0, 0), (2.29379, 9.17517), (4.79804, 17.5085), (7.47414, 25)) ((7.47414, 25), (31.2886, 91.6667), (68.7114, 91.6667), (92.5259, 25)) ((92.5259, 25), (95.202, 17.5085), (97.7062, 9.17517), (100, 1.77636e-15)) css*|]"}d|kodknr|VqdS)rr>Nr+)rLrMr+r+r,r_òszsplitCubic..)r\rr`Ú_splitCubicAtT) r&r'r(r)r]r^rGrHrbrErcr+r+r,rÓs cGs$t|||ƒ\}}}t|||f|žŽS)a•Split a quadratic Bezier curve at one or more values of t. Args: pt1,pt2,pt3: Control points of the Bezier as 2D tuples. *ts: Positions at which to split the curve. Returns: A list of curve segments (each curve segment being three 2D tuples). Examples:: >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5)) ((0, 0), (25, 50), (50, 50)) ((50, 50), (75, 50), (100, 0)) >>> printSegments(splitQuadraticAtT((0, 0), (50, 100), (100, 0), 0.5, 0.75)) ((0, 0), (25, 50), (50, 50)) ((50, 50), (62.5, 50), (75, 37.5)) ((75, 37.5), (87.5, 25), (100, 0)) )rUra)r&r'r(ÚtsrGrHrbr+r+r,røsc Gs*t||||ƒ\}}}}t||||f|žŽS)aSplit a cubic Bezier curve at one or more values of t. Args: pt1,pt2,pt3,pt4: Control points of the Bezier as 2D tuples. *ts: Positions at which to split the curve. Returns: A list of curve segments (each curve segment being four 2D tuples). Examples:: >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5)) ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) ((50, 75), (68.75, 75), (87.5, 50), (100, 0)) >>> printSegments(splitCubicAtT((0, 0), (25, 100), (75, 100), (100, 0), 0.5, 0.75)) ((0, 0), (12.5, 50), (31.25, 75), (50, 75)) ((50, 75), (59.375, 75), (68.75, 68.75), (77.3438, 56.25)) ((77.3438, 56.25), (85.9375, 43.75), (93.75, 25), (100, 0)) )r\rd) r&r'r(r)rerGrHrbrEr+r+r,rscGst|ƒ}g}|jddƒ|jdƒ|\}}|\}}|\} } xÒtt|ƒdƒD]¾} || } || d} | | }||}||}||}d|| ||}d|| ||}| | }|||| | }|||| | }t||f||f||fƒ\}}}|j|||fƒqLW|S)Nrggð?r>r=)ÚlistÚinsertrVÚrangeÚlenÚcalcQuadraticPoints)rGrHrbreÚsegmentsrNrOrPrQrRrSÚir r ÚdeltaÚdelta_2Úa1xÚa1yÚb1xÚb1yÚt1_2Úc1xÚc1yr&r'r(r+r+r,ra(s,   rac"Gsˆt|ƒ}|jddƒ|jdƒg}|\}}|\}} |\} } |\} } �x>tt|ƒdƒD�](}||}||d}||}||}||}||}||}||}||}d||||}d||| |}d||| d|||}d| || d|||}||||| || }||| || || }t||f||f||f||fƒ\}}} }!|j||| |!fƒqVW|S)Nrggð?r>r-r=)rfrgrVrhriÚcalcCubicPoints)"rGrHrbrErerkrNrOrPrQrRrSrZr[rlr r rmrnZdelta_3rsZt1_3rorprqrrrtruZd1xZd1yr&r'r(r)r+r+r,rdCs8     $rd)r@ÚacosÚcosÚpicCs~t|ƒtkr,t|ƒtkrg}qz| |g}nN||d||}|dkrv||ƒ}| |d|| |d|g}ng}|S)uKSolve a quadratic equation. Solves *a*x*x + b*x + c = 0* where a, b and c are real. Args: a: coefficient of *x²* b: coefficient of *x* c: constant term Returns: A list of roots. Note that the returned list is neither guaranteed to be sorted nor to contain unique values! g@gg@)r3rD)rGrHrbr@rWZDDZrDDr+r+r,rms  &cCsŽt|ƒtkrt|||ƒSt|ƒ}||}||}||}||d|d}d|||d||d|d}||} |||} | tkr”dn| } t| ƒtkr¨dn| } | | } | dkrÞ| dkrÞt| dtƒ} | | | gS| tdk�r@ttt|t | ƒd ƒd ƒƒ} dt |ƒ}|d}|t | dƒ|}|t | dt dƒ|}|t | d t dƒ|}t |||gƒ\}}}||tk�r¸||tk�r¸t|||dtƒ}}}n~||tk�rèt||dtƒ}}t|tƒ}nN||tk�rt|tƒ}t||dtƒ}}nt|tƒ}t|tƒ}t|tƒ}|||gSt t | ƒt|ƒdƒ} | || } |dk�rr| } t| |dtƒ} | gSd S)utSolve a cubic equation. Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real. Args: a: coefficient of *x³* b: coefficient of *x²* c: coefficient of *x* d: constant term Returns: A list of roots. Note that the returned list is neither guaranteed to be sorted nor to contain unique values! Examples:: >>> solveCubic(1, 1, -6, 0) [-3.0, -0.0, 2.0] >>> solveCubic(-10.0, -9.0, 48.0, -29.0) [-2.9, 1.0, 1.0] >>> solveCubic(-9.875, -9.0, 47.625, -28.75) [-2.911392, 1.0, 1.0] >>> solveCubic(1.0, -4.5, 6.75, -3.375) [1.5, 1.5, 1.5] >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123) [0.5, 0.5, 0.5] >>> solveCubic( ... 9.0, 0.0, 0.0, -7.62939453125e-05 ... ) == [-0.0, -0.0, -0.0] True g@g"@g@g;@gK@rggà?gð?g@r>Ngð¿gÀgUUUUUUÕ?)r3rDrÚfloatÚroundÚ epsilonDigitsrwÚmaxÚminr@rxryr`Úpow)rGrHrbrEZa1Za2Úa3ÚQÚRZR2ZQ3ZR2_Q3rBÚthetaZrQ2Za1_3rIrJÚx2r+r+r,rŽsT&  (            c Cs^|\}}|\}}|\}}||d} ||d} ||| } ||| } | | f| | f||ffS)Ng@r+) r&r'r(r„Úy2Úx3Úy3rRrSrPrQrNrOr+r+r,rUïs    rUcCs”|\}}|\}}|\}} |\} } || d} || d} ||d| }||d| }|| | |}| | | |}||f||f| | f| | ffS)Ng@r+)r&r'r(r)r„r…r†r‡Úx4Úy4rZr[rRrSrPrQrNrOr+r+r,r\ús  r\cCsf|\}}|\}}|\}}|} |} |d|} |d|} |||} |||}| | f| | f| |ffS)Ngà?r+)rGrHrbrNrOrPrQrRrSrJÚy1r„r…r†r‡r+r+r,rjs    rjcCsœ|\}}|\}}|\}} |\} } | } | } |d| }| d| }||d|}|| d|}|| ||}|| | |}| | f||f||f||ffS)Ng@r+)rGrHrbrErNrOrPrQrRrSrZr[rJrŠr„r…r†r‡rˆr‰r+r+r,rvs  rvcCs8|dd||d||dd||d|fS)zÖFinds the point at time `t` on a line. Args: pt1, pt2: Coordinates of the line as 2D tuples. t: The time along the line. Returns: A 2D tuple with the coordinates of the point. rr>r+)r&r'rMr+r+r,r*s cCsˆd|d||ddd|||d|||d}d|d||ddd|||d|||d}||fS)zèFinds the point at time `t` on a quadratic curve. Args: pt1, pt2, pt3: Coordinates of the curve as 2D tuples. t: The time along the curve. Returns: A 2D tuple with the coordinates of the point. r>rr=r+)r&r'r(rMrBÚyr+r+r,r7s @@cCsèd|d|d||ddd|d|||ddd||||d||||d}d|d|d||ddd|d|||ddd||||d||||d}||fS)zéFinds the point at time `t` on a cubic curve. Args: pt1, pt2, pt3, pt4: Coordinates of the curve as 2D tuples. t: The time along the curve. Returns: A 2D tuple with the coordinates of the point. r>rr-r+)r&r'r(r)rMrBr‹r+r+r,rFsppcCsZt|ƒdkrt||fžŽSt|ƒdkr4t||fžŽSt|ƒdkrNt||fžŽStdƒ‚dS)Nr=r-ézUnknown curve degree)rirrrÚ ValueError)ÚsegrMr+r+r,r_s   c Csx|\}}|\}}|\}}t||ƒtkréÿÿÿÿ)r3rD) ÚsÚerZsxZsyÚexZeyZpxÚpyr+r+r,Ú _line_t_of_ptns r”cCsR|d|d|d|d}|d|d|d|d}|dkoN|dk S)Nrr>gr+)rGrHÚoriginZxDiffZyDiffr+r+r,Ú'_both_points_are_on_same_side_of_origin|s  r–cCs |\}}|\}}|\}} |\} } tj|| ƒrJtj||ƒrJtj||ƒ rJgStj| | ƒrttj||ƒrttj|| ƒ rtgStj|| ƒr�tj| | ƒr�gStj||ƒr¬tj||ƒr¬gStj||ƒ�r|} | | | |} | | || }| |f}t|t|||ƒt|||ƒd�gStj|| ƒ�r`|} ||||}|| ||}| |f}t|t|||ƒt|||ƒd�gS||||}| | | |} tj|| ƒ�r’gS|||| || || } || ||}| |f}t|||ƒ�rt|||ƒ�rt|t|||ƒt|||ƒd�gSgS)aíFinds intersections between two line segments. Args: s1, e1: Coordinates of the first line as 2D tuples. s2, e2: Coordinates of the second line as 2D tuples. Returns: A list of ``Intersection`` objects, each object having ``pt``, ``t1`` and ``t2`` attributes containing the intersection point, time on first segment and time on second segment respectively. Examples:: >>> a = lineLineIntersections( (310,389), (453, 222), (289, 251), (447, 367)) >>> len(a) 1 >>> intersection = a[0] >>> intersection.pt (374.44882952482897, 313.73458370177315) >>> (intersection.t1, intersection.t2) (0.45069111555824465, 0.5408153767394238) )rr r )r?Úiscloserr”r–)Ús1Ze1Ús2Úe2Zs1xZs1yZe1xZe1yZs2xZs2yZe2xZe2yrBZslope34r‹rZslope12r+r+r,r ‚sN&&  cCsT|d}|d}tj|d|d|d|dƒ}tj| ƒj|d |d ƒS)Nrr>r�)r?Úatan2rÚrotateÚ translate)ÚsegmentÚstartÚendZangler+r+r,Ú_alignment_transformationÐs$r¡cCs˜t|ƒj|ƒ}t|ƒdkrBt|Ž\}}}t|d|d|dƒ}nDt|ƒdkr~t|Ž\}}}}t|d|d|d|dƒ}ntdƒ‚tdd„|DƒƒS)Nr-r>rŒzUnknown curve degreecss*|]"}d|kodknr|VqdS)gr>Nr+)rLrlr+r+r,r_äsz._curve_line_intersections_t..) r¡ZtransformPointsrirUrr\rr�r`)ÚcurveÚlineZ aligned_curverGrHrbÚ intersectionsrEr+r+r,Ú_curve_line_intersections_tÚs   r¥cCs†t|ƒdkrt}nt|ƒdkr$t}ntdƒ‚g}xPt||ƒD]B}|||fžŽ}t||fžŽ}t||fžŽ}|jt|||d�ƒq>> curve = [ (100, 240), (30, 60), (210, 230), (160, 30) ] >>> line = [ (25, 260), (230, 20) ] >>> intersections = curveLineIntersections(curve, line) >>> len(intersections) 3 >>> intersections[0].pt (84.9000930760723, 189.87306176459828) r-rŒzUnknown curve degree)rr r ) rirrr�r¥r”rrVr)r¢r£Z pointFinderr¤rMrZline_tr+r+r,r!çs  cCs4t|ƒdkrt|ŽSt|ƒdkr(t|ŽStdƒ‚dS)Nr-rŒzUnknown curve degree)rirrr�)rbr+r+r,Ú _curve_bounds s   r¦cCspt|ƒdkr0|\}}t|||ƒ}||f||fgSt|ƒdkrJt||fžŽSt|ƒdkrdt||fžŽStdƒ‚dS)Nr=r-rŒzUnknown curve degree)rirrrr�)rbrMr�r‘Úmidpointr+r+r,Ú_split_segment_at_ts    r¨çü©ñÒMbP?cs|t|ƒ}t|ƒ}|sd }|s d }t||ƒ\}}|s6gSdd„} t|ƒˆkrht|ƒˆkrh| |ƒ| |ƒfgSt|dƒ\} } |d| |ƒf} | |ƒ|df} t|dƒ\}}|d| |ƒf}| |ƒ|df}g}|jt| |ˆ| |d�ƒ|jt| |ˆ| |d�ƒ|jt| |ˆ| |d�ƒ|jt| |ˆ| |d�ƒ‡fd d „}tƒ}g}x8|D]0}||ƒ}||k�r^�qD|j|ƒ|j|ƒ�qDW|S) Nççð?cSsd|d|dS)Ngà?rr>r+)Úrr+r+r,r§1sz._curve_curve_intersections_t..midpointgà?rr>)Úrange1Úrange2cs t|dˆƒt|dˆƒfS)Nrr>)Úint)re)Ú precisionr+r,ÚVsz._curve_curve_intersections_t..)rªr«)rªr«) r¦rrr¨ÚextendÚ_curve_curve_intersections_tÚsetÚaddrV)Úcurve1Úcurve2r°r­r®Zbounds1Zbounds2Z intersectsÚ_r§Zc11Zc12Z c11_rangeZ c12_rangeZc21Zc22Z c21_rangeZ c22_rangeÚfoundZ unique_keyÚseenZ unique_valuesreÚkeyr+)r°r,r³!sR    r³cstˆ|ƒ}‡fdd„|DƒS)a Finds intersections between a curve and a curve. Args: curve1: List of coordinates of the first curve segment as 2D tuples. curve2: List of coordinates of the second curve segment as 2D tuples. Returns: A list of ``Intersection`` objects, each object having ``pt``, ``t1`` and ``t2`` attributes containing the intersection point, time on first segment and time on second segment respectively. Examples:: >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] >>> intersections = curveCurveIntersections(curve1, curve2) >>> len(intersections) 3 >>> intersections[0].pt (81.7831487395506, 109.88904552375288) cs,g|]$}ttˆ|dƒ|d|dd�‘qS)rr>)rr r )rr)rLre)r¶r+r,rT{sz+curveCurveIntersections..)r³)r¶r·Zintersection_tsr+)r¶r,r"ds  cCs–d}t|ƒt|ƒkr"||}}d}t|ƒdkrRt|ƒdkrFt||ƒ}q€t||ƒ}n.t|ƒdkrxt|ƒdkrxt||žŽ}ntdƒ‚|sˆ|Sdd„|DƒS)a)Finds intersections between two segments. Args: seg1: List of coordinates of the first segment as 2D tuples. seg2: List of coordinates of the second segment as 2D tuples. Returns: A list of ``Intersection`` objects, each object having ``pt``, ``t1`` and ``t2`` attributes containing the intersection point, time on first segment and time on second segment respectively. Examples:: >>> curve1 = [ (10,100), (90,30), (40,140), (220,220) ] >>> curve2 = [ (5,150), (180,20), (80,250), (210,190) ] >>> intersections = segmentSegmentIntersections(curve1, curve2) >>> len(intersections) 3 >>> intersections[0].pt (81.7831487395506, 109.88904552375288) >>> curve3 = [ (100, 240), (30, 60), (210, 230), (160, 30) ] >>> line = [ (25, 260), (230, 20) ] >>> intersections = segmentSegmentIntersections(curve3, line) >>> len(intersections) 3 >>> intersections[0].pt (84.9000930760723, 189.87306176459828) FTr=z4Couldn't work out which intersection function to usecSs g|]}t|j|j|jd�‘qS))rr r )rrr r )rLrlr+r+r,rT­sz/segmentSegmentIntersections..)rir"r!r r�)Zseg1Zseg2Zswappedr¤r+r+r,r#€s     c CsBy t|ƒ}Wntk r$d|SXddjdd„|DƒƒSdS)zw >>> _segmentrepr([1, [2, 3], [], [[2, [3, 4], [0.1, 2.2]]]]) '(1, (2, 3), (), ((2, (3, 4), (0.1, 2.2))))' z%gz(%s)z, css|]}t|ƒVqdS)N)Ú _segmentrepr)rLrBr+r+r,r_ºsz_segmentrepr..N)ÚiterÚ TypeErrorÚjoin)ÚobjÚitr+r+r,r¼°s   r¼cCsx|D]}tt|ƒƒqWdS)zlHelper for the doctests, displaying each segment in a list of segments on a single line as a tuple. N)Úprintr¼)rkržr+r+r,Ú printSegments½s rÃÚ__main__)r$)r$)r©NN)DÚ__doc__ZfontTools.misc.arrayToolsrrrZfontTools.misc.transformrr?Ú collectionsrrÚ__all__rr2r4rr|rDr<rCrrr rrr r rrrrrrrardr@rwrxryrrrUr\rjrvrrrrr”r–r r¡r¥r!r¦r¨r³r"r#r¼rÃÚ__name__ÚsysÚdoctestÚexitÚtestmodÚfailedr+r+r+r,Ús¢     # !"$&9-%' !a   N  & B0