summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex')
-rw-r--r--Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex990
1 files changed, 990 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex
new file mode 100644
index 00000000000..098e73f9110
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex
@@ -0,0 +1,990 @@
+%%
+%% Package: spectralsequences.sty version 1.0
+%% Author: Hood Chatham
+%% Email: hood@mit.edu
+%% Date: 2017-06-18
+%% License: Latex Project Public License
+%%
+%% File: sseqdrawing.code.tex
+%%
+%% Defines the macros that draw the features of the spectral sequence (at least, those that aren't drawn by tikz).
+%% Everything here has to be super optimized, because like 90% of the execution time is in these functions.
+%% In particular, tikz is a horrible performance hole that must be avoided at all costs. For example, the code
+%% the code to produce the axis ticks used to use the tikz \node command, and in the file example_KF3n.tex drawing
+%% the axes ticks was taking about 1/3 of the compile time (a little under 1s out of a 3.2)
+%%
+
+
+
+%%%
+%%% Draw axes and clip
+%%%
+\def\sseq@handlexaxis{
+ \ifsseq@drawxaxis
+ \bgroup
+ \ifsseq@borderxaxis\else
+ \let\sseq@ymin\sseq@yaxisorigin % Warning: this is a stupid, lazy hack.
+ \fi
+ \sseq@drawxaxis
+ \ifsseq@drawxaxisticks
+ \sseq@drawxticks
+ \fi
+ \egroup
+ \fi
+}
+\def\sseq@handleyaxis{
+ \ifsseq@drawyaxis
+ \bgroup
+ \ifsseq@borderyaxis\else
+ \let\sseq@xmin\sseq@xaxisorigin % Warning: this is a stupid, lazy hack.
+ \fi
+ \sseq@drawyaxis
+ \ifsseq@drawyaxisticks
+ \sseq@drawyticks
+ \fi
+ \egroup
+ \fi
+}
+\def\sseq@drawxaxis{
+ \bgroup
+ \pgftransformreset
+ \sseq@globaldetonetransform
+ %
+ \bgroup
+ \pgftransformxshift{\sseq@xaxis@end@extend}\pgftransformyshift{-\sseq@xaxisgap}
+ \sseq@globalscaletransform
+ \pgfpathmoveto{\pgfpoint{\sseq@xmax cm}{\sseq@ymin cm}}
+ \egroup
+ \bgroup
+ \pgftransformxshift{-\sseq@yaxisgap}
+ %\pgftransformxshift{-\sseq@ylabelgap}
+ \pgftransformxshift{-\sseq@xaxis@start@extend}
+ \pgftransformyshift{-\sseq@xaxisgap}
+ \sseq@globalscaletransform
+ \pgfpathlineto{\pgfpoint{\sseq@xmin cm}{\sseq@ymin cm}}
+ \egroup
+ \egroup
+ \pgfusepath{stroke}
+}
+\def\sseq@drawyaxis{
+ \bgroup
+ \pgftransformreset
+ \sseq@globaldetonetransform
+ \bgroup
+ \pgftransformyshift{\sseq@yaxis@end@extend}\pgftransformxshift{-\sseq@yaxisgap}
+ \sseq@globalscaletransform
+ \pgfpathmoveto{\pgfpoint{\sseq@xmin cm}{\sseq@ymax cm}}
+ \egroup
+ \bgroup
+ \pgftransformyshift{-\sseq@xaxisgap}
+ %\pgftransformyshift{-\sseq@xlabelgap}
+ \pgftransformyshift{-\sseq@yaxis@start@extend}
+ \pgftransformxshift{-\sseq@yaxisgap}
+ \sseq@globalscaletransform
+ \pgfpathlineto{\pgfpoint{\sseq@xmin cm}{\sseq@ymin cm}}
+ \egroup
+ \egroup
+ \pgfusepath{stroke}%
+}
+\def\sseq@drawxticks{
+ \sseq@tempy=\sseq@ymin\relax
+ \sseq@tempx=\sseq@xmax\relax
+ \advance\sseq@tempx\@ne\relax
+ \edef\sseq@temp{\the\sseq@tempx}%
+ \sseq@tempx=\sseq@xmin\relax
+ \loop
+ \bgroup
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{\the\sseq@tempx cm}{\the\sseq@tempy cm}}}
+ \pgftransformresetnontranslations
+ \sseq@globaldetonetransform
+ \pgftransformyshift{-\sseq@xlabelgap}\pgftransformyshift{-\sseq@xaxisgap}
+ \pgftransformresetnontranslations
+ \ifsseq@rotatelabels\sseq@globalrotatetransform\fi
+ \sseq@xtickstyle
+ \tikz@options
+ \pgftext{\hbox{$\sseq@xtickfn{\the\sseq@tempx}$}}
+ \egroup
+ \advance\sseq@tempx\sseq@xtickstep\relax
+ \ifnum\sseq@tempx<\sseq@temp\repeat
+}
+\def\sseq@drawyticks{
+ \sseq@tempx=\sseq@xmin\relax
+ \sseq@tempy=\sseq@ymax\relax
+ \advance\sseq@tempy\@ne\relax
+ \edef\sseq@tempmax{\the\sseq@tempy}
+ \sseq@tempy=\sseq@ymin\relax
+ \loop
+ \bgroup
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{\the\sseq@tempx cm}{\the\sseq@tempy cm}}}
+ \pgftransformresetnontranslations
+ \sseq@globaldetonetransform
+ \pgftransformxshift{-\sseq@ylabelgap}\pgftransformxshift{-\sseq@yaxisgap}
+ \pgftransformresetnontranslations
+ \ifsseq@rotatelabels\sseq@globalrotatetransform\fi
+ \sseq@ytickstyle
+ \tikz@options
+ \pgftext{\hbox{$\sseq@ytickfn{\the\sseq@tempy}$}}
+ \egroup
+ \advance\sseq@tempy\sseq@ytickstep\relax
+ \ifnum\sseq@tempy<\sseq@tempmax\repeat
+}
+\def\sseq@setupclip{
+ %\clip(\sseq@xmin-0.4,\sseq@ymin-0.4) rectangle (\sseq@xmax+0.5,\sseq@ymax+0.5);%
+ \ifsseq@clip
+ \ifx\sseq@customclip\pgfutil@empty
+ \bgroup
+ \pgftransformreset
+ \sseq@globaldetonetransform
+ \ifsseq@borderyaxis
+ \def\xmin{\pgftransformxshift{-\sseq@yaxisgap}\pgftransformxshift{\sseq@yclip@axisgap}}
+ \else
+ \def\xmin{\pgftransformxshift{-\sseq@xaxis@start@extend}\pgftransformxshift{-\sseq@clip@padding@left}}
+ \fi
+ \ifsseq@borderxaxis
+ \def\ymin{\pgftransformyshift{-\sseq@xaxisgap}\pgftransformyshift{\sseq@xclip@axisgap}}
+ \else
+ \def\ymin{\pgftransformyshift{-\sseq@yaxis@start@extend}\pgftransformyshift{-\sseq@clip@padding@bottom}}
+ \fi
+ \def\xmax{\pgftransformxshift{\sseq@xaxis@end@extend}\pgftransformxshift{\sseq@clip@padding@right}}
+ \def\ymax{\pgftransformyshift{\sseq@yaxis@end@extend}\pgftransformyshift{\sseq@clip@padding@top}}
+ \bgroup
+ \xmin\ymin\sseq@globalscaletransform
+ \pgfpathmoveto{\pgfpoint{\sseq@xmin cm}{\sseq@ymin cm}}
+ \egroup
+ \bgroup
+ \xmin\ymax\sseq@globalscaletransform
+ \pgfpathlineto{\pgfpoint{\sseq@xmin cm}{\sseq@ymax cm}}
+ \egroup
+ \bgroup
+ \xmax\ymax\sseq@globalscaletransform
+ \pgfpathlineto{\pgfpoint{\sseq@xmax cm}{\sseq@ymax cm}}
+ \egroup
+ \bgroup
+ \xmax\ymin\sseq@globalscaletransform
+ \pgfpathlineto{\pgfpoint{\sseq@xmax cm}{\sseq@ymin cm}}
+ \egroup
+ \egroup
+ \pgfpathclose
+ \pgfgetpath\sseq@theclippath % This stores the clipping so I can find intersections later
+ \pgfusepath{discard}% This has to be after the egroup or else the clipping gets screwed up
+ \bgroup
+ %\sseq@globalscaletransform
+ \pgfpathmoveto{\pgfpoint{\sseq@xmin cm}{\sseq@ymin cm}}
+ \pgfpathlineto{\pgfpoint{\sseq@xmin cm}{\sseq@ymax cm}}
+ \pgfpathlineto{\pgfpoint{\sseq@xmax cm}{\sseq@ymax cm}}
+ \pgfpathlineto{\pgfpoint{\sseq@xmax cm}{\sseq@ymin cm}}
+ \pgfpathclose
+ \egroup
+ \pgfgetpath\sseq@therangepath % Only for deciding whether to draw "tricky edges"
+ \pgfusepath{discard}
+ \else
+ \def\sseq@temp{\path[name path=temp]}
+ \@xptwo\sseq@temp\@xp\@gobble\sseq@customclip
+ \pgfgetpath\sseq@theclippath
+ \let\sseq@theclippath\tikz@intersect@path@name@temp
+ \fi
+ \else
+ \let\sseq@theclippath\relax
+ \fi
+}
+\def\sseq@useclip{\ifx\sseq@theclippath\relax\else\pgfsetpath\sseq@theclippath\pgfusepath{clip}\fi}
+\def\sseq@grid@chess{
+ \bgroup
+ \pgfscope
+ \sseq@useclip
+ \pgflowlevelsynccm
+ \pgfsetlinewidth{1cm}
+ \pgfsetdash{{1cm}{1cm}}{1cm}
+ \pgfsetcolor{lightgray}
+ \pgfpathgrid[stepx=2cm,stepy=2cm]{\pgfpoint{-0.5cm}{-0.5cm}}{\pgfpoint{\sseq@xmax cm+0.499cm}{\sseq@ymax cm+0.499cm}}
+ \pgfusepath{stroke}
+ \endpgfscope
+ \egroup
+}
+\def\sseq@grid@crossword{
+ \bgroup
+ \pgfscope
+ \pgfsetlinewidth{\the\sseq@gridstrokethickness}
+ \sseq@useclip
+ \pgftransformxshift{-0.5cm}
+ \pgftransformyshift{-0.5cm}
+ \pgfpathgrid[stepx=1cm,stepy=1cm]{\pgfpoint{-1cm}{-1cm}}{\pgfpoint{\xmax cm+0.99cm}{\ymax cm+0.99cm}}
+ \pgfusepath{stroke}
+ \endpgfscope
+ \egroup
+}
+\def\sseq@grid@go{
+ \bgroup
+ \pgfscope
+ \sseq@useclip
+ \pgfsetlinewidth{\the\sseq@gridstrokethickness}
+ \pgfpathgrid[stepx=1cm,stepy=1cm]{\pgfpoint{-1cm}{-1cm}}{\pgfpoint{\xmax cm+0.5cm}{\ymax cm+0.5cm}}
+ \pgfusepath{stroke}
+ \endpgfscope
+ \egroup
+}
+\def\sseq@grid@none{}
+\def\sseq@grid@dots{
+ \bgroup
+ \pgfscope
+ \pgfgettransform\sseq@savetransform
+ \pgftransformreset
+ \sseq@globalscaletransform
+ \pgfgettransformentries{\sseq@a}{\sseq@b}{\sseq@c}{\sseq@d}{\sseq@u}{\sseq@v}
+ \pgfsettransform\sseq@savetransform
+ \sseq@useclip
+ \pgftransformxshift{-1.5cm}
+ \pgftransformyshift{-0.5cm}
+ \pgfsetdash{{1pt}{\sseq@a*1cm-1pt}}{0.5cm+.5pt}
+ \pgfsetlinewidth{1pt}
+ \sseq@tempy=\sseq@ymin\relax
+ \advance\sseq@tempy\m@ne
+ \loop
+ \advance\sseq@tempy\@ne
+ \pgfpathmoveto{\pgfpoint{\sseq@xmin cm+0.5cm/\sseq@a}{\the\sseq@tempy cm}}
+ \pgfpathlineto{\pgfpoint{\sseq@xmax cm+1.01cm }{\the\sseq@tempy cm}}
+ \ifnum\sseq@tempy<\sseq@ymax\repeat
+ %\pgfpathgrid[stepx=1cm,stepy=1cm]{\pgfpoint{-0.5cm}{-0.5cm}}{\pgfpoint{\xmax cm-0.5cm}{\ymax cm-0.5cm}}
+ \pgfusepath{stroke}
+ \endpgfscope
+ \egroup
+}
+%%%
+%%% Draw Classes
+%%%
+%%% Class offsets
+\sseqnewclasspattern{standard}{
+ (0,0);
+ (-0.13,0)(0.13,0);
+ (-0.2,0)(0,0)(0.2,0);
+ (-0.13,-0.13)(0.13,-0.13)(-0.13,0.13)(0.13,0.13);
+ (-0.16,-0.16)(0.16,-0.16)(-0.16,0.16)(0.16,0.16)(0,0);
+ (-0.13,-0.2)(-0.13,0)(-0.13,0.2)(0.13,-0.2)(0.13,0)(0.13,0.2);
+}
+\sseqnewclasspattern{linear}{
+ (0,0);
+ (-0.13,0)(0.13,0);
+ (-0.2,0)(0,0)(0.2,0);
+ (-0.3,0)(-0.1,0)(0.1,0)(0.3,0);
+ (-0.4,0)(-0.2,0)(0,0)(0.2,0)(0.4,0);
+ (-0.5,0)(-0.3,0)(-0.1,0)(0.1,0)(0.3,0)(0.5,0);
+}
+\def\sseq@offset#1#2{
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{0\csname sseq@\sseq@classpattern xoffset#1/#2\endcsname cm}{0\csname sseq@\sseq@classpattern yoffset#1/#2\endcsname cm}}}
+}
+\def\sseq@class@getparts#1(#2,#3,#4)[#5].{
+ \sseq@seterrorannotation@drawing{#1}{#2}{#3}{#4}{#5}
+ \def\sseq@thisclassname{class.(#2,#3,#4)}
+ \def\sseq@thisnodename{sseq{#2,#3,#4}}
+ \def\sseq@thispos{(#2,#3)}
+ \def\sseq@thisposnum{#4}
+ \def\sseq@thisclassnum{#5}
+}
+
+\def\sseqtooltip#1#2{%
+ \edef\temp{\detokenize\@xpthree{#2}}%
+ \edef\temp{\@xp\sseqtooltip@replaceslashes\@xp{\temp}}%
+ \sseq@eval{\@nx\pdftooltip{\unexpanded{#1}}{\temp}}%
+}
+\bgroup\lccode`\!=`\\\lowercase{\egroup
+\def\sseqtooltip@replaceslashes#1{\sseqtooltip@replaceslashes@#1!\sseq@nil}
+\def\sseqtooltip@replaceslashes@#1!#2{%
+ #1%
+ \ifx\sseq@nil#2\@xp\@gobble\else
+ \@nx\@nx\@nx\textbackslash
+ \@xp\sseqtooltip@replaceslashes@
+ \fi#2%
+}
+}
+
+% #1 -- the name of the node object
+\def\sseq@class@drawnode#1{%
+ \begingroup
+ \sseq@class@getparts#1.
+ \sseq@tempx=\sseq@obj{\sseq@thisclassname.x}\relax
+ \sseq@tempy=\sseq@obj{\sseq@thisclassname.y}\relax
+ \sseq@needstikzfalse
+ \sseq@options@firstpassmode
+ \sseq@thesseqstyle
+ \sseq@theclassstyle
+ \ifnum\sseq@obj{#1.page}=\sseq@infinitycount
+ \sseq@thepermanentcyclestyle
+ \else
+ \sseq@thetransientcyclestyle
+ \ifsseq@thispage
+ \sseq@thethispagecyclestyle
+ \fi
+ \fi
+ \the\sseq@scope@toks
+ \sseq@obj{#1.needstikz}
+%
+ \sseq@outofrangetrue
+ \ifnum\sseq@tempx<\sseq@xmaxpp\relax\ifnum\sseq@tempx>\sseq@xminmm\relax\ifnum\sseq@tempy<\sseq@ymaxpp\relax\ifnum\sseq@tempy>\sseq@yminmm\relax
+ \sseq@outofrangefalse
+ \pgfscope
+ \let\tikz@options\pgfutil@empty
+ \let\tikz@alias=\pgfutil@empty
+ \def\pgfkeysdefaultpath{/sseqpages/class/}
+ \sseq@options@secondpassmode
+ \sseq@thesseqstyle
+ \sseq@theclassstyle
+ \ifnum\sseq@obj{#1.page}=\sseq@infinitycount
+ \sseq@thepermanentcyclestyle
+ \else
+ \sseq@thetransientcyclestyle
+ \ifsseq@thispage
+ \sseq@thethispagecyclestyle
+ \fi
+ \fi
+ \the\sseq@scope@toks
+ \sseq@obj{#1.options}%
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{\the\sseq@tempx cm}{\the\sseq@tempy cm}}}
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{-\the\sseq@x cm}{-\the\sseq@y cm}}}
+ \iftikz@fullytransformed\pgfgettransform{\savetransform}\fi
+ \pgftransformresetnontranslations
+ \sseq@globalrotatetransform
+ \sseq@classplacementtransform
+ \sseq@obj@ifdef{#1.offset}{\sseq@obj{#1.offset}}{%
+ \sseq@offset{\sseq@thisposnum}{\sseq@obj{partcoord.\sseq@thispos.numnodes}}%
+ }%
+ \iftikz@fullytransformed\pgfsettransform{\savetransform}\else\pgftransformresetnontranslations\ifsseq@rotatelabels\sseq@globalrotatetransform\fi\fi
+ \tikz@options
+ \ifsseq@needstikz
+ \let\sseq@mode\tikz@mode
+ \tikzset{every text node part/.code/.expand once={\sseq@globalrotatetransform\sseq@obj{#1.nodetext.options}}}%
+ \sseq@eval{%
+ \@nx\node[/utils/exec={\let\@nx\tikz@mode\@nx\sseq@mode},
+ /handlers/first char syntax/the character "/.initial=\@nx\sseq@handlequote
+ ] (\sseq@thisnodename) {\unexpanded\@xpthree{\sseq@obj{#1.nodetext}}}
+ [every text node part/.code={}]
+ \@nx\sseq@obj{#1.labelnodes};
+ }%
+ \else
+ \tikz@node@textfont
+ \edef\sseq@classnodetextoptions{\@xptwo\@nx\sseq@obj{#1.nodetext.options}}
+ \edef\sseq@classnodetext{\@xptwo\@nx\sseq@obj{#1.nodetext}}
+ \sseq@setnodetext
+ \let\tikz@fig@name\sseq@thisnodename
+ \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{\sseq@drawnode}%
+ \tikz@alias
+ \sseq@obj{#1.labelnodes}
+ \fi
+ \sseq@obj@ifdef{#1.tooltip}{
+ \pgfpointanchor{\sseq@thisnodename}{west}
+ \pgf@xa=\pgf@x
+ \pgfpointanchor{\sseq@thisnodename}{south}
+ \pgf@ya=\pgf@y
+%
+ \pgf@process{\pgfpointdiff{\pgfpointtransformed{\pgfpointanchor{\sseq@thisnodename}{west}}}{\pgfpointtransformed{\pgfpointanchor{\sseq@thisnodename}{east}}}}
+ \pgf@xb=\pgf@x
+ \pgf@process{\pgfpointdiff{\pgfpointtransformed{\pgfpointanchor{\sseq@thisnodename}{south}}}{\pgfpointtransformed{\pgfpointanchor{\sseq@thisnodename}{north}}}}
+ \pgf@yb=\pgf@y
+%
+ \setbox\tikz@tempbox=\hbox{
+ \pgfinterruptpicture
+ \sseqtooltip{\rule{\pgf@xb}{0pt}\rule{0pt}{\pgf@yb}}{\sseq@obj{#1.tooltip}}
+ \endpgfinterruptpicture
+ }
+ {%
+ \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
+ \pgfapproximatenonlineartransformation%
+ \pgfqboxsynced{\tikz@tempbox}%
+ }%
+ }{}
+ \endpgfscope
+ \fi\fi\fi\fi
+ \ifsseq@outofrange
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{\the\sseq@tempx cm}{\the\sseq@tempy cm}}}%
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{-\the\sseq@x cm}{-\the\sseq@y cm}}}
+ \pgftransformresetnontranslations
+ \sseq@globalrotatetransform
+ \sseq@classplacementtransform
+ \sseq@offset{\sseq@thisposnum}{\sseq@obj{partcoord.\sseq@thispos.numnodes}}
+ \pgfcoordinate{\sseq@thisnodename}{\pgfpointorigin}%
+ \fi
+ \endgroup
+}
+\def\sseq@setnodetext{%
+ \setbox\pgfnodeparttextbox=\hbox{%
+ \pgfscope%
+ \tikzset{every text node part/.try}%
+ \sseq@classnodetextoptions
+ \ifx\tikz@textopacity\pgfutil@empty%
+ \else%
+ \pgfsetfillopacity{\tikz@textopacity}%
+ \pgfsetstrokeopacity{\tikz@textopacity}%
+ \fi%
+ \pgfinterruptpicture
+ \ifx\tikz@text@width\pgfutil@empty%
+ \tikz@textfont%
+ \else%
+ \begingroup%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
+ \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}%
+ \tikz@textfont%
+ \tikz@text@action%
+ \fi%
+ \ifx\tikz@textcolor\pgfutil@empty%
+ \else%
+ \pgfutil@colorlet{.}{\tikz@textcolor}%
+ \fi%
+ \pgfsetcolor{.}%
+ \tikz@atbegin@node%
+ \sseq@classnodetext%
+ \tikz@atend@node%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \else%
+ \pgfutil@endminipage%
+ \endgroup%
+ \fi%
+ \endpgfinterruptpicture
+ \endpgfscope%
+ }%
+ \ifx\tikz@text@width\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@width}%
+ \wd\pgfnodeparttextbox=\pgf@x%
+ \fi%
+ \ifx\tikz@text@height\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@height}%
+ \ht\pgfnodeparttextbox=\pgf@x%
+ \fi%
+ \ifx\tikz@text@depth\pgfutil@empty%
+ \else%
+ \pgfmathsetlength{\pgf@x}{\tikz@text@depth}%
+ \dp\pgfnodeparttextbox=\pgf@x%
+ \fi%
+}
+\def\sseq@drawnode{%
+ \pgfutil@tempdima=\pgflinewidth%
+ {%
+ \tikz@mode%
+ %\iftikz@mode@clip \sseq@error@internal{Clip shouldn't happen here, but this error should be caught earlier}{}\fi %
+ \iftikz@mode@draw%
+ \iftikz@mode@double%
+ % Change line width
+ \begingroup%
+ \pgfsys@beginscope%
+ \tikz@double@setup%
+ \fi%
+ \fi%
+ %
+ % Step 10: Do stroke/fill as needed
+ %
+ \sseq@eval{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi%
+ \iftikz@mode@draw draw,\fi%
+ }}%
+ %
+ % Step 11: Double stroke, if necessary
+ %
+ \iftikz@mode@draw%
+ \iftikz@mode@double%
+ \pgfsys@endscope%
+ \endgroup%
+ \fi%
+ \fi
+ }%
+ \global\pgflinewidth=\pgfutil@tempdima%
+}
+
+%%%
+%%% Drawing edges
+%%%
+\def\sseq@ifinrange(#1){\sseq@ifinrange@#1,\sseq@nil}
+\def\sseq@ifinrange@#1,#2,#3\sseq@nil{%
+ \sseq@tempx=#1\relax\sseq@tempy=#2\relax
+ \sseq@outofrangetrue
+ \ifnum\sseq@tempx<\sseq@xmaxpp\relax\ifnum\sseq@tempx>\sseq@xminmm\relax\ifnum\sseq@tempy<\sseq@ymaxpp\relax\ifnum\sseq@tempy>\sseq@yminmm\relax
+ \sseq@outofrangefalse
+ \fi\fi\fi\fi
+ \ifsseq@outofrange
+ \@xp\pgfutil@secondoftwo
+ \else
+ \@xp\pgfutil@firstoftwo
+ \fi
+}
+
+\def\sseq@fullcoord@to@partialcoord(#1){\sseq@fullcoord@to@partialcoord@#1,\@nil}
+\def\sseq@fullcoord@to@partialcoord@#1,#2,#3\@nil{{#1cm}{#2cm}}
+% #1 -- source (full)
+% #2 -- target (full)
+% #3 -- which type of edge (either "structline" or "differential")
+% #4 -- options
+\def\sseq@drawedge(#1)(#2)#3#4{%
+ \begingroup\pgfscope
+ \def\sseq@edgetype{#3}
+ \let\sseq@edgesourceanchor\pgfutil@empty
+ \let\sseq@edgetargetanchor\pgfutil@empty
+%
+ \sseq@needstikzfalse
+ \def\pgfkeysdefaultpath{/sseqpages/#3/}%
+ \sseq@options@bothpassmode
+ \sseq@thesseqstyle
+ \sseq@theedgestyle\csname sseq@the#3style\endcsname\the\sseq@scope@toks
+ #4%
+ \sseq@eval{\@nx\pgftransformshift{\@nx\pgfpoint{-\the\sseq@x cm}{-\the\sseq@y cm}}}%
+ % First calculate actual start and end of the edge
+ \let\tempaf\pgfutil@empty
+ \ifx\sseq@edgesourceanchor\pgfutil@empty % Check that the source doesn't have a specified anchor
+ \def\tempa{\pgfpointanchor{sseq{#1}}{center}}% if so, start by taking the center of that coordinate
+ \else
+ \edef\tempa{\@nx\pgfpointanchor{sseq{#1}}{\sseq@edgesourceanchor}} % If it has an anchor, use that
+ \let\tempaf\tempa
+ \fi
+ \ifx\sseq@edgetargetanchor\pgfutil@empty % check that the target doesn't have a specified anchor
+ \def\tempb{\pgfpointshapeborder{sseq{#2}}{\tempa}}% if so, our end point is the point on the boundary of node b that is in the direction of our initial start coordinate
+ \else
+ \edef\tempb{\@nx\pgfpointanchor{sseq{#2}}{\sseq@edgetargetanchor}}% If it has a specified anchor, use that
+ \fi
+ \let\tempbf\tempb
+ \ifx\tempaf\pgfutil@empty%
+ \def\tempaf{\pgfpointshapeborder{sseq{#1}}{\tempb}}%
+ \fi
+%
+ \tikz@options
+ \tikz@mode
+ \def\temparrowstartspec{}%
+ \def\temparrowendspec{}%
+ \pgfcoordinate{tempa}{\tempaf}%
+ \pgfcoordinate{tempb}{\tempbf}%
+ \pgftransformreset
+ \sseq@ifinrange(#1){\sseq@ifinrange(#2){\sseq@outofrangefalse}{\sseq@outofrangetrue}}{\sseq@outofrangetrue}%
+ \ifsseq@outofrange
+ \sseq@handleoffpageedge{#1}{#2}{#3}%
+ \fi
+ \ifsseq@drawedge
+ % TODO: should some sort of transformation manipulation be here? Maybe allow user to specify preference?
+ % Don't draw dots on very short segments
+ \pgfpointdiff{\tempbf}{\tempaf}
+ \pgfmathveclen{\pgf@x}{\pgf@y}%
+ \@xp\pgfmathint\@xp{\pgfmathresult}%
+ \ifnum\pgfmathresult<10\relax%%17? % TODO: Fix this predicate
+ \tikzset{every text node part/.append code={\pgfsetcolor{white}}}% I wonder why this is here...
+ \ifx\temparrowstartspec\pgfutil@empty
+ \else
+ \def\temparrowstartspec{\pgfsetarrowsstart{}}%
+ \fi
+ \ifx\temparrowendspec\pgfutil@empty
+ \else
+ \def\temparrowendspec{\pgfsetarrowsend{}}%
+ \fi
+ \fi
+ \ifsseq@needstikz
+ \draw[/sseqpages,
+ /utils/exec={\sseq@thesseqstyle\sseq@theedgestyle\csname sseq@the#3style\endcsname\the\sseq@scope@toks
+ \temparrowstartspec\temparrowendspec #4}%
+ ] (tempa) to (tempb);%
+ \else
+ \temparrowstartspec
+ \temparrowendspec
+ \pgfpathmoveto{\pgfpointanchor{tempa}{center}}%
+ \pgfpathlineto{\pgfpointanchor{tempb}{center}}%
+ \sseq@eval{\noexpand\pgfusepath{%
+ \iftikz@mode@fill fill,\fi
+ \iftikz@mode@draw draw,\fi
+ }}%
+ \fi
+ \fi
+ \sseq@breakpoint
+ \endpgfscope\endgroup
+}
+
+% TODO: this macro is super expensive. Make it faster (avoid
+\def\sseq@handleoffpageedge#1#2#3{
+ \pgfpathmoveto{\tempaf}%
+ \pgfpathlineto{\tempbf}%
+ \pgfgetpath\thispath
+ \pgfusepath{discard}%
+ \pgfintersectionofpaths{\pgfsetpath\sseq@theclippath}{\pgfsetpath\thispath}%
+ \ifcase\pgfintersectionsolutions\relax
+ % No intersections, but one or both endpoints may be out of range but still in clipping region due to scaling. Add ellipses as appropriate.
+ \sseq@ifinrange(#1){% If the first endpoint is in range, the second must be out of range b/c sseq@outofrange is true.
+ %\edef\temparrowendspec{\@nx\pgfsetarrowsend{\csname sseq@runoffarrow@end@#3@spec\endcsname}}
+ }{%
+ \sseq@ifinrange(#2){%
+ \edef\temparrowstartspec{\@nx\pgfsetarrowsstart{\csname sseq@runoffarrow@start@#3@spec\endcsname}}
+ }{\sseq@drawedge@handletrickyedge}% uh-oh, both ends are out of range
+ }%
+ \or
+ \sseq@ifinrange(#1){% If the startpoint is in range, the intersection must be the end.
+ \def\tempbf{\pgfpointintersectionsolution{1}}
+ \edef\temparrowendspec{\@nx\pgfsetarrowsend{\csname sseq@runoffarrow@end@#3@spec\endcsname}}
+ \pgfcoordinate{tempb}{\tempbf}
+ }{%
+ \sseq@ifinrange(#2){% If the startpoint is out of range and the endpoint is in range, the intersection must be the start
+ \def\tempaf{\pgfpointintersectionsolution{1}}%
+ \edef\temparrowstartspec{\@nx\pgfsetarrowsstart{\csname sseq@runoffarrow@start@#3@spec\endcsname}}%
+ \pgfcoordinate{tempa}{\tempaf}%
+ }{\sseq@drawedge@handletrickyedge}% Uh-oh, both ends are out of range.
+ }
+ \or% an orphan
+ \ifsseq@draworphanedges
+ \sseq@drawedge@handleorphan
+ \else
+ \sseq@drawedgefalse % Don't draw "orphaned edges"
+ \fi
+ \else
+ \sseq@error{clip-not-convex}%
+ \sseq@breakfifi
+ \fi
+}
+
+\def\sseq@drawedge@handletrickyedge{%
+ \ifsseq@draworphanedges
+ \pgfintersectionofpaths{\pgfsetpath\sseq@therangepath}{\pgfsetpath\thispath}%
+ \ifnum\pgfintersectionsolutions=\z@
+ \sseq@drawedgefalse % don't draw orphan edges that never intersect actual range
+ \else% Now we have to make a line through tempa and tempb long enough so that it intersects the original clip area twice.
+ \pgfmathanglebetweenpoints{\pgfpointanchor{tempa}{center}}{\pgfpointanchor{tempb}{center}}%
+ \edef\tempangle{\pgfmathresult}
+ \pgfpathmoveto{\pgfpointadd{\pgfpointanchor{tempa}{center}}{\pgfpointpolar{\tempangle}{100cm}}}% a really long line
+ \pgfpathlineto{\pgfpointadd{\pgfpointanchor{tempa}{center}}{\pgfpointpolar{\tempangle}{-100cm}}}%
+ \pgfgetpath\thispath
+ \pgfusepath{discard}
+ \pgfintersectionofpaths{\pgfsetpath\sseq@theclippath}{\pgfsetpath\thispath}
+ \sseq@drawedge@handleorphan
+ \fi
+ \else
+ \sseq@drawedgefalse
+ \fi
+}
+
+
+\def\sseq@drawedge@handleorphan{%
+ \def\tempaf{\pgfpointintersectionsolution{1}}%
+ \def\tempbf{\pgfpointintersectionsolution{2}}%
+ \edef\temparrowstartspec{\@nx\pgfsetarrowsstart{\csname sseq@runoffarrow@start@\sseq@edgetype @spec\endcsname}}%
+ \edef\temparrowendspec{\@nx\pgfsetarrowsend{\csname sseq@runoffarrow@end@\sseq@edgetype @spec\endcsname}}%
+ \pgfcoordinate{tempa}{\tempaf}%
+ \pgfcoordinate{tempb}{\tempbf}%
+}
+
+
+%
+% #1 -- first coordinate
+% #2 -- second coordinate
+% #3 -- uid
+\def\sseq@circleclass@draw#1#2#3{
+ \begingroup
+ \pgfmathanglebetweenpoints{\pgfpointanchor{sseq{#2}}{center}}{\pgfpointanchor{sseq{#3}}{center}}
+ \let\tempangle\pgfmathresult
+ \let\tikz@lib@fit@scan@handle\sseq@fit@tikz@lib@fit@scan@handle % install fit modifications.
+ \let\tikz@calc@anchor\sseq@fit@tikz@calc@anchor
+ \sseq@tempiftrue
+ \node[
+ rotate fit=\tempangle,
+ /utils/exec={\sseq@thesseqstyle\sseq@thecircleclassstyle\the\sseq@scope@toks\sseq@savedoptioncode
+ \sseq@obj{#1.options}
+ \sseq@obj{#1.fitnodes}
+ \@xp\pgfkeysalso\@xp{\romannumeral0\sseq@obj{#1.tikzprimoptions}}
+ }
+ ] {};
+ \endgroup
+}
+% Modifies tikz commands \tikz@lib@fit@scan@handle from \pgf\frontendlayer\tikz\libraries\tikzlibraryfit.code.tex line 81 and
+% \tikz@calc@anchor from \pgf\frontendlayer\tikz\tikz.code.tex line 5164
+% make it so that fit silently ignores nodes that are not defined.
+% This is copied with modification from \pgf\frontendlayer\tikz\libraries\tikzlibraryfit.code.tex line 81
+\def\sseq@fit@tikz@lib@fit@scan@handle#1{%
+ \ifsseq@tempif % this has been set in the following macro to be true if there is a node with the given name. If it's not true, ignore this.
+ \iftikz@shapeborder%
+ % Ok, fit all four external anchors, if they exist
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{west}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{east}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{north}}%
+ \tikz@lib@fit@adjust{\pgfpointanchor{\tikz@shapeborder@name}{south}}%
+ \else%
+ \tikz@lib@fit@adjust{#1}%
+ \fi%
+ \fi
+ \sseq@tempiftrue
+ \tikz@lib@fit@scan%
+}
+
+% This is copied with modification from \pgf\frontendlayer\tikz\tikz.code.tex line 5164
+\def\sseq@fit@tikz@calc@anchor#1.#2\tikz@stop{%
+ \pgfutil@ifundefined{pgf@sh@ns@#1}{\sseq@tempiffalse}{%If the node doesn't exist, don't throw an error but record that we should skip it
+ \pgfpointanchor{\tikz@pp@name{#1}}{#2}%
+ }%s
+}
+
+
+%% New shapes and arrows
+%% These use lots of keys with spaces so it's convenient to turn off ExplSyntax.
+
+% Stolen from: https://tex.stackexchange.com/a/24621
+\pgfqkeys{/pgf}{
+ ellipse ratio/.code={\pgfkeyssetvalue{/pgf/ellipse ratio}{#1}},
+ ellipse ratio/.initial=1
+}
+\pgfdeclareshape{newellipse}
+{
+ \inheritsavedanchors[from=ellipse]
+ \inheritanchorborder[from=ellipse]
+ \savedanchor\radius{%
+ %
+ % Caculate ``height radius''
+ %
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@y by\pgf@yb%
+ %
+ % Caculate ``width radius''
+ %
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@x by\pgf@xb%
+ %
+ % Adjust
+ %
+ \pgfkeysgetvalue{/pgf/ellipse ratio}{\ratioscale}
+ \pgfmathsetmacro\widthfactor{sqrt(\ratioscale^2+1)/\ratioscale}
+ \pgfmathsetmacro\heightfactor{sqrt(\ratioscale^2+1)}
+ \pgf@x=\widthfactor\pgf@x%
+ \pgf@y=\heightfactor\pgf@y%
+ %
+ % Adjust height, if necessary
+ %
+ \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@y<.5\pgf@yc%
+ \pgf@y=.5\pgf@yc%
+ \fi%
+ %
+ % Adjust width, if necessary
+ %
+ \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}%
+ \ifdim\pgf@x<.5\pgf@xc%
+ \pgf@x=.5\pgf@xc%
+ \fi%
+ %
+ % Add outer sep
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \advance\pgf@x by\pgf@xb%
+ \advance\pgf@y by\pgf@yb%
+ }
+
+ \inheritanchor[from=ellipse]{center}
+ \inheritanchor[from=ellipse]{mid}
+ \inheritanchor[from=ellipse]{base}
+ \inheritanchor[from=ellipse]{north}
+ \inheritanchor[from=ellipse]{south}
+ \inheritanchor[from=ellipse]{west}
+ \inheritanchor[from=ellipse]{mid west}
+ \inheritanchor[from=ellipse]{base west}
+ \inheritanchor[from=ellipse]{north west}
+ \inheritanchor[from=ellipse]{south west}
+ \inheritanchor[from=ellipse]{east}
+ \inheritanchor[from=ellipse]{mid east}
+ \inheritanchor[from=ellipse]{base east}
+ \inheritanchor[from=ellipse]{north east}
+ \inheritanchor[from=ellipse]{south east}
+
+ \inheritbackgroundpath[from=ellipse]
+}
+
+%%
+%%
+%% n concentric circles
+%%
+
+\tikzset{circlen/.code={\def\circlen@n{#1}\pgfkeysalso{shape=circlen@shape}}}
+\pgfdeclareshape{circlen@shape}
+{
+ \savedanchor\centerpoint{%
+ \pgf@x=.5\wd\pgfnodeparttextbox%
+ \pgf@y=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
+ }
+
+ \saveddimen\radius{%
+ %
+ % Caculate ``height radius''
+ %
+ \pgf@ya=.5\ht\pgfnodeparttextbox%
+ \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
+ \advance\pgf@ya by\pgf@yb%
+ %
+ % Caculate ``width radius''
+ %
+ \pgf@xa=.5\wd\pgfnodeparttextbox%
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \advance\pgf@xa by\pgf@xb%
+ %
+ % Calculate length of radius vector:
+ %
+ \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
+ \ifdim\pgf@x>\pgf@y%
+ \c@pgf@counta=\pgf@x%
+ \ifnum\c@pgf@counta=\z@%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@xa=16\pgf@xa\relax%
+ \divide\pgf@xa by\c@pgf@counta%
+ \pgf@xa=16\pgf@xa\relax%
+ \fi%
+ \else%
+ \c@pgf@counta=\pgf@y%
+ \ifnum\c@pgf@counta=\z@%
+ \else%
+ \divide\c@pgf@counta by 255\relax%
+ \pgf@ya=16\pgf@ya\relax%
+ \divide\pgf@ya by\c@pgf@counta%
+ \pgf@xa=16\pgf@ya\relax%
+ \fi%
+ \fi%
+ \pgf@x=\pgf@xa%
+ %
+ % If necessary, adjust radius so that the size requirements are
+ % met:
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%
+ \ifdim\pgf@x<.5\pgf@xb%
+ \pgf@x=.5\pgf@xb%
+ \fi%
+ \ifdim\pgf@x<.5\pgf@yb%
+ \pgf@x=.5\pgf@yb%
+ \fi%
+ %
+ % Now, add larger of outer sepearations.
+ %
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgf@x by\pgf@yb%
+ \else%
+ \advance\pgf@x by\pgf@xb%
+ \fi%
+ \pgf@xb=2pt
+ \multiply\pgf@xb\circlen@n
+ \advance\pgf@x\pgf@xb
+ \advance\pgf@x-2pt\relax
+ }
+
+ %
+ % Anchors
+ %
+ \anchor{center}{\centerpoint}
+ \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}
+ \anchor{base}{\centerpoint\pgf@y=0pt}
+ \anchor{north}{\centerpoint\advance\pgf@y by\radius}
+ \anchor{south}{\centerpoint\advance\pgf@y by-\radius}
+ \anchor{west}{\centerpoint\advance\pgf@x by-\radius}
+ \anchor{east}{\centerpoint\advance\pgf@x by\radius}
+ \anchor{mid west}{\centerpoint\advance\pgf@x by-\radius\pgfmathsetlength\pgf@y{.5ex}}
+ \anchor{mid east}{\centerpoint\advance\pgf@x by\radius\pgfmathsetlength\pgf@y{.5ex}}
+ \anchor{base west}{\centerpoint\advance\pgf@x by-\radius\pgf@y=0pt}
+ \anchor{base east}{\centerpoint\advance\pgf@x by\radius\pgf@y=0pt}
+ \anchor{north west}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@xa
+ }
+ \anchor{south west}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by-0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@xa
+ }
+ \anchor{north east}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by0.707107\pgf@xa
+ }
+ \anchor{south east}{
+ \centerpoint
+ \pgf@xa=\radius
+ \advance\pgf@x by0.707107\pgf@xa
+ \advance\pgf@y by-0.707107\pgf@xa
+ }
+ \anchorborder{
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \edef\pgf@marshal{%
+ \noexpand\pgfpointborderellipse
+ {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}
+ {\noexpand\pgfqpoint{\radius}{\radius}}%
+ }%
+ \pgf@marshal%
+ \pgf@xa=\pgf@x%
+ \pgf@ya=\pgf@y%
+ \centerpoint%
+ \advance\pgf@x by\pgf@xa%
+ \advance\pgf@y by\pgf@ya%
+ }
+
+ %
+ % Background path
+ %
+ \behindbackgroundpath{
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \sseq@tempcount=\@ne
+ \loop
+ \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}%
+ \advance\pgfutil@tempdima-2pt\relax
+ \advance\sseq@tempcount\@ne
+ \ifnum\sseq@tempcount<\circlen@n \repeat
+ \tikz@mode
+ \sseq@eval{\noexpand\pgfusepath{
+ \iftikz@mode@draw draw,\fi
+ }}
+ }
+ \backgroundpath{%
+ \pgfutil@tempdima=\radius%
+ \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
+ \ifdim\pgf@xb<\pgf@yb%
+ \advance\pgfutil@tempdima by-\pgf@yb%
+ \else%
+ \advance\pgfutil@tempdima by-\pgf@xb%
+ \fi%
+ \advance\pgfutil@tempdima2pt\relax
+ \pgfutil@tempdimb=-2pt\relax
+ \multiply\pgfutil@tempdimb\circlen@n
+ \advance\pgfutil@tempdima\pgfutil@tempdimb\relax
+ \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}
+ }
+}
+
+
+
+% For out of bounds edges:
+
+\pgfdeclarearrow{
+ name = ...,
+ parameters = { \the\pgfarrowlength\the\pgflinewidth},
+ setup code = {
+ % The different end values:
+ \pgfarrowssetlineend{-\pgfarrowlength}
+ \pgfarrowssetbackend{-0.6\pgfarrowlength}
+ % The hull
+ \pgfarrowshullpoint{-\pgfarrowlength}{0pt}
+ \pgfarrowshullpoint{\pgfarrowlength}{0pt}
+ % Saves: Only the length:
+ \pgfarrowssavethe\pgfarrowlength
+ \pgfarrowssavethe\pgflinewidth
+ },
+ drawing code = {
+ \pgfpathcircle{\pgfpoint{-0.7\pgfarrowlength}{0pt}}{1.5\pgflinewidth}
+ \pgfpathcircle{\pgfpoint{-0.4\pgfarrowlength}{0pt}}{1.5\pgflinewidth}
+ \pgfpathcircle{\pgfpoint{-0.1\pgfarrowlength}{0pt}}{1.5\pgflinewidth}
+ \pgfpathclose
+ \pgfusepathqfill
+ },
+ defaults = { length = 0.3cm }
+} \ No newline at end of file