% Copyright 2022 by Qrrbrbirlbel % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Free Documentation License. % \tikzset{ arc to/.code=\pgfqkeys{/tikz/arc to}{#1}, arc to={ counter clockwise/.code=\pgfkeyssetvalue{/tikz/arc to/ccw flag}{1}, clockwise/.code=\pgfkeyssetvalue{/tikz/arc to/ccw flag}{0}, x radius/.code=\pgfkeyssetvalue{/tikz/x radius}{#1}, y radius/.code=\pgfkeyssetvalue{/tikz/y radius}{#1}, radius/.code=\pgfkeyssetvalue{/tikz/x radius}{#1}\pgfkeyssetvalue{/tikz/y radius}{#1}, large/.code=\pgfkeyssetvalue{/tikz/arc to/large flag}{1}, small/.code=\pgfkeyssetvalue{/tikz/arc to/large flag}{0}, % defaults rotate/.initial=0, counter clockwise, small, counter clockwise/.value forbidden, clockwise/.value forbidden, large/.value forbidden, small/.value forbidden}} \def\tikz@arcA rc{\pgfutil@ifnextchar t% {\tikz@flush@moveto\expandafter\expandafter\expandafter\tikz@arcB@cont\expandafter\pgfutil@gobble\pgfutil@gobble} {\tikz@flush@moveto\tikz@arc@cont}} \def\tikz@arcB@cont{% \pgfutil@ifnextchar[\tikz@@do@arcB{ \advance\tikz@expandcount by -10\relax% go down quickly \ifnum\tikz@expandcount<0\relax% \def\@next{\tikz@@do@arcB[]}% \else% \def\@next{\expandafter\tikz@arcB@cont}% \fi% \@next}}% \def\tikz@@do@arcB[#1]{% \def\tikz@arcB@options{#1}% \tikz@do@@arcB} \def\tikz@do@@arcB{% \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@do@@arcB} {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@do@@arcB} {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@do@@arcB} {\tikz@scan@one@point\tikz@do@arcB}}}} \def\tikz@do@arcB#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}} \tikz@make@last@position{#1}% \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \iftikz@shapeborder \edef\tikz@moveto@waiting{\tikz@shapeborder@name}% \fi \begingroup \tikzset{every arc/.try,every arc to/.try,arc to/.expand once=\tikz@arcB@options}% \pgfmathsetmacro\tikz@arc@x{\pgfkeysvalueof{/tikz/x radius}}% \ifpgfmathunitsdeclared \pgfmathsetmacro\tikz@arc@y{\pgfkeysvalueof{/tikz/y radius}}% \ifpgfmathunitsdeclared \tikzext@pgfpatharcto{\tikz@arc@x pt}{\tikz@arc@y pt} {\pgfkeysvalueof{/tikz/arc to/rotate}}{\pgfkeysvalueof{/tikz/arc to/large flag}} {\pgfkeysvalueof{/tikz/arc to/ccw flag}}{#1}% \else \tikzerror{You cannot mix dimensions and dimension values in an arc}% \fi \else \pgfmathsetmacro\tikz@arc@y{\pgfkeysvalueof{/tikz/y radius}}% \ifpgfmathunitsdeclared \tikzerror{You cannot mix dimensions and dimension values in an arc}% \else \pgf@process{\pgfpointxy{\tikz@arc@x}{0}}% \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \let\tikz@arc@x\pgfmathresult \pgf@process{\pgfpointxy{0}{\tikz@arc@y}}% \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \let\tikz@arc@y\pgfmathresult \tikzext@pgfpatharcto{+\tikz@arc@x pt}{+\tikz@arc@y pt} {\pgfkeysvalueof{/tikz/arc to/rotate}}{\pgfkeysvalueof{/tikz/arc to/large flag}} {\pgfkeysvalueof{/tikz/arc to/ccw flag}}{#1}% \fi \fi \endgroup % check whether \pgf@marshall starts with \pgfpathlineto \pgfutil@ifxempty\pgf@marshal{}{% \edef\tikz@temp{\expandafter\expandafter\expandafter\noexpand\expandafter\pgfutil@firstgobblerest\pgf@marshal\relax}% \expandafter\let\expandafter\tikz@temp\tikz@temp \pgfutil@ifx\tikz@temp\pgfpathlineto{}{% % getting rid of \pgfpatharcaxes inside \pgf@marshal \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@marshal \expandafter\expandafter\expandafter{\expandafter\pgfutil@gobble\pgf@marshal}% % extracting the other four values needed for the timer \edef\tikz@timer@start@angle{\expandafter\pgfutil@firstoffour\pgf@marshal}% \edef\tikz@timer@end@angle{\expandafter\pgfutil@secondoffour\pgf@marshal}% \pgfextract@process\tikz@timer@zero@axis{\expandafter\pgfutil@thirdoffour\pgf@marshal}% \pgfextract@process\tikz@timer@ninety@axis{\expandafter\pgfutil@fourthoffour\pgf@marshal}% % \let\tikz@timer=\tikz@timer@arc }% }% \tikz@scan@next@command } \def\pgfutil@firstoffour#1#2#3#4{#1} \def\pgfutil@secondoffour#1#2#3#4{#2} \def\pgfutil@thirdoffour#1#2#3#4{#3} \def\pgfutil@fourthoffour#1#2#3#4{#4} \def\pgfutil@firstgobblerest#1#2\relax{#1} % original from pgfcorepathconstruct.code.tex \def\tikzext@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 % Qrr: % make sure direction is properly followed \ifdim\pgf@arcto@fS pt=1pt % counter clockwise \ifdim\pgf@arcto@theta@end pt<\pgf@arcto@theta@start pt \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end+360}% \fi \else % clockwise \ifdim\pgf@arcto@theta@end pt>\pgf@arcto@theta@start pt \pgfmathsetmacro\pgf@arcto@theta@end{\pgf@arcto@theta@end-360}% \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 }