PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/share/texlive/texmf-dist/tex/generic/pgf/basiclayer
Viewing File: /usr/share/texlive/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex
% Copyright 2006 by Till Tantau % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. \ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex,v 1.24 2010/08/03 12:27:36 ludewich Exp $ \newdimen\pgf@path@lastx \newdimen\pgf@path@lasty \let\pgfgetpath=\pgfsyssoftpath@getcurrentpath \let\pgfsetpath=\pgfsyssoftpath@setcurrentpath % Replace corners by arcs. % % #1 = in-size of arc % #2 = out-size of arc % % Description: % % This command influences path construction command like % \pgfpathlineto or \pgfpatharc. It will cause the corners at the end % of these commands to be replaced by little arcs. If the % corner is a 90 degrees corner and if #1=#2, a quarter-circle of % radius #1 is put in place of the corner. If #1 and #2 are different, % the quarter circle will instead by a quarter ellipse. If the angle % is different from 90 degrees, a deformed quarter circle will % result, which may or may not be desirable. For a ``perfect'' arc you % must use the \pgfpatharc command. % % % Example: One rounded corner. % % \pgfpathmoveto{\pgfpointxy{0}{0}} % \pgfsetcornersarced{4pt}{4pt} % \pgfpathlineto{\pgfpointxy{0}{1}} % \pgfpathlineto{\pgfpointxy{1}{1}} % \pgfstroke % % Example: A rounded rectangle % % \pgfsetcornersarced{4pt}{4pt} % \pgfpathrectangle{\pgfpointorigin}{\pgfpoint{1cm}{1cm}} % \pgfstroke % % Example: A rounded triangles % % \pgfsetcornersarced{4pt}{4pt} % \pgfpathmoveto{\pgfpointorigin} % \pgfpathlineto{\pgfpoint{1cm}{0cm}} % \pgfpathlineto{\pgfpoint{1cm}{1cm}} % \pgfpathclose % \pgfstroke \newif\ifpgf@arccorners \def\pgfsetcornersarced#1{% \pgf@process{#1}% \edef\pgf@corner@arc{{\the\pgf@x}{\the\pgf@y}}% \pgf@arccornerstrue% \ifdim\pgf@x=0pt% \ifdim\pgf@y=0pt\relax% \pgf@arccornersfalse% \fi% \fi% } \def\pgf@roundcornerifneeded{% \ifpgf@arccorners\expandafter\pgfsyssoftpath@specialround\pgf@corner@arc\fi% } % Move current point to #1. % % #1 = new current point % % Example: % % \pgfpathmoveto{\pgfxy(0,0)} % \pgfpathlineto{\pgfxy(0,1)} % \pgfstroke \def\pgfpathmoveto#1{% \pgfpointtransformed{#1}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } \def\pgf@protocolsizes#1#2{% \ifpgf@relevantforpicturesize% \ifdim#1<\pgf@picminx\global\pgf@picminx#1\fi% \ifdim#1>\pgf@picmaxx\global\pgf@picmaxx#1\fi% \ifdim#2<\pgf@picminy\global\pgf@picminy#2\fi% \ifdim#2>\pgf@picmaxy\global\pgf@picmaxy#2\fi% \ifpgf@size@hooked% \let\pgf@size@hook@x#1\let\pgf@size@hook@y#2\pgf@path@size@hook% \fi% \fi% \ifdim#1<\pgf@pathminx\global\pgf@pathminx#1\fi% \ifdim#1>\pgf@pathmaxx\global\pgf@pathmaxx#1\fi% \ifdim#2<\pgf@pathminy\global\pgf@pathminy#2\fi% \ifdim#2>\pgf@pathmaxy\global\pgf@pathmaxy#2\fi% } \newif\ifpgf@size@hooked \let\pgf@path@size@hook=\pgfutil@empty% \def\pgf@resetpathsizes{% \global\pgf@pathmaxx=-16000pt\relax% \global\pgf@pathminx=16000pt\relax% \global\pgf@pathmaxy=-16000pt\relax% \global\pgf@pathminy=16000pt\relax% } \def\pgf@getpathsizes#1{% \edef#1{{\the\pgf@pathmaxx}{\the\pgf@pathminx}{\the\pgf@pathmaxy}{\the\pgf@pathminy}}% } \def\pgf@setpathsizes#1{% \expandafter\pgf@@setpathsizes#1% } \def\pgf@@setpathsizes#1#2#3#4{% \global\pgf@pathmaxx=#1\relax% \global\pgf@pathminx=#2\relax% \global\pgf@pathmaxy=#3\relax% \global\pgf@pathminy=#4\relax% } % Append a line from the current point to #1 to the current path. % % #1 = end of line % % Example: % % \pgfpathmoveto{\pgfxy(0,0)} % \pgfpathlineto{\pgfxy(0,1)} % \pgfstroke \def\pgfpathlineto#1{% \pgfpointtransformed{#1}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } % Close the current path. % % Example: % % % Draws two triangles % \pgfpathmoveto{\pgfxy(0,0)} % \pgfpathlineto{\pgfxy(0,1)} % \pgfpathlineto{\pgfxy(1,0)} % \pgfclosepath % \pgfpathmoveto{\pgfxy(2,0)} % \pgfpathlineto{\pgfxy(2,1)} % \pgfpathlineto{\pgfxy(3,0)} % \pgfpathclose % \pgfstroke \def\pgfpathclose{% \pgf@roundcornerifneeded% \pgfsyssoftpath@closepath% } % Append a cubic bezier spline from the current point to #3 with control % points #1 and #2 to the current path. % % #1 = first control point % #2 = second control point % #3 = end point % % Example: % % \pgfpathmoveto{\pgfpointxy{0}{0}} % \pgfpathcurveto{\pgfpointxy{0}{1}}{\pgfpointxy{1}{1}}{\pgfpointxy{1}{2}} % \pgfstroke \def\pgfpathcurveto#1#2#3{% \pgfpointtransformed{#3}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#2}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgfpointtransformed{#1}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% \pgfsyssoftpath@curveto{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } % Append a quadratic bezier spline from the current point to #2 with % control point #1 to the current path. % % #1 = control point % #2 = end point % % Example: % % \pgfpathmoveto{\pgfpointxy{0}{0}} % \pgfpathquadraticcurveto{\pgfpointxy{1}{1}}{\pgfpointxy{2}{0}} % \pgfstroke \def\pgfpathquadraticcurveto#1#2{% \pgfpointtransformed{#2}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#1}% \pgf@xc=.6666666\pgf@x% \pgf@yc=.6666666\pgf@y% % compute second control point: \pgf@xa=.33333333\pgf@xb% \pgf@ya=.33333333\pgf@yb% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% % compute first control point \advance\pgf@xc by.3333333\pgf@path@lastx% \advance\pgf@yc by.3333333\pgf@path@lasty% \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% \pgf@roundcornerifneeded% \pgfsyssoftpath@curveto{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } % Append an arc to the current point, where the current point is at % angle #1 and the end is at angle #2. If #2 > #1, the arc is drawn % counter-clockwise, otherwise it is clockwise. % % #1 = angle of first point % #2 = angle of second point % #3 = radius or x-radius/y-radius % % Example: % % \pgfpathmoveto{\pgfxy(0,0)} % \pgfpatharc{0}{90}{2cm} % \pgfstroke \def\pgfpatharc#1#2#3{% {% \pgfmathparse{#1}\let\pgf@temp@a=\pgfmathresult% \pgfmathparse{#2}\let\pgf@temp@b=\pgfmathresult% \pgfutil@in@{and }{#3}% \ifpgfutil@in@% \pgf@arc@get@radii#3\pgf@arc@stop% \else \pgf@arc@get@radii#3and #3\pgf@arc@stop% \fi% \pgf@arc@local@angle@a=\pgf@temp@a pt% \pgf@arc@local@angle@b=\pgf@temp@b pt% \loop% \pgfutil@tempdima=\pgf@arc@local@angle@a% \advance\pgfutil@tempdima by-\pgf@arc@local@angle@b\relax% \ifdim\pgfutil@tempdima<0pt\relax% \pgfutil@tempdima=-\pgfutil@tempdima\relax% \fi% \ifdim\pgfutil@tempdima>90pt\relax% \ifdim\pgfutil@tempdima>115pt\relax% \pgf@arc@temp=90pt% big skip \else% \pgf@arc@temp=60pt% smaller skip to ensure wide segments % (important shortened end segments because % of arrow tips) \fi% \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax% {% \pgf@arc@local@angle@b=\pgf@arc@local@angle@a\relax% \advance\pgf@arc@local@angle@b by\pgf@arc@temp\relax% \pgf@arc% } \advance\pgf@arc@local@angle@a by\pgf@arc@temp\relax% \else {% \pgf@arc@local@angle@b=\pgf@arc@local@angle@a\relax% \advance\pgf@arc@local@angle@b by-\pgf@arc@temp\relax% \pgf@arc% }% \advance\pgf@arc@local@angle@a by-\pgf@arc@temp\relax% \fi% \repeat% \pgf@roundcornerifneeded% \pgf@arc% }% } \dimendef\pgf@arc@local@angle@a=0 \dimendef\pgf@arc@local@angle@b=1 \dimendef\pgf@arc@temp=2 \def\pgf@arc@get@radii#1and #2\pgf@arc@stop{% \pgfmathparse{#1}\let\pgf@arc@radius@a=\pgfmathresult% \pgfmathparse{#2}\let\pgf@arc@radius@b=\pgfmathresult% } \def\pgf@arc{% {% \pgfutil@tempdima=\pgf@arc@radius@a pt% \pgfutil@tempdimb=\pgf@arc@radius@b pt% % \pgf@xa=\pgf@arc@local@angle@a\relax% \pgf@xb=\pgf@arc@local@angle@b\relax% \advance\pgf@xb by-\pgf@xa\relax% \ifdim\pgf@xb<0pt\relax% \pgf@xb=-\pgf@xb\relax% \fi% \ifdim\pgf@xb=90.0pt% \def\pgfmathresult{0.55228475}% \else% \pgfmathparse{1.333333333*tan(.25*\pgf@sys@tonumber{\pgf@xb})}% many thanks to Ken Starks \fi% \pgfutil@tempdima=\pgfmathresult\pgfutil@tempdima% \pgfutil@tempdimb=\pgfmathresult\pgfutil@tempdimb% %.. controls +(\pgf@xa+90:\pgfutil@tempdima) and +(\pgf@xb-90:\pgfutil@tempdima) .. +(-(#1:#3)+(#2:#3))% % store first support vector in xa/ya: \pgf@xa=\pgf@arc@local@angle@a\relax% \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax% \advance\pgf@xa by 90pt\relax% \else% \advance\pgf@xa by -90pt\relax% \fi% \edef\pgf@arc@angle{\pgf@sys@tonumber{\pgf@xa}}% \pgfpointtransformed{\pgfpointpolar{\pgf@arc@angle}{\pgfutil@tempdima and \pgfutil@tempdimb}}% \advance\pgf@x by-\pgf@pt@x% \advance\pgf@y by-\pgf@pt@y% \pgf@xa=\pgf@path@lastx% \pgf@ya=\pgf@path@lasty% \advance\pgf@xa by \pgf@x% \advance\pgf@ya by \pgf@y% % store target in xb/yb: \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@a}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}% \pgf@xb=\pgf@path@lastx% \pgf@yb=\pgf@path@lasty% \advance\pgf@xb by -\pgf@x% \advance\pgf@yb by -\pgf@y% \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgf@arc@radius@a pt and \pgf@arc@radius@b pt}}% \advance\pgf@xb by \pgf@x% \advance\pgf@yb by \pgf@y% % store second support xc/yc: \ifdim\pgf@arc@local@angle@b>\pgf@arc@local@angle@a\relax% \advance\pgf@arc@local@angle@b by -90pt\relax% \else% \advance\pgf@arc@local@angle@b by 90pt\relax% \fi% \pgfpointtransformed{\pgfpointpolar{\pgf@sys@tonumber{\pgf@arc@local@angle@b}}{\pgfutil@tempdima and \pgfutil@tempdimb}}% \advance\pgf@x by-\pgf@pt@x% \advance\pgf@y by-\pgf@pt@y% \pgf@xc=\pgf@xb\relax% \pgf@yc=\pgf@yb\relax% \advance \pgf@xc by \pgf@x\relax% \advance \pgf@yc by \pgf@y\relax% \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xb}{\the\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% }% } % Append an arc to the current point, where the arc is on an ellipse % given by two axis vectors. % % #1 = angle of first point % #2 = angle of second point % #3 = first axis % #4 = second axis % % Example: % % \pgfpathmoveto{\pgfxy(0,0)} % \pgfpatharcaxes{0}{90}{\pgfpointxy{2}{0}}{\pgfpointxy{0}{2}} % \pgfstroke \def\pgfpatharcaxes#1#2#3#4{% {% \pgftransformtriangle{\pgfpointorigin}{#3}{#4}% \pgfpatharc{#1}{#2}{1pt}% }% } % Append an arc to the current point that ends at a given position. % % #1 = x-radius % #2 = y-radius % #3 = x-axis-rotation (in degrees) % #4 = large-arc-sweep-flag (0 or 1) % #5 = sweep-flag (0 or 1) % #6 = target point % % Description: % % This command implements an arc drawing where a given target % coordinate (#6) is given and the task is to draw an arc of an % ellipse with the given radii. The center point of the ellipse is not % give, but computed automatically. % % This kind of "endpoint parameterization" of an arc is exactly the % same as the one specified by the SVG-specification for the "A" and % "a" path commands. Please see the SVG-specification for details. % % Note that the problem is internally converted to drawing an arc % using \pgfpatharc. This means that there may be a heavy loss of % accuracy. % % Example: % % \pgfpathmoveto{\pgfpoint{1cm}{1cm}} % \pgfpatharcto{1cm}{1cm}{0}{0}{0}{\pgfpoint{0cm}{2cm}} \def\pgfpatharcto#1#2#3#4#5#6{% {% % The following code is based on the transformation described in svg % 1.1 specification Section F.6.5 % % Step 1: store the simple parameters (xa=x1 since TeX does not % allow numbers in names) % \pgfmathsetmacro\pgf@arcto@rx{abs(#1)}% \pgfmathsetmacro\pgf@arcto@ry{abs(#2)}% \ifdim\pgf@arcto@rx pt=0pt% special rule: zero radius=straight line \gdef\pgf@marshal{\pgfpathlineto{#6}}% \else \ifdim\pgf@arcto@ry pt=0pt% special rule: zero radius=straight line \gdef\pgf@marshal{\pgfpathlineto{#6}}% \else \pgfmathsetmacro\pgf@arcto@phi{#3}% \pgfmathsetmacro\pgf@arcto@fA{#4}% \ifdim\pgf@arcto@fA pt=0pt \else \pgfmathsetmacro\pgf@arcto@fA{1.0} % Special rule: every non-zero value is 1. \fi \pgfmathsetmacro\pgf@arcto@fS{#5}% \ifdim\pgf@arcto@fS pt=0pt \else \pgfmathsetmacro\pgf@arcto@fS{1.0} % Special rule: every non-zero value is 1. \fi \pgf@process{#6} \edef\pgf@arcto@xb{\the\pgf@x}% \edef\pgf@arcto@yb{\the\pgf@y}% % % Step 2: x1,y1 is more complicated to compute: It is given by lastx % and lasty, but these are transformed coordinates, we need the % untransformed ones. So, we inverse the transformation (arghh...) % \pgftransforminvert% \pgf@process{\pgfpointtransformed{\pgfqpoint{\pgf@path@lastx}{\pgf@path@lasty}}} \edef\pgf@arcto@xa{\the\pgf@x} \edef\pgf@arcto@ya{\the\pgf@y} \edef\pgf@temp@a{\pgf@arcto@xa,\pgf@arcto@ya} \edef\pgf@temp@b{\pgf@arcto@xb,\pgf@arcto@yb} \ifx\pgf@temp@a\pgf@temp@b% special rule: skip! \global\let\pgf@marshal\pgfutil@empty \else % % Ok, now we got all the parameters setup. Now comes the % computation... % % % Step 3: Start with a new coordinate system and rotate everything % by the negated phi. % \pgftransformreset \pgftransformrotate{-\pgf@arcto@phi} % Ok, using \pgfpointtransformed we now get transformed points... % % Step 4: Compute x1' and y1' (xaprime and yaprime) % \pgf@process{ \pgfpointtransformed{\pgfpointscale{.5}{\pgfpointdiff {\pgfqpoint{\pgf@arcto@xb}{\pgf@arcto@yb}} {\pgfqpoint{\pgf@arcto@xa}{\pgf@arcto@ya}} } } } \edef\pgf@arcto@xaprime{\pgf@sys@tonumber\pgf@x} \edef\pgf@arcto@yaprime{\pgf@sys@tonumber\pgf@y} % % Compute Lambda % \pgfmathsetmacro\pgf@arcto@frac@x{\pgf@arcto@xaprime/\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@frac@y{\pgf@arcto@yaprime/\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@lambda{ \pgf@arcto@frac@x*\pgf@arcto@frac@x+\pgf@arcto@frac@y*\pgf@arcto@frac@y } \ifdim\pgf@arcto@lambda pt>1pt% \pgfmathsetmacro\pgf@arcto@sqrt@lambda{sqrt(\pgf@arcto@lambda)} \pgfmathsetmacro\pgf@arcto@rx{\pgf@arcto@sqrt@lambda*\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@ry{\pgf@arcto@sqrt@lambda*\pgf@arcto@ry} \fi % % Do some scaling % \pgfmathsetmacro\pgf@arcto@xaprime@abs{abs(\pgf@arcto@xaprime)} \pgfmathsetmacro\pgf@arcto@yaprime@abs{abs(\pgf@arcto@yaprime)} \pgfmathmax@{\pgf@arcto@rx,\pgf@arcto@ry,\pgf@arcto@xaprime@abs,\pgf@arcto@yaprime@abs} \pgfmathsetmacro\pgf@arcto@scaling{20/\pgfmathresult} \pgfmathsetmacro\pgf@arcto@rx@scaled{\pgf@arcto@scaling*\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@ry@scaled{\pgf@arcto@scaling*\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@xaprime@scaled{\pgf@arcto@scaling*\pgf@arcto@xaprime} \pgfmathsetmacro\pgf@arcto@yaprime@scaled{\pgf@arcto@scaling*\pgf@arcto@yaprime} % % Step 5: Now comes the messy computation of c1' and c2'. % \ifdim\pgf@arcto@rx pt>\pgf@arcto@ry pt% \pgfmathsetmacro\pgf@arcto@rx@over@ry{\pgf@arcto@rx/\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@ry@over@rx{\pgf@arcto@ry/\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@temp{\pgf@arcto@ry@over@rx*\pgf@arcto@xaprime@scaled} \pgfmathsetmacro\pgf@arcto@numerator{ \pgf@arcto@ry@scaled*\pgf@arcto@ry@scaled- \pgf@arcto@yaprime@scaled*\pgf@arcto@yaprime@scaled- \pgf@arcto@temp*\pgf@arcto@temp } \pgfmathsetmacro\pgf@arcto@denominator{ \pgf@arcto@yaprime@scaled*\pgf@arcto@yaprime@scaled+ \pgf@arcto@temp*\pgf@arcto@temp } \else \pgfmathsetmacro\pgf@arcto@rx@over@ry{\pgf@arcto@rx/\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@ry@over@rx{\pgf@arcto@ry/\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@temp{\pgf@arcto@rx@over@ry*\pgf@arcto@yaprime@scaled} \pgfmathsetmacro\pgf@arcto@numerator{ \pgf@arcto@rx@scaled*\pgf@arcto@rx@scaled- \pgf@arcto@xaprime@scaled*\pgf@arcto@xaprime@scaled- \pgf@arcto@temp*\pgf@arcto@temp } \pgfmathsetmacro\pgf@arcto@denominator{ \pgf@arcto@xaprime@scaled*\pgf@arcto@xaprime@scaled+ \pgf@arcto@temp*\pgf@arcto@temp } \fi \pgfmathsetmacro\pgf@arcto@frac{ \pgf@arcto@numerator/\pgf@arcto@denominator } \ifdim\pgf@arcto@frac pt<0pt \pgfmathsetmacro\pgf@arcto@factor{0} \else \pgfmathsetmacro\pgf@arcto@factor{sqrt(\pgf@arcto@frac)} \fi \ifx\pgf@arcto@fA\pgf@arcto@fS \pgfmathsetmacro\pgf@arcto@factor{-\pgf@arcto@factor} \fi \pgfmathsetmacro\pgf@arcto@cxprime{ \pgf@arcto@factor*\pgf@arcto@rx@over@ry*\pgf@arcto@yaprime } \pgfmathsetmacro\pgf@arcto@cyprime{ -\pgf@arcto@factor*\pgf@arcto@ry@over@rx*\pgf@arcto@xaprime } % % Step 6: Ok, now compute cx,cy % \pgftransformreset \pgftransformrotate{\pgf@arcto@phi} \pgf@process{ \pgfpointtransformed{\pgfqpoint{\pgf@arcto@cxprime pt}{\pgf@arcto@cyprime pt}} } \edef\pgf@arcto@temp{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \pgf@process{\pgfpointadd{\pgf@arcto@temp}{ \pgfpointscale{.5}{ \pgfpointadd {\pgfqpoint{\pgf@arcto@xa}{\pgf@arcto@ya}} {\pgfqpoint{\pgf@arcto@xb}{\pgf@arcto@yb}} } } } \edef\pgf@arcto@cx{\the\pgf@x} \edef\pgf@arcto@cy{\the\pgf@y} % % Step 7: Compute start angle: % \pgfmathsetmacro\pgf@arcto@vec@x{(\pgf@arcto@xaprime-\pgf@arcto@cxprime)/\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@vec@y{(\pgf@arcto@yaprime-\pgf@arcto@cyprime)/\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@denominator{veclen(\pgf@arcto@vec@x,\pgf@arcto@vec@y)} \pgfmathsetmacro\pgf@arcto@frac{\pgf@arcto@vec@x/\pgf@arcto@denominator} \pgfmathsetmacro\pgf@arcto@theta@start{acos(\pgf@arcto@frac)} \ifdim\pgf@arcto@vec@y pt<0pt \pgfmathsetmacro\pgf@arcto@theta@start{-\pgf@arcto@theta@start} \fi % % Step 8: Compute end angle: % \pgfmathsetmacro\pgf@arcto@vec@x{(-\pgf@arcto@xaprime-\pgf@arcto@cxprime)/\pgf@arcto@rx} \pgfmathsetmacro\pgf@arcto@vec@y{(-\pgf@arcto@yaprime-\pgf@arcto@cyprime)/\pgf@arcto@ry} \pgfmathsetmacro\pgf@arcto@denominator{veclen(\pgf@arcto@vec@x,\pgf@arcto@vec@y)} \pgfmathsetmacro\pgf@arcto@frac{\pgf@arcto@vec@x/\pgf@arcto@denominator} \pgfmathsetmacro\pgf@arcto@theta@end{acos(\pgf@arcto@frac)} \ifdim\pgf@arcto@vec@y pt<0pt \pgfmathsetmacro\pgf@arcto@theta@end{-\pgf@arcto@theta@end} \fi \pgfmathsetmacro\pgf@arcto@delta@theta{abs(\pgf@arcto@theta@start-\pgf@arcto@theta@end)} \ifdim\pgf@arcto@fA pt=0pt% \ifdim\pgf@arcto@delta@theta pt>180pt% % Ok, we need to adjust the angle! \ifdim\pgf@arcto@theta@end pt>\pgf@arcto@theta@start pt \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end-360} \else \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end+360} \fi \fi \else \ifdim\pgf@arcto@delta@theta pt<180pt% % Ok, we need to adjust the angle! \ifdim\pgf@arcto@theta@end pt>\pgf@arcto@theta@start pt \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end-360} \else \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end+360} \fi \fi \fi \xdef\pgf@marshal{\noexpand \pgfpatharcaxes{\pgf@arcto@theta@start}{\pgf@arcto@theta@end} {\noexpand\pgfpointpolar{\pgf@arcto@phi}{\pgf@arcto@rx}} {\noexpand\pgfpointpolar{\pgf@arcto@phi+90}{\pgf@arcto@ry}} } \fi\fi\fi } \pgf@marshal } % the quality of arc approximation by means of Bezier splines is % controlled by a mesh width. % % The mesh width is provided in (full!) degrees. The smaller the mesh % width, the more precise the arc approximation. % % Use an empty value to disable spline approximation (uses a single % cubic polynomial for the complete arc). % % The value must be an integer! \def\pgfpatharctomaxstepsize{45} % A specialized arc operation for an arc on an (axis--parallel) ellipse. % % In contrast to \pgfpatharc, it explicitly interpolates start- and end points. % % In contrast to \pgfpatharcto, this routine is numerically stable and % quite fast since it relies on a lot of precomputed information. % % #1 center of ellipse % #2 angle of last path position inside of the ellipse % #3 end angle % #4 end point (a \pgfpoint) % #5 xradius % #6 yradius % #7 the ratio xradius/yradius of the ellipse % #8 the ratio yradius/xradius of the ellipse % Example: % \def\cx{1cm}% center x % \def\cy{1cm}% center y % \def\startangle{0}% % \def\endangle{45}% % \def\a{5cm}% xradius % \def\b{10cm}% yradius % \pgfmathparse{\a/\b}\let\abratio=\pgfmathresult % \pgfmathparse{\b/\a}\let\baratio=\pgfmathresult % % \pgfpathmoveto{\pgfpoint{\cx+\a*cos(\startangle)}{\cy+\b*sin(\startangle)}}% % \pgfpatharctoprecomputed % {\pgfpoint{\cx}{\cy}} % {\startangle} % {\endangle} % {\pgfpoint{\cx+\a*cos(\endangle)}{\cy+\b*sin(\endangle)}}% % {\a} % {\b} % {\abratio} % {\baratio} % \def\pgfpatharctoprecomputed#1#2#3#4#5#6#7#8{% \begingroup % Implementation idea: % % let % m = center (#1) % \gamma_0 = start angle % \gamma_1 = end angle % a = x radius % b = y radius % % an axis parallel ellipse is parameterized by % C(\gamma) = m + ( a cos(\gamma), b sin(\gamma) ), \gamma in [0,360]. % % Now, consider the segment \gamma(t), % \gamma:[0,1] -> [\gamma_0,\gamma_1], % t -> \gamma_0 + t(\gamma_1 - \gamma_0) % and % C(\gamma(t)) which is defined on [0,1]. % % I'd like to approximate the arc by one or more cubic bezier % splines which interpolate through the last and first provided % points. % % In general, a Bezier spline C:[0,1] -> \R of order n fulfills % C'(0) = n ( P_1 - P_0 ), % C'(1) = n ( P_n - P_{n-1} ). % For n=3 and given P_0 and P_3, I can directly compute P_1 and P_2 once I know % the derivatives at t=0 and t=1. % % The derivatives in our case are % ( C \circ \gamma )'(t) = C'[\gamma(t)] * \gamma'(t) % = ( -a pi/180 sin(\gamma(t)), b pi/180 cos(\gamma(t)) ) * (\gamma_1 - \gamma_0). % The pi/180 comes into play since we are working with degrees. % % Expression (C\circ\gamma)'(0) using P_0 and (C \circ \gamma)'(1) % using P_3 yields the expressions % (C \circ \gamma)'(0) = % pi/180 * (\gamma_1 - \gamma_0)* [ - a/b(P_0^y - my), b/a (P_0^x - mx) ] % (C \circ \gamma)'(1) = % pi/180 * (\gamma_1 - \gamma_0)* [ - a/b(P_3^y - my), b/a (P_3^x - mx) ] % % defining % scaleA = a/b * pi / (3*180) * (\gamma_1 - \gamma_0) % and % scaleB = b/a * pi / (3*180) * (\gamma_1 - \gamma_0) % yields the direct expressions for the intermediate bezier % control points % % P_1 = [ % P_0^x - scaleA* ( P_0^y -my), % P_0^y + scaleB* ( P_0^x -mx) ] % and % P_2 = [ % P_3^x + scaleA* ( P_3^y -my), % P_3^y - scaleB* ( P_3^x -mx) ]. % % This works fast, with few operations, if % - a/b and b/a are known in advance % - P_0 and P_3 are known in advance % - \gamma_0 and \gamma_1 are known. % % It is also reliable if (\gamma_1 - \gamma_0) is small % \pgf@process{#1}% \edef\pgfpath@center@x{\the\pgf@x}% \edef\pgfpath@center@y{\the\pgf@y}% \def\pgfpath@completearcend{#4}% % compute scale (#3-#2) * pi/(3*180) = (#3 - #2) * pi/27 * 1/20 % splitting pi/(3*180) into two scales has higher TeX accuracy \pgf@xa=#2pt \pgf@xb=#3pt \edef\pgfpath@startangle{#2pt}% \edef\pgfpath@endangle{\pgf@sys@tonumber\pgf@xb}% % \pgf@ya=\pgf@xb \advance\pgf@ya by-\pgf@xa % \ifx\pgfpatharctomaxstepsize\pgfutil@empty \def\pgfpath@N{1}% \pgf@xc=\pgf@ya \else \pgf@xc=\pgf@ya% compute N = floor((gamma_1 - gamma_0) / max) +1 \ifdim\pgf@xc<0pt \multiply\pgf@xc by-1 \fi \divide\pgf@xc by\pgfpatharctomaxstepsize\relax \afterassignment\pgfutil@gobble@until@relax \c@pgf@counta=\the\pgf@xc\relax \advance\c@pgf@counta by1 \edef\pgfpath@N{\the\c@pgf@counta}% % \pgf@xc=\pgf@ya \divide\pgf@xc by\c@pgf@counta \fi % \edef\pgfpath@h{\pgf@sys@tonumber\pgf@xc}% % %\message{pgfpathellipse: using N =\pgfpath@N\space spline points y0 = \pgfpath@startangle, y0+i*h, yN=\pgfpath@endangle, i=1,...,(\pgfpath@N-1), with h=\pgfpath@h\space mesh width (total arc angle \pgf@sys@tonumber\pgf@ya).}% % % \pgf@xc=0.116355283466289\pgf@xc % pi/27 \divide\pgf@xc by20 \pgf@xa=#7\pgf@xc \edef\pgfpath@scale@A{\pgf@sys@tonumber\pgf@xa}% \pgf@xa=#8\pgf@xc \edef\pgfpath@scale@B{\pgf@sys@tonumber\pgf@xa}% % % compute intermediate spline segments for % i = 1,...,N-1 % this is a no-op for N=1. \c@pgf@countd=1 \pgfutil@loop \ifnum\c@pgf@countd<\pgfpath@N\relax % \pgf@xa=\pgfpath@startangle % compute \pgf@xa = y_0 + i*h \pgf@xb=\pgfpath@h pt \multiply\pgf@xb by\c@pgf@countd \advance\pgf@xa by\pgf@xb \edef\pgfpath@angle@i{\pgf@sys@tonumber\pgf@xa}% %\message{angle \the\c@pgf@countd: \pgfpath@angle@i...}% % \pgfpatharcofellipse@{% \pgfpoint {\pgfpath@center@x + #5*cos(\pgfpath@angle@i)} {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)} }% % \advance\c@pgf@countd by1 \pgfutil@repeat % % compute final spline segment. It only differs insofar as the % final point is already known explicitly and should be % interpolated without additional math error. %\message{angle \pgfpath@N: \pgfpath@endangle...}% \pgfpatharcofellipse@{\pgfpath@completearcend}% \endgroup }% \def\pgfpatharcofellipse@#1{% \begingroup \pgf@process{#1}% \edef\pgfpath@endpt{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% % \pgfpathcurveto{ \begingroup \global\pgf@x=\pgf@path@lastx \global\pgf@y=\pgf@path@lasty \pgf@xa=\pgf@x \advance\pgf@xa by-\pgfpath@center@x \pgf@ya=\pgf@y \advance\pgf@ya by-\pgfpath@center@y \global\advance\pgf@x by-\pgfpath@scale@A\pgf@ya \global\advance\pgf@y by \pgfpath@scale@B\pgf@xa \endgroup }{% \begingroup \pgfpath@endpt \pgf@xa=\pgf@x \advance\pgf@xa by-\pgfpath@center@x \pgf@ya=\pgf@y \advance\pgf@ya by-\pgfpath@center@y \global\advance\pgf@x by \pgfpath@scale@A\pgf@ya \global\advance\pgf@y by-\pgfpath@scale@B\pgf@xa \endgroup }{% \pgfpath@endpt }% \endgroup } % Append an ellipse to the current path. % % #1 = center % #2 = first axis % #3 = second axis % % Example: % % % Add a circle of radius 3cm around the origin % \pgfpathellipse{\pgforigin}{\pgfxy(2,0)}{\pgfxy(0,1)} % % % Draw a non-filled circle of radius 1cm around the point (1,1) % \pgfpathellipse{\pgfxy(1,1)}{\pgfxy(1,1)}{\pgfxy(-2,2)} % \pgfstroke \def\pgfpathellipse#1#2#3{% \pgfpointtransformed{#1}% store center in xc/yc \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgfpointtransformed{#2}% \pgf@xa=\pgf@x% store first axis in xa/ya \pgf@ya=\pgf@y% \advance\pgf@xa by-\pgf@pt@x% \advance\pgf@ya by-\pgf@pt@y% \pgfpointtransformed{#3}% \pgf@xb=\pgf@x% store second axis in xb/yb \pgf@yb=\pgf@y% \advance\pgf@xb by-\pgf@pt@x% \advance\pgf@yb by-\pgf@pt@y% {% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% }% \pgf@x=0.55228475\pgf@xb% first arc \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% {% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% \advance\pgf@yb by\pgf@yc% \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis \pgf@ya=-\pgf@ya% \pgf@x=0.55228475\pgf@xa% second arc \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% {% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% }% \pgf@xb=-\pgf@xb% flip second axis \pgf@yb=-\pgf@yb% \pgf@x=0.55228475\pgf@xb% third arc \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% {% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% \advance\pgf@yb by\pgf@yc% \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis once more \pgf@ya=-\pgf@ya% \pgf@x=0.55228475\pgf@xa% fourth arc \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% {% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% }% \pgfsyssoftpath@closepath% \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% } % Append a circle to the current path % % #1 = center % #2 = radius % % Example: % % % Append a circle of radius 3cm around the the point (1,1) % \pgfpathcircle{\pgxy(1,1)}{3cm} \def\pgfpathcircle#1#2{\pgfpathellipse{#1}{\pgfpoint{#2}{0pt}}{\pgfpoint{0pt}{#2}}} % Append a rectangle to the current path % % #1 = lower left corner point of rectangle % #2 = width and height vector % % Example: % % % A rectangle with corners (2,2) and (3,3) % \pgfpathrectangle{\pgfpointxy{2}{2}}{\pgfpointxy{1}{1}} \def\pgfpathrectangle{% \let\pgfrect@next=\pgf@specialrect% \ifpgf@pt@identity% \ifpgf@arccorners% \else% \let\pgfrect@next=\pgf@normalrect% \fi% \fi% \pgfrect@next% } \def\pgf@normalrect#1#2{% \pgf@process{#2}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgfpointtransformed{#1}% \pgfsyssoftpath@rect{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \advance\pgf@x by\pgf@xa\relax% \advance\pgf@y by\pgf@ya\relax% \pgf@protocolsizes{\pgf@x}{\pgf@y}% } \def\pgf@specialrect#1#2{% \pgf@process{#2}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{#1}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \advance\pgf@xa by\pgf@xb% \advance\pgf@ya by\pgf@yb% \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}}% \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}}% \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}}% \pgfpathclose% \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}}% } % Append a rectangle to the current path % % #1 = one corner of the rectangle % #2 = opposite corner of the rectangle % % Example: % % % A rectangle with corners (2,2) and (3,3) % \pgfpathrectanglecorners{\pgfpointxy{2}{2}}{\pgfpointxy{3}{3}} \def\pgfpathrectanglecorners#1#2{% \pgf@process{#2}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgf@process{#1}% \advance\pgf@xc by-\pgf@x% \advance\pgf@yc by-\pgf@y% \pgfpathrectangle{#1}{\pgfqpoint{\pgf@xc}{\pgf@yc}}% } % Append a grid to the current path. % % #1 = lower left point of grid % #2 = upper right point of grid % % Options: % % stepx = x-step dimension (default 1cm) % stepy = y-step dimension (default 1cm) % step = dimesion vector % % Example: % % \pgfsetlinewidth{0.8pt} % \pgfgrid{\pgfxy(0,0)}{\pgfxy(3,2)} % \pgfsetlinewidth{0.4pt} % \pgfgrid[stepx=1cm,stepy=1cm]{\pgfxy(0,0)}{\pgfxy(3,2)} \pgfkeys{ /pgf/stepx/.initial=1cm, /pgf/stepy/.initial=1cm, /pgf/step/.code={\pgf@process{#1}\pgfkeysalso{/pgf/stepx/.expanded=\the\pgf@x,/pgf/stepy/.expanded=\the\pgf@y}}, /pgf/step/.value required } \def\pgfpathgrid{\pgfutil@ifnextchar[{\pgf@pathgrid}{\pgf@pathgrid[]}} \def\pgf@pathgrid[#1]#2#3{% \pgfset{#1}% \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/stepx}}% \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/stepy}}% \pgf@process{#3}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgf@process{#2}% \pgf@xa=\pgf@x\relax% \pgf@ya=\pgf@y\relax% {% % compute bounding box % first corner \pgf@x=\pgf@xb% \pgf@y=\pgf@yb% \pgf@pos@transform{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% % second corner \pgf@x=\pgf@xb% \pgf@y=\pgf@ya% \pgf@pos@transform{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% % third corner \pgf@x=\pgf@xa% \pgf@y=\pgf@yb% \pgf@pos@transform{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% % fourth corner \pgf@x=\pgf@xa% \pgf@y=\pgf@ya% \pgf@pos@transform{\pgf@x}{\pgf@y}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% }% \c@pgf@counta=\pgf@y\relax% \c@pgf@countb=\pgf@yc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% \pgf@y=\c@pgf@counta\pgf@yc\relax% \ifdim\pgf@y<\pgf@ya% \advance\pgf@y by\pgf@yc% \fi% \loop% horizontal lines {% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% \pgf@xa=\pgf@xb% \pgf@ya=\pgf@y% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% }% \advance\pgf@y by\pgf@yc% \ifdim\pgf@y<\pgf@yb% \repeat% \advance\pgf@y by-0.01pt\relax% \ifdim\pgf@y<\pgf@yb% {% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% \pgf@xa=\pgf@xb% \pgf@ya=\pgf@y% \pgf@pos@transform{\pgf@xa}{\pgf@ya} \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% }% \fi% \c@pgf@counta=\pgf@x\relax% \c@pgf@countb=\pgf@xc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% \pgf@x=\c@pgf@counta\pgf@xc\relax% \ifdim\pgf@x<\pgf@xa% \advance\pgf@x by\pgf@xc% \fi% \loop% vertical lines {% \pgf@xc=\pgf@x% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% }% \advance\pgf@x by\pgf@xc% \ifdim\pgf@x<\pgf@xb% \repeat% \advance\pgf@x by-0.01pt\relax% \ifdim\pgf@x<\pgf@xb% {% \pgf@xc=\pgf@x% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% }% \fi% } % Append two half-parabolas to the path % % #1 = bend (relative to current point) % #2 = end point (relative to bend point) % % Description: % % This command appends a half-parabola that starts at the current point % and has its bend at #1+current point. Then, a second parabola is % appended that starts at #1+current point, where it also has its % minimum/maximum, and ends at #1+current point+#2, which becomes the % new current point. % % By setting #2 = (0,0) you draw only a half parabola that goes from the % current point to the bend; by setting #1 = (0,0) % you draw a half parabola that going to current point + #2 and has its % bend at the current point. % % Examples: % % % Half-parabola going ``up and right'' % \pgfpathmoveto{\pgfpointorigin} % \pgfpathparabola{\pgfpointorigin}{\pgfpoint{2cm}{4cm}} % % % Half-parabola going ``down and right'' % \pgfpathmoveto{\pgfpointorigin} % \pgfpathparabola{\pgfpoint{-2cm}{4cm}}}{\pgfpointorigin} % % % Full parabola % \pgfpathmoveto{\pgfpointorigin} % \pgfpathparabola{\pgfpoint{-2cm}{4cm}}{\pgfpoint{2cm}{4cm}} \def\pgfpathparabola#1#2{% {% \pgf@process{#2}% untransformed \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgf@process{#1}% untransformed \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgfutil@tempswatrue% \ifdim\pgf@xb=0pt\relax% \ifdim\pgf@yb=0pt\relax% \pgfutil@tempswafalse% \fi% \fi% {% \ifpgfutil@tempswa% \pgf@arccornersfalse \else% \fi% \pgfutil@tempswatrue% \ifdim\pgf@xc=0pt\relax% \ifdim\pgf@yc=0pt\relax% \pgfutil@tempswafalse% \fi% \fi% \ifpgfutil@tempswa {% \pgf@pt@x=\pgf@path@lastx% \pgf@pt@y=\pgf@path@lasty% \pgfpathcurveto% {\pgfqpoint{.1125\pgf@xc}{.225\pgf@yc}}% found by trial and error {\pgfqpoint{.5\pgf@xc}{\pgf@yc}}% found by trial and error {\pgfqpoint{\pgf@xc}{\pgf@yc}}% }% \fi% }% \ifpgfutil@tempswa% \pgf@xc=\pgf@xb% \pgf@yc=\pgf@yb% {% \pgf@pt@x=\pgf@path@lastx% \pgf@pt@y=\pgf@path@lasty% \pgfpathcurveto% {\pgfqpoint{.5\pgf@xc}{0\pgf@yc}}% found by trial and error {\pgfqpoint{.8875\pgf@xc}{.775\pgf@yc}}% found by trial and error {\pgfqpoint{\pgf@xc}{\pgf@yc}}% }% \fi% }% } % Append a sine curve between 0 and \pi/2 to the path. % % #1 = vector, describing the width and height of the curve % % Description: % % This command appends a sine curve in the interval 0 and \pi/2 to the % current path. The sine curve ends at currentpoint+#1. % % Examples: % % % One complete sine in the interval [0,\pi] % \pgfpathmoveto{\pgfpointorigin} % \pgfpathsine{\pgfpoint{1.57cm}{1cm}} % \pgfpathcosine{\pgfpoint{3.141cm}{0cm}} \def\pgfpathsine#1{% {% \pgf@process{#1}% untransformed \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgf@pt@x=\pgf@path@lastx% evil trickery to transform to the last point \pgf@pt@y=\pgf@path@lasty% \pgfpathcurveto% {\pgfqpoint{.31831\pgf@xc}{.5\pgf@yc}}% found by trial and error {\pgfqpoint{.63503\pgf@xc}{\pgf@yc}}% found by trial and error {\pgfqpoint{\pgf@xc}{\pgf@yc}}% }% } % Append a cosine curve between 0 and \pi/2 to the path. % % #1 = vector, describing the width and height of the curve % % Examples: % % % One complete sine in the interval [0,\pi] % \pgfpathmoveto{\pgfpointorigin} % \pgfpathsine{\pgfpoint{1.57cm}{1cm}} % \pgfpathcosine{\pgfpoint{3.141cm}{0cm}} \def\pgfpathcosine#1{% {% \pgf@process{#1}% untransformed \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgf@pt@x=\pgf@path@lastx% evil trickery to transform to the last point \pgf@pt@y=\pgf@path@lasty% \pgfpathcurveto% {\pgfqpoint{.36497\pgf@xc}{0pt}}% found by trial and error {\pgfqpoint{.68169\pgf@xc}{.5\pgf@yc}}% found by trial and error {\pgfqpoint{\pgf@xc}{\pgf@yc}}% }% } % Draw part of a curve between two specified times s and t. % % #1 - a start time s. % #2 - an end time t. % #3 - start point of the curve % #4 - first control % #5 - second control % #6 - end point of the curve % % There are two versions, \pgfpathcurvebetweentime and % \pgfpathcurvebetweentimecontinue. The latter does not insert a % moveto to the first point. % \def\pgfpathcurvebetweentime{\pgf@ignoremovetofalse\pgf@@pathcurvebetweentime} \def\pgfpathcurvebetweentimecontinue{\pgf@ignoremovetotrue\pgf@@pathcurvebetweentime} \newif\ifpgf@ignoremoveto \def\pgf@@pathcurvebetweentime#1#2#3#4#5#6{% \pgfmathparse{#1}% \let\pgf@time@s=\pgfmathresult% \pgfmathparse{#2}% \let\pgf@time@t=\pgfmathresult% \ifdim\pgf@time@s pt>\pgf@time@t pt\relax% \pgfmathsetmacro\pgf@time@s{1-#1}% \pgfmathsetmacro\pgf@time@t{1-#2}% \pgf@@@pathcurvebetweentime{\pgf@time@t}{#6}{#5}{#4}{#3}% \else% \pgf@@@pathcurvebetweentime{\pgf@time@t}{#3}{#4}{#5}{#6}% \fi% } \def\pgf@@@pathcurvebetweentime#1#2#3#4#5{% % Q1 = P1. \pgf@process{#2}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% % Q2 = P1 + t*(P2-P1). \pgf@process{% \pgf@process{#3}% \pgf@xa=#1\pgf@x% \pgf@ya=#1\pgf@y% \pgf@process{#2}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \advance\pgf@x by-#1\pgf@xb% \advance\pgf@y by-#1\pgf@yb% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% }% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% % Q3 = Q2 + t*((P2 + t*(P3-P2)) - Q2). \pgf@process{% \pgf@process{#4}% \pgf@xa=#1\pgf@x% \pgf@ya=#1\pgf@y% % \pgf@process{#3}% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \advance\pgf@xc by-#1\pgf@x% \advance\pgf@yc by-#1\pgf@y% % \pgf@x=\pgf@xb% \pgf@y=\pgf@yb% \advance\pgf@x by#1\pgf@xa% \advance\pgf@y by#1\pgf@ya% \advance\pgf@x by-#1\pgf@xb% \advance\pgf@y by-#1\pgf@yb% \advance\pgf@x by#1\pgf@xc% \advance\pgf@y by#1\pgf@yc% }% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% % Q4 = (1-t)^3*P1 + 3*t(1-t)^2*P2 + 3*t^2(1-t)*P3 + t^3*P4. \pgf@process{\pgfpointcurveattime{#1}{#2}{#3}{#4}{#5}}% \ifx#1\pgf@time@t% % First time round... \pgfmathdivide@{\pgf@time@s}{\pgf@time@t}% \pgfmathadd@{-\pgfmathresult}{1}% \let\pgf@time@s=\pgfmathresult% \edef\pgf@marshal{% \noexpand\pgf@@@pathcurvebetweentime{\noexpand\pgf@time@s}% {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% }% \else% % ...second time round. \ifpgf@ignoremoveto% \edef\pgf@marshal{% \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% }% \else% \edef\pgf@marshal{% \noexpand\pgfpathmoveto{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% \noexpand\pgfpathcurveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% }% \fi% \fi% \pgf@marshal% } \endinput