diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex | 4419 |
1 files changed, 4419 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex new file mode 100644 index 00000000000..2f11e6a4fd2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex @@ -0,0 +1,4419 @@ +% Copyright 2006 by Till Tantau and Mark Wibrow +% +% 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[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryshapes.geometric.code.tex,v 1.22 2008/02/01 17:09:04 vibrovski Exp $ + +\pgfdeclareshape{ellipse} +% +% Draws a circle around the text +% +{ + \savedanchor\centerpoint{% + \pgf@x=.5\wd\pgfnodeparttextbox% + \pgf@y=.5\ht\pgfnodeparttextbox% + \advance\pgf@y by-.5\dp\pgfnodeparttextbox% + } + \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 + % + \pgf@x=1.4142136\pgf@x% + \pgf@y=1.4142136\pgf@y% + % + % Adjust hieght, 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% + } + + % + % Anchors + % + \anchor{center}{\centerpoint} + \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}} + \anchor{base}{\centerpoint\pgf@y=0pt} + \anchor{north} + { + \pgf@process{\radius} + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@y by\pgf@ya + } + \anchor{south} + { + \pgf@process{\radius} + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@y by-\pgf@ya + } + \anchor{west} + { + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by-\pgf@xa + } + \anchor{mid west} + {% + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by-\pgf@xa% + \pgfmathsetlength\pgf@y{.5ex} + } + \anchor{base west} + {% + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by-\pgf@xa% + \pgf@y=0pt + } + \anchor{north west} + { + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@x by-0.707107\pgf@xa + \advance\pgf@y by0.707107\pgf@ya + } + \anchor{south west} + { + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@x by-0.707107\pgf@xa + \advance\pgf@y by-0.707107\pgf@ya + } + \anchor{east} + {% + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by\pgf@xa + } + \anchor{mid east} + {% + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by\pgf@xa% + \pgfmathsetlength\pgf@y{.5ex} + } + \anchor{base east} + {% + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@process{\centerpoint} + \advance\pgf@x by\pgf@xa% + \pgf@y=0pt + } + \anchor{north east} + { + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@x by0.707107\pgf@xa + \advance\pgf@y by0.707107\pgf@ya + } + \anchor{south east} + { + \pgf@process{\radius} + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\centerpoint} + \advance\pgf@x by0.707107\pgf@xa + \advance\pgf@y by-0.707107\pgf@ya + } + \anchorborder{ + \edef\pgf@marshal{% + \noexpand\pgfpointborderellipse + {\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + {\noexpand\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 + % + \backgroundpath + { + \pgf@process{\radius}% + \pgfutil@tempdima=\pgf@x% + \pgfutil@tempdimb=\pgf@y% + \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% + \advance\pgfutil@tempdima by-\pgf@xb% + \advance\pgfutil@tempdimb by-\pgf@yb% + \pgfpathellipse{\centerpoint}{\pgfqpoint{\pgfutil@tempdima}{0pt}}{\pgfqpoint{0pt}{\pgfutil@tempdimb}}% + } +} + + + + +% Set the recommended shape aspect ratio +% +% #1 = aspect ratio +% +% Example: +% +% \pgfsetshapeaspect{1.5} + +% Keys for shape aspect ratio. +% +% /pgf/aspect : recommended width/height quotient. +% +\pgfkeys{/pgf/.cd, + aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz... + shape aspect/.initial=1,% but this is consistent with other pgfset stuff. + shape aspect/.code={% + \pgfkeys{/pgf/aspect=#1}% + \pgfkeyssetvalue{/pgf/shape aspect}{#1} + }% +} + + +\def\pgfsetshapeaspect#1{% + \def\pgfshapeaspect{#1}% + % Invert + \pgfutil@tempdima=#1pt% + \pgfutil@tempdima=.125\pgfutil@tempdima% + \c@pgf@counta=\pgfutil@tempdima\relax% 8192*determinant + \pgfutil@tempdima=8192pt% + \divide\pgfutil@tempdima by\c@pgf@counta% + \edef\pgfshapeaspectinverse{\pgf@sys@tonumber{\pgfutil@tempdima}} +} + +\pgfsetshapeaspect{1} + +\pgfdeclareshape{diamond} +{ + \savedanchor\outernortheast{% + % + % Calculate width and height of the inner rectangle + % + \pgf@xa=.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@xa by\pgf@xc% + \pgf@ya=.5\ht\pgfnodeparttextbox% + \advance\pgf@ya by.5\dp\pgfnodeparttextbox% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@ya by\pgf@yc% + % + % Calculate width and height of diamond + % + \pgf@x=\pgf@xa% + \advance\pgf@x by\pgfshapeaspect\pgf@ya% + \pgf@y=\pgfshapeaspectinverse\pgf@xa% + \advance\pgf@y by\pgf@ya% + % + % Check against minimum height/width + % + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}% + \pgf@xb=.5\pgf@xb% + \ifdim\pgf@x<\pgf@xb% + % yes, too small. Enlarge... + \pgf@x=\pgf@xb% + \fi% + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}% + \pgf@yb=.5\pgf@yb% + \ifdim\pgf@y<\pgf@yb% + % yes, too small. Enlarge... + \pgf@y=\pgf@yb% + \fi% + % + % Add outer border + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \advance\pgf@x by\pgf@xa% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + \advance\pgf@y by\pgf@ya% + } + \savedanchor\text{% + \pgf@x=-.5\wd\pgfnodeparttextbox% + \pgf@y=-.5\ht\pgfnodeparttextbox% + \advance\pgf@y by.5\dp\pgfnodeparttextbox% + } + + % + % Anchors + % + \anchor{text}{\text}% + \anchor{center}{\pgfpointorigin}% + \anchor{mid}{% + \pgf@process{\text}% + \pgf@x=0pt% + \pgfmathsetlength\pgf@ya{.5ex} + \advance\pgf@y by\pgf@ya% + } + \anchor{base}{\pgf@process{\text}\pgf@x=0pt } + \anchor{north}{\pgf@process{\outernortheast}\pgf@x=0pt} + \anchor{south}{\pgf@process{\outernortheast}\pgf@x=0pt\pgf@y=-\pgf@y} + \anchor{west}{\pgf@process{\outernortheast}\pgf@x=-\pgf@x\pgf@y=0pt} + \anchor{north west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=.5\pgf@y} + \anchor{south west}{\pgf@process{\outernortheast}\pgf@x=-.5\pgf@x\pgf@y=-.5\pgf@y} + \anchor{east}{\pgf@process{\outernortheast}\pgf@y=0pt} + \anchor{north east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=.5\pgf@y} + \anchor{south east}{\pgf@process{\outernortheast}\pgf@x=.5\pgf@x\pgf@y=-.5\pgf@y} + \anchorborder{% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\outernortheast}% + \ifdim\pgf@xa>0pt% + \else% + \pgf@x=-\pgf@x% + \fi% + \ifdim\pgf@ya>0pt% + \else% + \pgf@y=-\pgf@y% + \fi% + \edef\pgf@marshal{% + \noexpand\pgfpointintersectionoflines + {\noexpand\pgfpointorigin} + {\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}} + {\noexpand\pgfqpoint{\the\pgf@x}{0pt}} + {\noexpand\pgfqpoint{0pt}{\the\pgf@y}}% + }% + \pgf@process{\pgf@marshal}% + } + + % + % Background path + % + \backgroundpath{ + \pgf@process{\outernortheast}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgfmathsetlength{\pgf@xa}{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength{\pgf@ya}{\pgfkeysvalueof{/pgf/outer ysep}}% + \advance\pgf@xc by-1.414213\pgf@xa% + \advance\pgf@yc by-1.414213\pgf@ya% + \pgfpathmoveto{\pgfqpoint{\pgf@xc}{0pt}}% + \pgfpathlineto{\pgfqpoint{0pt}{\pgf@yc}}% + \pgfpathlineto{\pgfqpoint{-\pgf@xc}{0pt}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@yc}}% + \pgfpathclose% + } +} + + + + + + +\newif\ifpgf@lib@shapes@starouterradiususesratio +\pgf@lib@shapes@starouterradiususesratiotrue + +% Keys for star shape +% +% /pgf/star points : Number of points on the star. +% /pgf/star point height : The height of the outer star points. +% /pgf/star point ratio : The ratio of the outer point and inner point radii. + +\pgfkeys{/pgf/.cd, + star points/.initial=5, + star point height/.initial=.5cm, + star point height/.code={% + \def\pgf@lib@temp{#1}% + \pgfkeyslet{/pgf/star point height}{\pgf@lib@temp}% + \pgf@lib@shapes@starouterradiususesratiofalse% + }, + star point ratio/.initial=1.5, + star point ratio/.code={% + \def\pgf@lib@temp{#1}% + \pgfkeyslet{/pgf/star point ratio}{\pgf@lib@temp}% + \pgf@lib@shapes@starouterradiususesratiotrue% + }% + star rotate/.style={/pgf/shape border rotate=#1}% For compatability with 1.18 +} + + +% Shape star. +% +\pgfdeclareshape{star}{ + \savedmacro\totalstarpoints{% + \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/star points}}% + \multiply\c@pgf@counta2\relax% + \edef\totalstarpoints{\the\c@pgf@counta}% + } + \savedmacro\anglestep{% + \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/star points}}% + \let\anglestep\pgfmathresult% + } + \savedmacro\calculateradii{% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + % + % Calculate the incircle radius. + % + \pgf@x1.41421\pgf@x% + \edef\innerradius{\the\pgf@x}% + % + % Calculate the circumcircle radius. + % + % Use the star point height or the star point ratio? + % + \ifpgf@lib@shapes@starouterradiususesratio% + \pgfmathparse{\pgfkeysvalueof{/pgf/star point ratio}}% + \expandafter\pgf@x\pgfmathresult\pgf@x% + \else% + \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/star point height}}% + \fi% + \pgf@xc\pgf@x% + % + % Accommodate the larger of the minimum height/width. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya>\pgf@xa% + \pgf@xa\pgf@ya% + \fi% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \edef\outerradius{\the\pgf@x}% + % + % If the outer radius has been enlarged, adjust the inner radius... + % + \ifdim\pgf@x>\pgf@xc% + % + % ...using the star point ratio, or... + % + \ifpgf@lib@shapes@starouterradiususesratio% + \pgfmathreciprocal{\pgfkeysvalueof{/pgf/star point ratio}}% + \pgf@xa\pgfmathresult\pgf@x\relax% + \edef\innerradius{\the\pgf@xa}% + \else% + % + % The star point height. + % + \pgf@xa\pgf@x\relax% + \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/star point height}}% + \edef\innerradius{\the\pgf@xa}% + \fi% + \fi% + \edef\outerradius{\the\pgf@x}% + % + % Now calculate the anchor radii from the outer sep. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@ya>\pgf@xa% + \pgf@xa\pgf@ya% + \fi + % + % Take into account the miter length... + % + \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/star points}}% + \let\angletofirstpoint\pgfmathresult% + \pgfmathmultiply@{\angletofirstpoint}{2}% + \let\angletosecondpoint\pgfmathresult% + % + % ...for the outer radius... + % + \pgfmathanglebetweenlines% + {\pgfqpointpolar{\angletofirstpoint}{\outerradius}}% + {\pgfqpointpolar{\angletosecondpoint}{\innerradius}}% + {\pgfqpointpolar{\angletofirstpoint}{\outerradius}}% + {\pgfqpointpolar{0}{\innerradius}}% + \pgfmathdivide@{\pgfmathresult}{2}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outerradius\relax% + \advance\pgf@x\pgfmathresult\pgf@xa% + \edef\anchorouterradius{\the\pgf@x}% + % + % ...and for the inner radius. + % + \pgfmathanglebetweenlines% + {\pgfqpointpolar{\angletofirstpoint}{\innerradius}}% + {\pgfqpointpolar{0}{\outerradius}}% + {\pgfqpointpolar{\angletofirstpoint}{\innerradius}}% + {\pgfqpointpolar{\angletosecondpoint}{\outerradius}}% + \pgfmathdivide@{\pgfmathresult}{2}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\innerradius\relax% + \advance\pgf@x\pgfmathresult\pgf@xa% + \edef\anchorinnerradius{\the\pgf@x}% + % + % Save all radii. + % + \addtosavedmacro{\innerradius}% + \addtosavedmacro{\outerradius}% + \addtosavedmacro{\anchorinnerradius}% + \addtosavedmacro{\anchorouterradius}% + } + \savedmacro\startangle{% + \pgfmathadd{90}{\pgfkeysvalueof{/pgf/shape border rotate}}% + \let\startangle\pgfmathresult% + } + % + % Saved anchors. + % + \savedanchor{\centerpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor{\midpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + % + % Other anchors. + % +% + % Other anchors. + % + \anchor{center}{\centerpoint}% + \anchor{mid}{\centerpoint\pgfmathsetlength\pgf@y{.5ex}}% + \anchor{base}{\centerpoint\pgf@y=0pt}% + \anchor{north}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{0pt}{\anchorouterradius}}}% + \anchor{south}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{0pt}{-\anchorouterradius}}}% + \anchor{east}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{0pt}}}% + \anchor{west}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{0pt}}}% + \anchor{north east}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{\anchorouterradius}}}% + \anchor{north west}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{\anchorouterradius}}}% + \anchor{south east}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{\anchorouterradius}{-\anchorouterradius}}}% + \anchor{south west}{% + \calculateradii% + \csname pgf@anchor@star@border\endcsname{\pgfqpoint{-\anchorouterradius}{-\anchorouterradius}}}% + % + % Background path. + % + \backgroundpath{% + \calculateradii% + \let\angle\startangle% + \pgfpathmoveto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\startangle}{\outerradius}}}% + \pgfmathloop% + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \ifnum\pgfmathcounter=\totalstarpoints% + \pgfpathclose% + \else% + \ifodd\pgfmathcounter + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\innerradius}}}% + \else% + \pgfpathlineto{\pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\outerradius}}}% + \fi% + \repeatpgfmathloop% + }% + % + % Define points on the anchor border. + % + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + % + % Locate the appropriate sides on the star border... + % + \pgfmathsubtract@{\pgfmathresult}{\startangle}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \pgfmathdivide@{\pgfmathresult}{\anglestep}% + \pgfmathfloor@{\pgfmathresult}% + \afterassignment\pgfmath@gobbletilpgfmath@ + \c@pgf@counta\pgfmathresult\relax\pgfmath@ + \pgfmathmultiply@{\pgfmathresult}{\anglestep}% + \pgfmathadd@{\pgfmathresult}{\startangle}% + \let\firstangle\pgfmathresult% + \pgfmathadd@{\pgfmathresult}{\anglestep}% + \let\secondangle\pgfmathresult% + \calculateradii% + % + % ...and thus, the point on the star border. + % + \ifodd\c@pgf@counta + \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\firstangle}{+\anchorinnerradius}}% + }% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\secondangle}{+\anchorouterradius}}% + }% + \else% + \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\firstangle}{+\anchorouterradius}}% + }% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\secondangle}{+\anchorinnerradius}}% + }% + \fi% + } + % + % Some hackery. This is needed if a star is positioned using + % a `...point <n+1>' anchor, where n is the maximum number of + % points of any previously drawn star. + % + \pgfutil@g@addto@macro\pgf@sh@s@star{% + \c@pgf@counta\totalstarpoints\relax% + \divide\c@pgf@counta2\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \c@pgf@countb\c@pgf@counta\relax% + \advance\c@pgf@countb-1\relax% + \pgfutil@ifundefined{pgf@anchor@star@inner point\space\the\c@pgf@counta}{% + \expandafter\xdef\csname pgf@anchor@star@inner point\space\the\c@pgf@counta\endcsname{% + \noexpand\calculateradii% + \noexpand\pgfmathmultiply@{\the\c@pgf@countb}{\noexpand\anglestep}% + \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{2}% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\anglestep}% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}% + \noexpand\let\noexpand\angle\noexpand\pgfmathresult% + \noexpand\pgfpointadd{\noexpand\centerpoint}% + {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorinnerradius}}% + }% + \expandafter\xdef\csname pgf@anchor@star@outer point\space\the\c@pgf@counta\endcsname{% + \noexpand\calculateradii% + \noexpand\pgfmathmultiply@{\the\c@pgf@countb}{\noexpand\anglestep}% + \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{2}% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}% + \noexpand\let\noexpand\angle\noexpand\pgfmathresult% + \noexpand\pgfpointadd{\noexpand\centerpoint}% + {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorouterradius}}% + }% + }{\c@pgf@counta0\relax}% + \advance\c@pgf@counta-1\relax% + \repeatpgfmathloop% + }% +} + + + + +% Keys for shape regular polygon +% +% /pgf/regular polygon sides +% +\pgfkeys{/pgf/.cd, + regular polygon sides/.initial=5, + regular polygon rotate/.style={/pgf/shape border rotate=#1}% For compatability with 1.18 +} + + +% Shape Regular Polygon. +% +\pgfdeclareshape{regular polygon}{ + \savedmacro\sides{% + \pgfmathtruncatemacro\sides{\pgfkeysvalueof{/pgf/regular polygon sides}}% + } + \savedmacro\anglestep{% + \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/regular polygon sides}}% + \let\anglestep\pgfmathresult% + } + \savedmacro\calculateradii{% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + % + % Calculate i, the incircle radius + % + \pgf@x1.41421\pgf@x% + % + % Calculate r, the polygon radius + % + % r = i / cos(360 / s / 2) + % + % (s = polygon sides) + % + \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/regular polygon sides}}% + \pgfmathsec@{\pgfmathresult}% + \pgf@x\pgfmathresult\pgf@x% + % + % Accommodate the minimum width/height. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya>\pgf@xa% + \pgf@xa\pgf@ya% + \fi% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \edef\radius{\the\pgf@x}% + % + % Now calculate the anchor radius from the outer sep. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@ya>\pgf@xa% + \pgf@xa\pgf@ya% + \fi + % + % Take into account the miter length. + % + % m = o / sin (90 - (360 / s / 2)) + % + % (o = outer sep, s = sides) + % + \pgfmathdivide{180}{\pgfkeysvalueof{/pgf/regular polygon sides}}% + \pgfmathsubtract@{90}{\pgfmathresult}% + \pgfmathcosec@{\pgfmathresult}% + \advance\pgf@x\pgfmathresult\pgf@xa% + \edef\anchorradius{\the\pgf@x}% + % + % Save both radii. + % + \addtosavedmacro{\radius}% + \addtosavedmacro{\anchorradius}% + } + \savedmacro\startangle{% + \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/regular polygon sides}}% + \let\anglestep\pgfmathresult% + \pgfmathtruncatemacro\sides{\pgfkeysvalueof{/pgf/regular polygon sides}}% + \expandafter\ifodd\sides\relax% + \edef\pgfmathresult{90}% + \else% + \pgfmathdivide@{\anglestep}{2}% + \pgfmathsubtract@{90}{\pgfmathresult}% + \fi% + \pgfmathadd{\pgfmathresult}{\pgfkeysvalueof{/pgf/shape border rotate}}% + \let\startangle\pgfmathresult% + } + % + % Saved anchors. + % + \savedanchor{\centerpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor{\midpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + % + % Other anchors. + % + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint}% + \anchor{base}{\centerpoint\pgf@y=0pt}% + \anchor{north}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{0pt}{\anchorradius}}}% + \anchor{south}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{0pt}{-\anchorradius}}}% + \anchor{east}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{0pt}}}% + \anchor{west}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{0pt}}}% + \anchor{north east}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{\anchorradius}}}% + \anchor{north west}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{\anchorradius}}}% + \anchor{south east}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{\anchorradius}{-\anchorradius}}}% + \anchor{south west}{% + \calculateradii% + \csname pgf@anchor@regular polygon@border\endcsname{\pgfqpoint{-\anchorradius}{-\anchorradius}}}% + % + % Background path. + % + \backgroundpath{% + \calculateradii% + \pgfpathmoveto{% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{\startangle}{\radius}}% + }% + \let\angle\startangle% + \pgfmathloop% + \ifnum\pgfmathcounter=\sides\relax% + \pgfpathclose% + \else% + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \pgfpathlineto{% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{\angle}{\radius}}% + }% + \repeatpgfmathloop% + }% + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + % + % Locate the appropriate sides on the polygon border... + % + \pgfmathsubtract@{\pgfmathresult}{\startangle}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \pgfmathdivide@{\pgfmathresult}{\anglestep}% + \pgfmathfloor@{\pgfmathresult}% + \pgfmathmultiply@{\pgfmathresult}{\anglestep}% + \pgfmathadd@{\pgfmathresult}{\startangle}% + \let\firstangle\pgfmathresult% + \pgfmathadd@{\pgfmathresult}{\anglestep}% + \let\secondangle\pgfmathresult% + \calculateradii% + % + % ...and thus, the point on the polygon border. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfpoint{+\externalx}{+\externaly}}% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\firstangle}{+\anchorradius}}% + }% + {% + \pgfpointadd{\centerpoint}% + {\pgfqpointpolar{+\secondangle}{+\anchorradius}}% + }% + } + % + % More hackery for when the recuglar polygon is positioned using + % a `corner <n+1>' or `side <n+1>' anchor, where n is the maximum + % number of sides of any previously drawn regular polygon. + % + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@regular polygon\endcsname{% + \c@pgf@counta\sides\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \pgfutil@ifundefined{pgf@anchor@regular polygon@corner\space\the\c@pgf@counta}{% + % + % ...(manually \xdef as \gdef is normally used by \anchor)... + % + \expandafter\xdef\csname pgf@anchor@regular polygon@corner\space\the\c@pgf@counta\endcsname{% + \noexpand\calculateradii% + \noexpand\pgfmathsubtract@{\the\c@pgf@counta}{1}% + \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{\noexpand\anglestep}% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}% + \noexpand\let\noexpand\angle\noexpand\pgfmathresult% + \noexpand\pgfpointadd{\noexpand\centerpoint}% + {\noexpand\pgfqpointpolar{\noexpand\angle}{\noexpand\anchorradius}}% + }% + \expandafter\xdef\csname pgf@anchor@regular polygon@side\space\the\c@pgf@counta\endcsname{% + \noexpand\calculateradii% + \noexpand\pgfmathsubtract@{\the\c@pgf@counta}{1}% + \noexpand\pgfmathmultiply@{\noexpand\pgfmathresult}{\noexpand\anglestep}% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\startangle}% + \noexpand\let\noexpand\firstangle\noexpand\pgfmathresult% + \noexpand\pgfmathadd@{\noexpand\pgfmathresult}{\noexpand\anglestep}% + \noexpand\let\noexpand\secondangle\noexpand\pgfmathresult% + \noexpand\pgfpointlineattime{0.5}% + {\noexpand\pgfpointadd{\noexpand\centerpoint}% + {\noexpand\pgfqpointpolar{\noexpand\firstangle}{\noexpand\anchorradius}}}% + {\noexpand\pgfpointadd{\noexpand\centerpoint}% + {\noexpand\pgfqpointpolar{\noexpand\secondangle}{\noexpand\anchorradius}}}% + }% + }{\c@pgf@counta0\relax}% + \advance\c@pgf@counta-1\relax% + \repeatpgfmathloop% + }% +} + + + +% Keys for shape trapezium +% +% /pgf/trapezium left angle : angle of the left side. +% /pgf/trapezium right angle : angle of the right side. + +\pgfkeys{/pgf/.cd, + trapezium left angle/.initial=60, + trapezium right angle/.initial=60, + trapezium angle/.style={ + /pgf/trapezium left angle=#1, + /pgf/trapezium right angle=#1 + },% + trapezium stretches/.is if=pgf@lib@sh@trapeziumstretches,% + trapezium stretches body/.is if=pgf@lib@sh@trapeziumstretchesbody% +} + +\newif\ifpgf@lib@sh@trapeziumstretchesbody +\newif\ifpgf@lib@sh@trapeziumstretches + + +% Shape trapezium. +% +\pgfdeclareshape{trapezium}{ + \savedmacro\installtrapeziumparameters{% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \ifpgfshapeborderusesincircle% + % + % Get the rotation (no rounding). + % + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + % + % Use the radius of the incircle if required... + % + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + \pgf@y\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % Calculate the width and height of the node + % contents, according to any border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + \fi% + \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium left angle}}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\leftangle\pgfmathresult% + \ifdim\leftangle pt=0pt\relax% + \def\pgfmathresult{0}% + \else% + \pgfmathcot@{\leftangle}% + \fi% + \pgf@xa2\pgf@y% + \pgf@xa\pgfmathresult\pgf@xa% + \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium right angle}}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\rightangle\pgfmathresult% + \ifdim\rightangle pt=0pt\relax% + \def\pgfmathresult{0}% + \else% + \pgfmathcot@{\rightangle}% + \fi% + \pgf@xb2\pgf@y% + \pgf@xb\pgfmathresult\pgf@xb% + % + % Take into account minimum height and width. + % + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@y<.5\pgf@ya% + \ifpgf@lib@sh@trapeziumstretches% + \pgf@y.5\pgf@ya% + \else% + \ifpgf@lib@sh@trapeziumstretchesbody% + \pgf@y.5\pgf@ya% + \else% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}% + \pgf@yb.5\pgf@ya% + \pgf@yb\pgfmathresult\pgf@yb% + \pgf@y.5\pgf@ya% + \pgf@x\pgfmath@tonumber{\pgf@yb}\pgf@x% + \pgf@xa\pgfmath@tonumber{\pgf@yb}\pgf@xa% + \pgf@xb\pgfmath@tonumber{\pgf@yb}\pgf@xb% + \fi% + \fi% + \fi% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum width}}% + \pgf@xc2\pgf@x% + \ifdim\pgf@xa<0pt\relax% + \advance\pgf@xc-\pgf@xa% + \else% + \advance\pgf@xc\pgf@xa% + \fi% + \ifdim\pgf@xb<0pt\relax% + \advance\pgf@xc-\pgf@xb% + \else% + \advance\pgf@xc\pgf@xb% + \fi% + \ifdim\pgf@xc<\pgf@ya% + \ifpgf@lib@sh@trapeziumstretchesbody% + \pgf@xc-\pgf@xc% + \advance\pgf@xc\pgf@ya% + \advance\pgf@x.5\pgf@xc% + \else% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% + \pgf@ya\pgfmathresult\pgf@ya% + \pgf@x\pgfmath@tonumber{\pgf@ya}\pgf@x% + \pgf@xa\pgfmath@tonumber{\pgf@ya}\pgf@xa% + \pgf@xb\pgfmath@tonumber{\pgf@ya}\pgf@xb% + \ifpgf@lib@sh@trapeziumstretches% + \else% + \pgf@y\pgfmath@tonumber{\pgf@ya}\pgf@y% + \fi% + \fi% + \fi% + \edef\halfheight{\the\pgf@y}% + \edef\halfwidth{\the\pgf@x}% + \edef\leftextension{\the\pgf@xa}% + \edef\rightextension{\the\pgf@xb}% + \pgf@xc2\pgf@x% + % + % Take the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % The \externalradius is a length that is + % guarenteed to produce a point outside the trapezium. + % + \advance\pgf@xc2.0\pgf@x% + \pgf@yc\halfheight\relax% + \multiply\pgf@yc2\relax% + \advance\pgf@yc2.0\pgf@x% + \ifdim\pgf@xc<\pgf@yc% + \edef\externalradius{\the\pgf@yc}% + \else% + \edef\externalradius{\the\pgf@xc}% + \fi% + % + % Calculate the centre base and mid poins of the node. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \pgfextract@process\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \pgfextract@process\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + % + % Calculate each point on the trapezium (without rotation). + % + \pgfextract@process\lowerleftpoint{% + \centerpoint% + \advance\pgf@x-\halfwidth\relax% + \ifdim\leftextension>0pt\relax% + \advance\pgf@x-\leftextension\relax% + \fi% + \advance\pgf@y-\halfheight\relax% + }% + \pgfextract@process\upperleftpoint{% + \centerpoint% + \advance\pgf@x-\halfwidth\relax% + \ifdim\leftextension<0pt\relax% + \advance\pgf@x\leftextension\relax% + \fi% + \advance\pgf@y\halfheight\relax% + }% + \pgfextract@process\upperrightpoint{% + \centerpoint% + \advance\pgf@x\halfwidth\relax% + \ifdim\rightextension<0pt\relax% + \advance\pgf@x-\rightextension\relax% + \fi% + \advance\pgf@y\halfheight\relax% + }% + \pgfextract@process\lowerrightpoint{% + \centerpoint% + \advance\pgf@x\halfwidth\relax% + \ifdim\rightextension>0pt\relax% + \advance\pgf@x\rightextension\relax% + \fi% + \advance\pgf@y-\halfheight\relax% + }% + % + % Now calculate the adjustment for the miter length at each corner + % of the trapezium. This ensures more accurate anchor positioning + % when the line width is particularly thick. + % + \pgfextract@process\lowerleftmiter{% + \pgfmathanglebetweenlines{\lowerleftpoint}{\lowerrightpoint}{\lowerleftpoint}{\upperleftpoint}% + \pgfmathmultiply@{\pgfmathresult}{.5}% + \pgfmathtan@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x-\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y-\outersep\relax% + }% + \pgfextract@process\upperleftmiter{% + \pgfmathanglebetweenlines{\upperleftpoint}{\lowerleftpoint}{\upperleftpoint}{\upperrightpoint}% + \pgfmathmultiply@{\pgfmathresult}{.5}% + \pgfmathtan@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x-\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\outersep\relax% + }% + \pgfextract@process\upperrightmiter{% + \pgfmathanglebetweenlines{\upperrightpoint}{\upperleftpoint}{\upperrightpoint}{\lowerrightpoint}% + \pgfmathmultiply@{\pgfmathresult}{.5}% + \pgfmathtan@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\outersep\relax% + }% + \pgfextract@process\lowerrightmiter{% + \pgfmathanglebetweenlines{\lowerrightpoint}{\upperrightpoint}{\lowerrightpoint}{\lowerleftpoint}% + \pgfmathmultiply@{\pgfmathresult}{.5}% + \pgfmathtan@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y-\outersep\relax% + }% + % + % Now calculate the corners for determining anchor border + % points, by adding the adjustment for the miter length. + % + \pgfextract@process\lowerleftborderpoint{% + \pgfpointadd{\lowerleftpoint}{\lowerleftmiter}% + }% + \pgfextract@process\upperleftborderpoint{% + \pgfpointadd{\upperleftpoint}{\upperleftmiter}% + }% + \pgfextract@process\upperrightborderpoint{% + \pgfpointadd{\upperrightpoint}{\upperrightmiter}% + }% + \pgfextract@process\lowerrightborderpoint{% + \pgfpointadd{\lowerrightpoint}{\lowerrightmiter}% + }% + % + % Calulate the angle from the centerpoint to each corner. + % Rotation is not important here (see \anchorborder code). + % + \pgfmathanglebetweenpoints{\centerpoint}{\lowerleftborderpoint}% + \let\angletolowerleft\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\upperleftborderpoint}% + \let\angletoupperleft\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\upperrightborderpoint}% + \let\angletoupperright\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\lowerrightborderpoint}% + \let\angletolowerright\pgfmathresult% + % + % Do the same for the *inversely rotated* base point... + % + \pgfextract@process\rotatedbasepoint{% + \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lowerleftborderpoint}% + \let\baseangletolowerleft\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\upperleftborderpoint}% + \let\baseangletoupperleft\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\upperrightborderpoint}% + \let\baseangletoupperright\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lowerrightborderpoint}% + \let\baseangletolowerright\pgfmathresult% + % + % And the *inversely rotated* mid point... + % + \pgfextract@process\rotatedmidpoint{% + \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lowerleftborderpoint}% + \let\midangletolowerleft\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\upperleftborderpoint}% + \let\midangletoupperleft\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\upperrightborderpoint}% + \let\midangletoupperright\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lowerrightborderpoint}% + \let\midangletolowerright\pgfmathresult% + % + % Now rotate the border points around the centerpoint... + % + \pgfextract@process\lowerleftborderpoint{% + \pgfmathrotatepointaround% + {\lowerleftborderpoint}% + {\centerpoint}% + {\rotate}% + }% + \pgfextract@process\upperleftborderpoint{% + \pgfmathrotatepointaround% + {\upperleftborderpoint}% + {\centerpoint}% + {\rotate}% + }% + \pgfextract@process\upperrightborderpoint{% + \pgfmathrotatepointaround% + {\upperrightborderpoint}% + {\centerpoint}% + {\rotate}% + }% + \pgfextract@process\lowerrightborderpoint{% + \pgfmathrotatepointaround% + {\lowerrightborderpoint}% + {\centerpoint}% + {\rotate}% + }% + % + % ...and the points for drawing the border (i.e. no outer sep). + % + \pgfextract@process\lowerleftpoint{% + \pgfmathrotatepointaround{\lowerleftpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\upperleftpoint{% + \pgfmathrotatepointaround{\upperleftpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\upperrightpoint{% + \pgfmathrotatepointaround{\upperrightpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\lowerrightpoint{% + \pgfmathrotatepointaround{\lowerrightpoint}{\centerpoint}{\rotate}% + }% + % + % And finally, save all the relevant stuff. + % + \addtosavedmacro{\lowerleftpoint}% + \addtosavedmacro{\upperleftpoint}% + \addtosavedmacro{\upperrightpoint}% + \addtosavedmacro{\lowerrightpoint}% + % + \addtosavedmacro{\lowerleftborderpoint}% + \addtosavedmacro{\upperleftborderpoint}% + \addtosavedmacro{\upperrightborderpoint}% + \addtosavedmacro{\lowerrightborderpoint}% + % + \addtosavedmacro{\angletolowerleft}% + \addtosavedmacro{\angletoupperleft}% + \addtosavedmacro{\angletoupperright}% + \addtosavedmacro{\angletolowerright}% + % + \addtosavedmacro{\baseangletolowerleft}% + \addtosavedmacro{\baseangletoupperleft}% + \addtosavedmacro{\baseangletoupperright}% + \addtosavedmacro{\baseangletolowerright}% + % + \addtosavedmacro{\midangletolowerleft}% + \addtosavedmacro{\midangletoupperleft}% + \addtosavedmacro{\midangletoupperright}% + \addtosavedmacro{\midangletolowerright}% + % + \addtosavedmacro{\rotate}% + \addtosavedmacro{\externalradius}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint}% + \anchor{base}{\basepoint}% + \anchor{base east}{% + \installtrapeziumparameters% + \let\pgf@trapeziumanchorborderreferencepoint\basepoint% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{base west}{% + \installtrapeziumparameters% + \let\pgf@trapeziumanchorborderreferencepoint\basepoint% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{mid}{\midpoint}% + \anchor{mid east}{% + \installtrapeziumparameters% + \let\pgf@trapeziumanchorborderreferencepoint\midpoint% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{mid west}{% + \installtrapeziumparameters% + \let\pgf@trapeziumanchorborderreferencepoint\midpoint% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{north}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% + } + \anchor{south}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% + } + \anchor{east}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{west}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{north east}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% + } + \anchor{south west}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% + } + \anchor{south east}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% + } + \anchor{north west}{% + \installtrapeziumparameters% + \csname pgf@anchor@trapezium@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% + } + \anchor{bottom left corner}{% + \installtrapeziumparameters% + \lowerleftborderpoint% + }% + \anchor{top left corner}{% + \installtrapeziumparameters% + \upperleftborderpoint% + }% + \anchor{top right corner}{% + \installtrapeziumparameters% + \upperrightborderpoint% + }% + \anchor{bottom right corner}{% + \installtrapeziumparameters% + \lowerrightborderpoint% + }% + \anchor{left side}{% + \installtrapeziumparameters% + \pgfpointlineattime{0.5}{\lowerleftborderpoint}{\upperleftborderpoint}% + }% + \anchor{right side}{% + \installtrapeziumparameters% + \pgfpointlineattime{0.5}{\lowerrightborderpoint}{\upperrightborderpoint}% + }% + \anchor{top side}{% + \installtrapeziumparameters% + \pgfpointlineattime{0.5}{\upperleftborderpoint}{\upperrightborderpoint}% + }% + \anchor{bottom side}{% + \installtrapeziumparameters% + \pgfpointlineattime{0.5}{\lowerleftborderpoint}{\lowerrightborderpoint}% + }% + \backgroundpath{% + \installtrapeziumparameters% + \pgfpathmoveto{\lowerleftpoint}% + \pgfpathlineto{\upperleftpoint}% + \pgfpathlineto{\upperrightpoint}% + \pgfpathlineto{\lowerrightpoint}% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % This allows anchors base east, base west, mid east and mid west, + % to redefine the `center' of the node to correctly calculate the + % border points. + % + \pgfutil@ifundefined{pgf@trapeziumanchorborderreferencepoint}% + {\let\referencepoint\centerpoint}% + {\let\referencepoint\pgf@trapeziumanchorborderreferencepoint}% + % + % Adjust the location of the external + % point relative to the reference point. + % + \referencepoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Install the required points and angles. + % + \installtrapeziumparameters% + % + % Get the angle of the external point to the \referencepoint. + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + % + % *Subtract* the rotation from the external angle. This is + % why the border point angles do not neeed to be rotated. + % + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + % + % Get the relevant angles for the reference point. + % + \let\externalangle\pgfmathresult% + \ifx\referencepoint\basepoint% + \let\angletoupperright\baseangletoupperright% + \let\angletoupperleft\baseangletoupperleft% + \let\angletolowerright\baseangletolowerright% + \let\angletolowerleft\baseangletolowerleft% + \else% + \ifx\referencepoint\midpoint% + \let\angletoupperright\midangletoupperright% + \let\angletoupperleft\midangletoupperleft% + \let\angletolowerright\midangletolowerright% + \let\angletolowerleft\midangletolowerleft% + \fi\fi% + % + % Find the line on the border... + % + \ifdim\externalangle pt<\angletoupperright pt\relax% + \let\firstpoint\upperrightborderpoint% + \let\secondpoint\lowerrightborderpoint% + \else% + \ifdim\externalangle pt<\angletoupperleft pt\relax% + \let\firstpoint\upperleftborderpoint% + \let\secondpoint\upperrightborderpoint% + \else% + \ifdim\externalangle pt<\angletolowerleft pt\relax% + \let\firstpoint\upperleftborderpoint% + \let\secondpoint\lowerleftborderpoint% + \else% + \ifdim\externalangle pt<\angletolowerright pt\relax% + \let\firstpoint\lowerleftborderpoint% + \let\secondpoint\lowerrightborderpoint% + \else% + \let\firstpoint\upperrightborderpoint% + \let\secondpoint\lowerrightborderpoint% + \fi% + \fi% + \fi% + \fi% + % + % ...and thus the point on the border. + % + \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + }% +} + + + + +% Shape semicircle. +% +\pgfdeclareshape{semicircle}{ + \savedmacro\installsemicircleparameters{% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x+.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y+.5\ht\pgfnodeparttextbox% + \advance\pgf@y+.5\dp\pgfnodeparttextbox% + % + % Use the radius of the incircle if required... + % + \ifpgfshapeborderusesincircle% + % + % Get the rotation (no rounding). + % + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + \edef\halfheight{\the\pgf@x}% + \advance\pgf@x\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % Calculate the width and height of the node + % contents, according to any border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + \advance\pgf@y\pgf@y% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgf@x\pgfmathresult pt\relax% + \pgf@y.5\pgf@y% + \edef\halfheight{\the\pgf@y}% + \fi% + \edef\defaultradius{\the\pgf@x}% + % + % Take into account minimum height and width. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<\pgf@ya% + \pgf@x\pgf@ya% + \fi% + \edef\semicircleradius{\the\pgf@x}% + % + % Find the center/base/mid of the semi circle node. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y+-.5\dp\pgfnodeparttextbox% + }% + \pgfextract@process\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \pgfextract@process\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \pgfextract@process\semicirclecenterpoint{% + \centerpoint% + \pgf@ya\semicircleradius\relax% + \advance\pgf@ya-\defaultradius\relax% + % + % The point is adjusted to make the node contents + % appear more centered if the node is enlarged to + % some minimum size. The factor .4 just seems OK. + % + \pgf@ya.4\pgf@ya% + \advance\pgf@y-\pgf@ya% + \pgf@ya\halfheight\relax% + \advance\pgf@y-\pgf@ya% + }% + % + % Add the outer sep to the radius here. + % + \pgf@x\semicircleradius\relax% + \advance\pgf@x\outersep\relax% + \edef\semicircleradius{\the\pgf@x}% + \pgfpointdiff{\centerpoint}{\semicirclecenterpoint}% + \ifdim\pgf@y<0pt\pgf@y-\pgf@y\fi% + \edef\centerpointdiff{\the\pgf@y}% + % + % Calculate the start and end points on the border. + % + \pgfextract@process\arcstartborder{% + \semicirclecenterpoint% + \advance\pgf@x\semicircleradius\relax% + }% + \pgfextract@process\arcendborder{% + \semicirclecenterpoint% + \advance\pgf@x-\semicircleradius\relax% + }% + % + % Calculate the start and end *corner* points on the border. + % This is needed to accommodate the outer sep. + % + \pgfextract@process\arcstartcorner{% + \arcstartborder% + \advance\pgf@y-\outersep\relax% + }% + \pgfextract@process\arcendcorner{% + \arcendborder% + \advance\pgf@y-\outersep\relax% + } + % + % Now calculate all the relevant angles. + % + % For the center point. + % + \pgfmathanglebetweenpoints{\centerpoint}{\arcstartborder}% + \let\angletoarcstartborder\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcendborder}% + \let\angletoarcendborder\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcstartcorner}% + \let\angletoarcstartcorner\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcendcorner}% + \let\angletoarcendcorner\pgfmathresult% + % + % For the basepoint (rotated about the center point). + % + \pgfextract@process\rotatedbasepoint{% + \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcstartborder}% + \let\baseangletoarcstartborder\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcendborder}% + \let\baseangletoarcendborder\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcstartcorner}% + \let\baseangletoarcstartcorner\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\arcendcorner}% + \let\baseangletoarcendcorner\pgfmathresult% + % + % For the midpoint (rotated about the center point). + % + \pgfextract@process\rotatedmidpoint{% + \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcstartborder}% + \let\midangletoarcstartborder\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcendborder}% + \let\midangletoarcendborder\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcstartcorner}% + \let\midangletoarcstartcorner\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\arcendcorner}% + \let\midangletoarcendcorner\pgfmathresult% + % + % Now, rotate the semicircle points around the centerpoint. + % + \pgfextract@process\semicirclecenterpoint{% + \pgfmathrotatepointaround{\semicirclecenterpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcstartborder{% + \pgfmathrotatepointaround{\arcstartborder}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcendborder{% + \pgfmathrotatepointaround{\arcendborder}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcstartcorner{% + \pgfmathrotatepointaround{\arcstartcorner}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcendcorner{% + \pgfmathrotatepointaround{\arcendcorner}{\centerpoint}{\rotate}% + }% + % + % Calculate the distance between the base point and the (rotated) semicircle center. + % + \pgfpointdiff{\basepoint}{\semicirclecenterpoint}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \edef\basesemicirclecenterdiff{\pgfmathresult pt}% + % + % Calculate the distance between the base point and the (rotated) semicircle center. + % + \pgfpointdiff{\midpoint}{\semicirclecenterpoint}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \edef\midsemicirclecenterdiff{\pgfmathresult pt}% + % + % And save all the stuff. + % + \addtosavedmacro{\rotate}% + \addtosavedmacro{\outersep}% + \addtosavedmacro{\semicircleradius}% + % + \addtosavedmacro{\arcstartborder}% + \addtosavedmacro{\arcendborder}% + \addtosavedmacro{\arcstartcorner}% + \addtosavedmacro{\arcendcorner}% + \addtosavedmacro{\semicirclecenterpoint}% + % + \addtosavedmacro{\angletoarcstartborder}% + \addtosavedmacro{\angletoarcendborder}% + \addtosavedmacro{\angletoarcstartcorner}% + \addtosavedmacro{\angletoarcendcorner}% + % + \addtosavedmacro{\centerpointdiff}% + \addtosavedmacro{\basesemicirclecenterdiff}% + \addtosavedmacro{\midsemicirclecenterdiff}% + % + \addtosavedmacro{\baseangletoarcstartborder}% + \addtosavedmacro{\baseangletoarcendborder}% + \addtosavedmacro{\baseangletoarcstartcorner}% + \addtosavedmacro{\baseangletoarcendcorner}% + % + \addtosavedmacro{\midangletoarcstartborder}% + \addtosavedmacro{\midangletoarcendborder}% + \addtosavedmacro{\midangletoarcstartcorner}% + \addtosavedmacro{\midangletoarcendcorner}% + } + \savedanchor{\centerpoint}{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{-.5\dp\pgfnodeparttextbox}% + } + \savedanchor{\basepoint}{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgf@y0pt\relax% + } + \savedanchor{\midpoint}{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5ex}% + } + \anchor{center}{\centerpoint} + \anchor{base}{\basepoint} + \anchor{base west}{% + \installsemicircleparameters% + \let\pgf@semicirclereferencepoint\basepoint% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{-\semicircleradius}{0pt}}% + } + \anchor{base east}{% + \installsemicircleparameters% + \let\pgf@semicirclereferencepoint\basepoint% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{\semicircleradius}{0pt}}% + } + \anchor{mid}{\midpoint} + \anchor{mid west}{% + \installsemicircleparameters% + \let\pgf@semicirclereferencepoint\midpoint% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{-\semicircleradius}{0pt}}% + } + \anchor{mid east}{% + \installsemicircleparameters% + \let\pgf@semicirclereferencepoint\midpoint% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpoint{\semicircleradius}{0pt}}% + } + \anchor{apex}{% + \installsemicircleparameters% + \pgfmathadd@{\rotate}{90}% + \let\angle\pgfmathresult% + \pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\angle}{\semicircleradius}}% + } + \anchor{arc start}{% + \installsemicircleparameters% + \arcstartcorner% + } + \anchor{arc end}{% + \installsemicircleparameters% + \arcendcorner% + } + \anchor{chord center}{% + \installsemicircleparameters% + \pgfpointlineattime{0.5}{\arcstartcorner}{\arcendcorner}% + } + \anchor{north}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{90}{\semicircleradius}}% + } + \anchor{south}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{270}{\semicircleradius}}% + } + \anchor{east}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{0}{\semicircleradius}}% + } + \anchor{west}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{180}{\semicircleradius}}% + } + \anchor{north west}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{135}{\semicircleradius}}% + } + \anchor{south west}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{225}{\semicircleradius}}% + } + \anchor{north east}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{45}{\semicircleradius}}% + } + \anchor{south east}{% + \installsemicircleparameters% + \csname pgf@anchor@semicircle@border\endcsname{\pgfqpointpolar{315}{\semicircleradius}}% + } + \backgroundpath{% + \installsemicircleparameters% + \pgf@x\semicircleradius\relax% + \advance\pgf@x-\outersep\relax% + \edef\semicircleradius{\the\pgf@x}% + \pgfpathmoveto{\pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\rotate}{\semicircleradius}}}% + {% + \pgftransformrotate{\rotate}% + \pgfpatharc{0}{180}{\semicircleradius}% + \pgfpathclose% + }% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Check if a reference point has been defined (i.e. \midpoint or \basepoint). + % + \pgfutil@ifundefined{pgf@semicirclereferencepoint}% + {\let\referencepoint\centerpoint}% + {\let\referencepoint\pgf@semicirclereferencepoint}% + % + % Adjust the location of the external point relative to the reference point. + % + \referencepoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Install the required points and angles. + % + \installsemicircleparameters% + % + % Get the angle of the external point to the \referencepoint. + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + \let\externalangle\pgfmathresult% + % + % *Subtract* the rotation from the external angle. + % + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\angle\pgfmathresult% + \ifx\referencepoint\basepoint% + \let\angletoarcstartborder\baseangletoarcstartborder% + \let\angletoarcendborder\baseangletoarcendborder% + \let\angletoarcstartcorner\baseangletoarcstartcorner% + \let\angletoarcendcorner\baseangletoarcendcorner% + \let\centerpointdiff\basesemicirclecenterdiff% + \else% + \ifx\referencepoint\midpoint% + \let\angletoarcstartborder\midangletoarcstartborder% + \let\angletoarcendborder\midangletoarcendborder% + \let\angletoarcstartcorner\midangletoarcstartcorner% + \let\angletoarcendcorner\midangletoarcendcorner% + \let\centerpointdiff\midsemicirclecenterdiff% + \fi\fi% + % + % Determine if the line will cross the semicircle arc, or the chord. + % + \ifdim\angle pt>\angletoarcstartborder pt\relax% + \let\firstpoint\pgfutil@empty% + \let\secondpoint\pgfutil@empty% + \else% + \ifdim\angle pt>\angletoarcstartcorner pt\relax% + \let\firstpoint\arcstartcorner% + \let\secondpoint\arcstartborder% + \else% + \ifdim\angle pt>\angletoarcendcorner pt\relax% + \let\firstpoint\arcendcorner% + \let\secondpoint\arcstartcorner% + \else% + \ifdim\angle pt>\angletoarcendborder pt\relax% + \let\firstpoint\arcendborder% + \let\secondpoint\arcendcorner% + \else% + \let\firstpoint\pgfutil@empty% + \let\secondpoint\pgfutil@empty% + \fi% + \fi% + \fi% + \fi% + \ifx\firstpoint\pgfutil@empty + % + % Calculate the angle from the centre of the semicircle to the + % point on the semicircle arc which intersects the line from + % the external point to the reference point... + % + \pgfmathanglebetweenlines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + {\semicirclecenterpoint}{\referencepoint}% + \pgfmathsin@{\pgfmathresult}% + \let\sineangle\pgfmathresult% + \pgf@x\semicircleradius\relax% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}% + \let\reciprocalradius\pgfmathresult% + \pgf@x\centerpointdiff\relax% + \pgf@x\sineangle\pgf@x% + \pgf@x\reciprocalradius\pgf@x% + \pgfmathasin@{\pgfmath@tonumber{\pgf@x}}% + \pgf@x\pgfmathresult pt\relax% + \advance\pgf@x\externalangle pt\relax% + \edef\angle{\pgfmath@tonumber{\pgf@x}}% + % + % ...and thus the point on the border. + % + \pgfpointadd{\semicirclecenterpoint}{\pgfqpointpolar{\angle}{\semicircleradius}}% + \else% + % + % Calculate the the point where the semicircle chord intersects + % the line from the external point to the reference point. + % + \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + \fi% + } +} + + +% Keys for shape isosceles triangle +% +% /pgf/isosceles triangle apex angle : angle at the apex of the triangle. +\pgfkeys{/pgf/.cd, + isosceles triangle apex angle/.initial=45, + isosceles triangle stretches/.is if=pgf@lib@sh@isosceslestrianglestretches +} +\newif\ifpgf@lib@sh@isosceslestrianglestretches + +\pgfdeclareshape{isosceles triangle}{ + \savedmacro\trianglepoints{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/isosceles triangle apex angle}}% + \divide\pgf@x2\relax% + \edef\halfapexangle{\pgfmath@tonumber{\pgf@x}}% + \addtosavedmacro\halfapexangle% + % + \pgfmathtan@{\halfapexangle}% + \let\tanhalfapexangle\pgfmathresult% + % + \pgfmathcot@{\halfapexangle}% + \let\cothalfapexangle\pgfmathresult% + % + \pgfmathsin@{\halfapexangle}% + \let\sinhalfapexangle\pgfmathresult% + % + \pgfmathreciprocal@{\pgfmathresult}% + \let\cosechalfapexangle\pgfmathresult% + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + \ifpgfshapeborderusesincircle% + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \else% + \pgf@y\pgf@x% + \fi% + \pgf@x1.414213\pgf@x% + \pgf@y1.414213\pgf@y% + % + \pgf@xa\pgf@x% + \advance\pgf@xa\cosechalfapexangle\pgf@x% + \pgf@ya\tanhalfapexangle\pgf@xa% + \else% + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \pgfmathsetcount\c@pgf@counta{+\pgfmathresult}% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \edef\rotate{\the\c@pgf@counta}% + \ifnum\c@pgf@counta=90\relax% + \pgf@xa\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xa% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xa\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xa% + \fi% + \fi% + % + \pgf@xa2.0\pgf@x% + \pgf@ya\tanhalfapexangle\pgf@xa% + \advance\pgf@xa\cothalfapexangle\pgf@y% + \advance\pgf@ya\pgf@y% + \fi% + \addtosavedmacro\rotate% + \ifdim\pgf@xa=0pt\relax% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum height}}% + \fi% + % Adjust for minimum height and width. + % + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@ya<.5\pgf@yb% + \ifpgf@lib@sh@isosceslestrianglestretches% + \pgf@ya.5\pgf@yb% + % + \pgfmathdivide@{\pgfmath@tonumber{\pgf@ya}}{\pgfmath@tonumber{\pgf@xa}}% + \pgfmathatan@{\pgfmathresult}% + \let\halfapexangle\pgfmathresult% + % + \else% + \pgf@ya.5\pgf@yb% + \pgf@xa\cothalfapexangle\pgf@ya% + \fi% + \fi% + % + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@xa<\pgf@xb% + \ifpgf@lib@sh@isosceslestrianglestretches% + \pgf@xa\pgf@xb% + % + \pgfmathdivide@{\pgfmath@tonumber{\pgf@ya}}{\pgfmath@tonumber{\pgf@xa}}% + \pgfmathatan@{\pgfmathresult}% + \let\halfapexangle\pgfmathresult% + % + \else% + \pgf@xa\pgf@xb% + \pgf@ya\tanhalfapexangle\pgf@xa% + \fi% + \fi% + % + % + % Now find the ``offset height'' (h'). This is the distance from the + % center of the node contents to the base of the triangle. + % + \ifpgfshapeborderusesincircle% + % + % h' = H*sin(a/2) / (1+sin(a/2)) + % + % where: + % H = the height of the triangle. + % a = the apex angle. + % + \pgf@xc\pgf@xa% + \pgfmathsin@{\halfapexangle}% + \pgf@xc\pgfmathresult\pgf@xc% + \pgf@yc1pt\relax% + \advance\pgf@yc\pgfmathresult pt\relax% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@xc}}{\pgfmath@tonumber{\pgf@yc}} + \pgfutil@tempdima\pgfmathresult pt\relax% + \else% + % + % h' = 0.5*h + (0.5*(W-w)*cos(a/2) - h*sin(a/2))/(1+sin(a/2)) + % + % where: + % h = the height of the node contents. + % w = the width of the node contents. + % W = the width of the triangle. + % a = the apex angle. + % + \pgf@xc\pgf@ya% + \advance\pgf@xc-\pgf@y% + \pgfmathcos@{\halfapexangle}% + \pgf@xc\pgfmathresult\pgf@xc% + \pgfmathsin@{\halfapexangle}% + \advance\pgf@xc-\pgfmathresult\pgf@x% + \advance\pgf@xc-\pgfmathresult\pgf@x% + \pgf@yc\pgfmathresult pt\relax% + \advance\pgf@yc1pt\relax% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@xc}}{\pgfmath@tonumber{\pgf@yc}}% + \pgfutil@tempdima\pgfmathresult pt\relax% + \advance\pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\apex{% + \pgf@y0pt% + \pgf@x\pgf@xa% + \advance\pgf@x-\pgfutil@tempdima% + }% + \addtosavedmacro\apex% + % + \pgfextract@process\lowerleft{% + \pgf@y\pgf@ya% + \pgf@x-\pgfutil@tempdima% + }% + \addtosavedmacro\lowerleft% + % + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xb<\pgf@yb% + \pgf@xb\pgf@yb% + \fi% + \pgfextract@process\apexanchor{% + \apex% + \advance\pgf@x\cosechalfapexangle\pgf@xb% + }% + \addtosavedmacro\apexanchor% + % + \pgf@yc-\halfapexangle pt\relax% + \advance\pgf@yc90pt\relax% + \divide\pgf@yc2\relax% + \pgfmathcot@{\pgfmath@tonumber{\pgf@yc}}% + \pgfextract@process\lowerleftanchor{% + \lowerleft% + \advance\pgf@y\pgfmathresult\pgf@xb% + \advance\pgf@x-\pgf@xb% + }% + \addtosavedmacro\lowerleftanchor% + % + \pgfextract@process\lowerrightanchor{% + \lowerleftanchor% + \pgf@y-\pgf@y% + }% + \addtosavedmacro\lowerrightanchor% + } + \anchor{apex}{% + \trianglepoints% + \pgfpointadd{\centerpoint}{% + \pgfmathrotatepointaround{\apexanchor}{\pgfpointorigin}{\rotate}% + }% + }% + \anchor{left corner}{% + \trianglepoints% + \pgfpointadd{\centerpoint}{% + \pgfmathrotatepointaround{\lowerleftanchor}{\pgfpointorigin}{\rotate}% + }% + }% + \anchor{right corner}{% + \trianglepoints% + \pgfpointadd{\centerpoint}{% + \pgfmathrotatepointaround{\lowerrightanchor}{\pgfpointorigin}{\rotate}% + }% + }% + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + }% + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint}% + \anchor{mid west}{% + \trianglepoints% + \let\pgf@isoscelestriangle@referencepoint\midpoint% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}% + }% + \anchor{mid east}{% + \trianglepoints% + \let\pgf@isoscelestriangle@referencepoint\midpoint% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}% + }% + \anchor{base}{\basepoint}% + \anchor{base west}{% + \trianglepoints% + \let\pgf@isoscelestriangle@referencepoint\basepoint% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}% + }% + \anchor{base east}{% + \trianglepoints% + \let\pgf@isoscelestriangle@referencepoint\basepoint% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}% + }% + \anchor{north}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{0pt}{1pt}}% + } + \anchor{south}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{0pt}{-1pt}}% + } + \anchor{east}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{0pt}}% + } + \anchor{west}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{0pt}}% + } + \anchor{north east}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{1pt}}% + } + \anchor{south west}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{-1pt}}% + } + \anchor{south east}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{1pt}{-1pt}}% + } + \anchor{north west}{% + \trianglepoints% + \csname pgf@anchor@isosceles triangle@border\endcsname{\pgfqpoint{-1pt}{1pt}}% + } + \anchor{left side}{% + \trianglepoints% + \pgfmathrotatepointaround{% + \pgfpointadd{\pgfpointlineattime{0.5}{\lowerleftanchor}{\apexanchor}}{\centerpoint}}% + {\centerpoint}{\rotate}% + } + \anchor{right side}{% + \trianglepoints% + \pgfmathrotatepointaround{% + \pgfpointadd{\pgfpointlineattime{0.5}{\lowerrightanchor}{\apexanchor}}{\centerpoint}}% + {\centerpoint}{\rotate}% + } + \anchor{lower side}{% + \trianglepoints% + \pgfmathrotatepointaround{% + \pgfpointadd{\pgfpointlineattime{0.5}{\lowerleftanchor}{\lowerrightanchor}}{\centerpoint}}% + {\centerpoint}{\rotate}% + } + \backgroundpath{% + \trianglepoints% + {% + \pgftransformshift{\centerpoint}% + \pgftransformrotate{\rotate}% + \pgfpathmoveto{\apex}% + \pgfpathlineto{\lowerleft}% + \pgfpathlineto{\lowerleft\pgf@y-\pgf@y}% + \pgfpathclose% + }% + } + \anchorborder{% + \pgfutil@ifundefined{pgf@isoscelestriangle@referencepoint}{\let\referencepoint\centerpoint}% + {\let\referencepoint\pgf@isoscelestriangle@referencepoint}% + \pgfextract@process\externalpoint{% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \referencepoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \trianglepoints% + \pgfmathanglebetweenpoints{\referencepoint}{\externalpoint}% + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \pgfmathmod@{\pgfmathresult}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\lowerrightanchor}}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\lowerleftanchor}}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\centerpoint}{\apexanchor}}% + \ifdim\externalangle pt>\pgfmathresult pt\relax% + \let\firstpoint\apexanchor% + \let\secondpoint\lowerleftanchor% + \else% + \let\firstpoint\apexanchor% + \let\secondpoint\lowerrightanchor% + \fi% + \else% + \let\firstpoint\lowerleftanchor% + \let\secondpoint\lowerrightanchor% + \fi% + \else% + \let\firstpoint\lowerrightanchor% + \let\secondpoint\apexanchor% + \fi% + \pgfpointintersectionoflines{\referencepoint}{\externalpoint}% + {\pgfmathrotatepointaround{\pgfpointadd{\centerpoint}{\firstpoint}}{\centerpoint}{\rotate}}% + {\pgfmathrotatepointaround{\pgfpointadd{\centerpoint}{\secondpoint}}{\centerpoint}{\rotate}}% + }% +} + + + + +% Keys for shape kite +% +% +\pgfkeys{/pgf/.cd, + kite upper vertex angle/.initial=120, + kite lower vertex angle/.initial=60, + kite vertex angles/.code={% + \pgfutil@in@{and}{#1}% + \ifpgfutil@in@% + \def\pgf@marshal##1and##2\@@{% + \pgfkeys{/pgf/kite upper vertex angle=##1}% + \pgfkeys{/pgf/kite lower vertex angle=##2}% + }% + \expandafter\pgf@marshal#1\@@% + \else% + \pgfkeys{/pgf/kite upper vertex angle=#1}% + \pgfkeys{/pgf/kite lower vertex angle=#1}% + \fi% + }% +} + +% Shape kite. +% +\pgfdeclareshape{kite}{ + \savedmacro\installkiteparameters{% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Calculate the centre, base and mid points of the node. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \pgfextract@process\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \pgfextract@process\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + % + % Halve the vertex angles. + % + \pgfmathdivide{\pgfkeysvalueof{/pgf/kite upper vertex angle}}{2}% + \let\halfuppervertexangle\pgfmathresult% + \pgfmathdivide{\pgfkeysvalueof{/pgf/kite lower vertex angle}}{2}% + \let\halflowervertexangle\pgfmathresult% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \ifpgfshapeborderusesincircle% + % + % Get the rotation. + % + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + % + % Get the radis of the incircle. + % + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + % + % Get the distances from the upper and lower verticies + % to the center of the incircle. + % + \pgfmathsin@{\halfuppervertexangle}% + \let\sinehalfuppervertexangle\pgfmathresult% + \pgfmathreciprocal@{\pgfmathresult}% + \let\cosechalfuppervertexangle\pgfmathresult% + \pgf@ya\pgfmathresult\pgf@x% + \pgfmathsin@{\halflowervertexangle}% + \let\sinehalflowervertexangle\pgfmathresult% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@yb\pgfmathresult\pgf@x% + % + % Now calculate vertical offset (yc) between the center of + % the incircle, and the intersection of the kite diagonals. + % + % yc = x * cosec(a/2) - x * cot(a/2) * (sin(a/2) + sin(b/2)) * cosec(a/2 + b/2) + % + % where: + % x = the incircle radius. + % a = the upper vertex angle. + % b = the lower vertex angle. + % + \pgf@yc\pgf@x% + \pgfmathadd@{\halfuppervertexangle}{\halflowervertexangle}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@yc\pgfmathresult\pgf@yc% + \pgfmathadd@{\sinehalfuppervertexangle}{\sinehalflowervertexangle}% + \pgf@yc\pgfmathresult\pgf@yc% + \pgfmathcos@{\halfuppervertexangle}% + \pgf@yc\pgfmathresult\pgf@yc% + \pgf@yc-\cosechalfuppervertexangle\pgf@yc% + \advance\pgf@yc\cosechalfuppervertexangle\pgf@x% + \edef\deltay{\the\pgf@yc}% + % + % Now calculate the height of the kite... + % + \advance\pgf@ya-\pgf@yc% + % + % ...and the depth. + % + \advance\pgf@yb\pgf@yc% + % + % Get the half width of the widest part of the kite. + % + \pgfmathtan@{\halfuppervertexangle}% + \pgf@xa\pgfmathresult\pgf@ya% + \else% + \multiply\pgf@x2\relax% + \multiply\pgf@y2\relax% + % + % Get the rotation (with rounding). + % + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % Calculate the width and height of the node + % contents, according to any border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + % + % The node contents (total height y) extends a distance ya into the + % upper isosceles triangle of the kite and a distance yb into the + % lower isosceles triangle. Thus, the following relationships hold: + % + % ya/yb = tan(b/2)/tan(a/2) + % + % and y = ya + yb + % + % so ya = y * sin(a/2 + b/2) / (cos(a/2) * sin(b/2)) + % + % where: + % a = upper vertex angle. + % b = lower vertex angle. + % + \pgfmathadd@{\halfuppervertexangle}{\halflowervertexangle}% + \pgfmathsin@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@ya\pgfmathresult\pgf@y% + \pgfmathcos@{\halfuppervertexangle}% + \pgf@ya\pgfmathresult\pgf@ya% + \pgfmathsin@{\halflowervertexangle}% + \pgf@ya\pgfmathresult\pgf@ya% + \pgf@yb\pgf@y% + \advance\pgf@yb-\pgf@ya% + % + % The vertical offset between the center of the node, and + % the intersection of the kite diagonals is given by: + % + % yc = y/2 - ya + % + \pgf@yc.5\pgf@y% + \advance\pgf@yc-\pgf@ya% + \edef\deltay{\the\pgf@yc}% + % + % Get the half width of the widest part of the kite. + % + \pgfmathtan@{\halfuppervertexangle}% + \pgf@xa.5\pgf@x% + \advance\pgf@xa\pgfmathresult\pgf@ya% + % + % Now calculate the height of the kite... + % + \pgf@xb.5\pgf@x% + \pgfmathreciprocal@{\pgfmathresult}% + \advance\pgf@ya\pgfmathresult\pgf@xb% + % + % ...and the depth. + % + \pgfmathtan@{\halflowervertexangle}% + \pgfmathreciprocal@{\pgfmathresult}% + \advance\pgf@yb\pgfmathresult\pgf@xb% + \fi% + % + % Take into account minimum height and width. + % + % ya is the kite height. + % yb is the kite depth. + % xa is the kite (half) width. + % + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/minimum height}}% + \pgf@y\pgf@ya% + \advance\pgf@y\pgf@yb% + \ifdim\pgf@y<\pgf@yc% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}% + \pgf@yc\pgfmathresult\pgf@yc% + \pgf@xa\pgfmath@tonumber{\pgf@yc}\pgf@xa% + \pgf@ya\pgfmath@tonumber{\pgf@yc}\pgf@ya% + \pgf@yb\pgfmath@tonumber{\pgf@yc}\pgf@yb% + \fi% + \pgf@x2.0\pgf@xa% + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@x<\pgf@xc% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}% + \pgf@xc\pgfmathresult\pgf@xc% + \pgf@xa\pgfmath@tonumber{\pgf@xc}\pgf@xa% + \pgf@ya\pgfmath@tonumber{\pgf@xc}\pgf@ya% + \pgf@yb\pgfmath@tonumber{\pgf@xc}\pgf@yb% + \fi% + \edef\kitehalfwidth{\the\pgf@xa}% + \edef\kiteheight{\the\pgf@ya}% + \edef\kitedepth{\the\pgf@yb}% + % + % Calculate the basic points on the kite (for the background path). + % + \pgfextract@process\toppoint{% + \centerpoint% + \advance\pgf@y\deltay\relax% + \advance\pgf@y\kiteheight% + }% + \pgfextract@process\bottompoint{% + \centerpoint% + \advance\pgf@y\deltay\relax% + \advance\pgf@y-\kitedepth% + }% + \pgfextract@process\leftpoint{% + \centerpoint% + \advance\pgf@y\deltay\relax% + \advance\pgf@x-\kitehalfwidth% + }% + \pgfextract@process\rightpoint{% + \centerpoint% + \advance\pgf@y\deltay\relax% + \advance\pgf@x\kitehalfwidth% + }% + % + % Now calculate the miter length. At the top... + % + \pgfmathsin@{\halfuppervertexangle}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@y\outersep\relax% + \pgf@y\pgfmathresult\pgf@y% + \edef\topmiter{\the\pgf@y}% + % + % ...at the bottom... + % + \pgfmathsin@{\halflowervertexangle}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@y\outersep\relax% + \pgf@y\pgfmathresult\pgf@y% + \edef\bottommiter{\the\pgf@y}% + % + % ...to the right... + % + \pgfmathsubtract@{180}{\halflowervertexangle}% + \pgfmathsubtract@{\pgfmathresult}{\halfuppervertexangle}% + \pgfmathdivide@{\pgfmathresult}{2}% + \pgfmathsin@{\pgfmathresult}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@xa\outersep\relax% + \pgf@xa\pgfmathresult\pgf@xa% + \pgfmathsubtract@{\halfuppervertexangle}{\halflowervertexangle}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\angle\pgfmathresult% + \pgfextract@process\rightmiter{% + \pgfqpointpolar{\angle}{\the\pgf@xa}% + }% + % + % ...and to the left. + % + \pgfmathsubtract@{180}{\angle}% + \let\angle\pgfmathresult% + \pgfextract@process\leftmiter{% + \pgfqpointpolar{\angle}{\the\pgf@xa}% + }% + % + % Create the border points. + % + \pgfextract@process\topborderpoint{% + \toppoint% + \advance\pgf@y\topmiter\relax% + }% + \pgfextract@process\bottomborderpoint{% + \bottompoint% + \advance\pgf@y-\bottommiter\relax% + }% + \pgfextract@process\leftborderpoint{% + \leftpoint% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \leftmiter% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfextract@process\rightborderpoint{% + \rightpoint% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \rightmiter% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Get the angle from the \centerpoint to the *unrotated points*. + % + \pgfmathanglebetweenpoints{\centerpoint}{\topborderpoint}% + \let\angletotoppoint\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\leftborderpoint}% + \let\angletoleftpoint\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\bottomborderpoint}% + \let\angletobottompoint\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\rightborderpoint}% + \let\angletorightpoint\pgfmathresult% + % + % ...from the *inversly rotated* \basepoint... + % + \pgfextract@process\rotatedbasepoint{% + \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\topborderpoint}% + \let\baseangletotoppoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\leftborderpoint}% + \let\baseangletoleftpoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\bottomborderpoint}% + \let\baseangletobottompoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\rightborderpoint}% + \let\baseangletorightpoint\pgfmathresult% + % + % ...and from the *inversely rotated* \midpoint. + % + \pgfextract@process\rotatedmidpoint{% + \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\topborderpoint}% + \let\midangletotoppoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\leftborderpoint}% + \let\midangletoleftpoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\bottomborderpoint}% + \let\midangletobottompoint\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\rightborderpoint}% + \let\midangletorightpoint\pgfmathresult% + % + % Calculate a radius guaranteed to be outside the kite. + % + \pgfextractx\pgf@xa{\pgfpointdiff{\leftborderpoint}{\rightborderpoint}}% + \ifdim\pgf@xa<0pt\relax% + \pgf@xa-\pgf@xa% + \fi% + \pgfextracty\pgf@ya{\pgfpointdiff{\topborderpoint}{\bottomborderpoint}}% + \ifdim\pgf@ya<0pt\relax% + \pgf@ya-\pgf@ya% + \fi% + \ifdim\pgf@ya>\pgf@xa% + \edef\externalradius{\the\pgf@ya}% + \else% + \edef\externalradius{\the\pgf@xa}% + \fi% + % + % Now rotate the points... + % + \pgfextract@process\toppoint{% + \pgfmathrotatepointaround{\toppoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\bottompoint{% + \pgfmathrotatepointaround{\bottompoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\leftpoint{% + \pgfmathrotatepointaround{\leftpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\rightpoint{% + \pgfmathrotatepointaround{\rightpoint}{\centerpoint}{\rotate}% + }% + % + % ...and the border points. + % + \pgfextract@process\topborderpoint{% + \pgfmathrotatepointaround{\topborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\bottomborderpoint{% + \pgfmathrotatepointaround{\bottomborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\leftborderpoint{% + \pgfmathrotatepointaround{\leftborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\rightborderpoint{% + \pgfmathrotatepointaround{\rightborderpoint}{\centerpoint}{\rotate}% + }% + % + % Now save it all. + % + \addtosavedmacro{\rotate}% + \addtosavedmacro{\externalradius}% + % + \addtosavedmacro\toppoint% + \addtosavedmacro\bottompoint% + \addtosavedmacro\leftpoint% + \addtosavedmacro\rightpoint% + % + \addtosavedmacro\topborderpoint% + \addtosavedmacro\bottomborderpoint% + \addtosavedmacro\leftborderpoint% + \addtosavedmacro\rightborderpoint% + % + \addtosavedmacro\angletotoppoint% + \addtosavedmacro\angletobottompoint% + \addtosavedmacro\angletoleftpoint% + \addtosavedmacro\angletorightpoint% + % + \addtosavedmacro\baseangletotoppoint% + \addtosavedmacro\baseangletobottompoint% + \addtosavedmacro\baseangletoleftpoint% + \addtosavedmacro\baseangletorightpoint% + % + \addtosavedmacro\midangletotoppoint% + \addtosavedmacro\midangletobottompoint% + \addtosavedmacro\midangletoleftpoint% + \addtosavedmacro\midangletorightpoint% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint}% + \anchor{base}{\basepoint}% + \anchor{base west}{% + \installkiteparameters% + \let\pgf@kiteanchorborderreferencepoint\basepoint% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{base east}{% + \installkiteparameters% + \let\pgf@kiteanchorborderreferencepoint\basepoint% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + }% + \anchor{mid}{\midpoint}% + \anchor{mid west}{% + \installkiteparameters% + \let\pgf@kiteanchorborderreferencepoint\midpoint% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{mid east}{% + \installkiteparameters% + \let\pgf@kiteanchorborderreferencepoint\midpoint% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + }% + \anchor{north}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% + } + \anchor{south}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% + } + \anchor{east}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{west}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{north east}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% + } + \anchor{south west}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% + } + \anchor{south east}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% + } + \anchor{north west}{% + \installkiteparameters% + \csname pgf@anchor@kite@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% + } + \anchor{upper vertex}{% + \installkiteparameters% + \topborderpoint} + \anchor{lower vertex}{% + \installkiteparameters% + \bottomborderpoint} + \anchor{left vertex}{% + \installkiteparameters% + \leftborderpoint} + \anchor{right vertex}{% + \installkiteparameters% + \rightborderpoint} + \anchor{upper left side}{% + \installkiteparameters% + \pgfpointlineattime{0.5}{\topborderpoint}{\leftborderpoint}} + \anchor{lower left side}{% + \installkiteparameters% + \pgfpointlineattime{0.5}{\bottomborderpoint}{\leftborderpoint}} + \anchor{upper right side}{% + \installkiteparameters% + \pgfpointlineattime{0.5}{\topborderpoint}{\rightborderpoint}} + \anchor{lower right side}{% + \installkiteparameters% + \pgfpointlineattime{0.5}{\bottomborderpoint}{\rightborderpoint}} + \backgroundpath{% + \installkiteparameters% + \pgfpathmoveto{\toppoint}% + \pgfpathlineto{\leftpoint}% + \pgfpathlineto{\bottompoint}% + \pgfpathlineto{\rightpoint}% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % This allows anchors base east, base west, mid east and mid west, + % to redefine the `center' of the node to correctly calculate the + % border points. + % + \pgfutil@ifundefined{pgf@kiteanchorborderreferencepoint}% + {\let\referencepoint\centerpoint}% + {\let\referencepoint\pgf@kiteanchorborderreferencepoint}% + % + % Adjust the location of the external + % point relative to the reference point. + % + \referencepoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Install the required points and angles. + % + \installkiteparameters% + % + % Get the angle of the external point relative to \referencepoint. + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + % + % *Subtract* the rotation from the external angle. + % + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + \ifx\referencepoint\basepoint% + \let\angletotoppoint\baseangletotoppoint% + \let\angletobottompoint\baseangletobottompoint% + \let\angletoleftpoint\baseangletoleftpoint% + \let\angletorightpoint\baseangletorightpoint% + \else% + \ifx\referencepoint\midpoint% + \let\angletotoppoint\midangletotoppoint% + \let\angletobottompoint\midangletobottompoint% + \let\angletoleftpoint\midangletoleftpoint% + \let\angletorightpoint\midangletorightpoint% + \fi\fi% + % + % Depending on the rotation, the angle to \rightborderpoint + % may be smaller than the angle to \topborderpoint. + % + \ifdim\angletorightpoint pt<\angletotoppoint pt\relax% + \ifdim\externalangle pt<\angletorightpoint pt\relax% + \let\firstpoint\rightborderpoint% + \let\secondpoint\bottomborderpoint% + \else% + \ifdim\externalangle pt<\angletotoppoint pt\relax% + \let\firstpoint\rightborderpoint% + \let\secondpoint\topborderpoint% + \else% + \ifdim\externalangle pt<\angletoleftpoint pt\relax% + \let\firstpoint\topborderpoint% + \let\secondpoint\leftborderpoint% + \else% + \ifdim\externalangle pt<\angletobottompoint pt\relax% + \let\firstpoint\leftborderpoint% + \let\secondpoint\bottomborderpoint% + \else% + \let\firstpoint\rightborderpoint% + \let\secondpoint\bottomborderpoint% + \fi% + \fi% + \fi% + \fi% + \else% + \ifdim\externalangle pt<\angletotoppoint pt\relax% + \let\firstpoint\rightborderpoint% + \let\secondpoint\topborderpoint% + \else% + \ifdim\externalangle pt<\angletoleftpoint pt\relax% + \let\firstpoint\leftborderpoint% + \let\secondpoint\topborderpoint% + \else% + \ifdim\externalangle pt<\angletobottompoint pt\relax% + \let\firstpoint\bottomborderpoint% + \let\secondpoint\leftborderpoint% + \else% + \ifdim\externalangle pt<\angletorightpoint pt\relax% + \let\firstpoint\rightborderpoint% + \let\secondpoint\bottomborderpoint% + \else% + \let\firstpoint\rightborderpoint% + \let\secondpoint\topborderpoint% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + } +} + + + + +% Keys for shape dart. +% +% + +\pgfkeys{/pgf/.cd, + dart tip angle/.initial=45, + dart tail angle/.initial=135 +} + +% Shape dart. +% +\pgfdeclareshape{dart}{% + \savedmacro\installdartparameters{% + % + % Get the halved angles (more useful). + % + \pgfmathdivide{\pgfkeysvalueof{/pgf/dart tip angle}}{2}% + \let\halftipangle\pgfmathresult% + \pgfmathdivide{\pgfkeysvalueof{/pgf/dart tail angle}}{2}% + \let\halftailangle\pgfmathresult% + % + % Calculate some common results. + % + \pgfmathcot@{\halftipangle}% + \let\cothalftipangle\pgfmathresult% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Calculate the centre, base and mid points of the node. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \pgfextract@process\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \pgfextract@process\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + % + % Get the (halved) dimension of the node. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + % Get the length of the dart tip. + % + \ifpgfshapeborderusesincircle% + % + % Get the (unrounded) rotation. + % + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + % + % Get the radius of the incircle. + % + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + % + % Calculate the length of the dart tip. + % + \pgf@xa\cothalftipangle\pgf@x% + \advance\pgf@xa\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % Flip the width and height of the node contents, + % according to the appropriate border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + % + % Calculate the length of the dart tip. + % + \pgf@xa\cothalftipangle\pgf@y% + \advance\pgf@xa2.0\pgf@x% + \fi% + % + % Get the (half) separation of the dart tails. + % + \pgfmathsubtract@{\halftailangle}{\halftipangle}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@ya\pgfmathresult\pgf@xa% + \pgfmathsin@{\halftipangle}% + \pgf@ya\pgfmathresult\pgf@ya% + \pgfmathcos@{\halftipangle}% + \pgf@ya\pgfmathresult\pgf@ya% + % + % Get the total length of the dart... + % + \pgf@xb\cothalftipangle\pgf@ya% + % + % and hence the length of the tails. + % + \pgf@xc-\pgf@xa% + \advance\pgf@xc\pgf@xb% + % + % Adjust for minimum height (length of the dart). + % + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@xb<\pgf@y% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xb}}% + \pgf@y\pgfmathresult\pgf@y% + \pgf@xa\pgfmath@tonumber{\pgf@y}\pgf@xa% + \pgf@xc\pgfmath@tonumber{\pgf@y}\pgf@xc% + \pgf@ya\pgfmath@tonumber{\pgf@y}\pgf@ya% + \pgf@x\pgfmath@tonumber{\pgf@y}\pgf@x% + \fi% + % + % Adjust for minimum width (tail separation length). + % + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum width}}% + \pgf@y.5\pgf@y% + \ifdim\pgf@ya<\pgf@y% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@ya}}% + \pgf@ya\pgf@y% + \pgf@y\pgfmathresult\pgf@y% + \pgf@xa\pgfmath@tonumber{\pgf@y}\pgf@xa% + \pgf@xc\pgfmath@tonumber{\pgf@y}\pgf@xc% + \pgf@x\pgfmath@tonumber{\pgf@y}\pgf@x% + \fi% + \edef\dartlength{\the\pgf@xa}% + \edef\deltax{\the\pgf@x}% + \edef\taillength{\the\pgf@xc}% + \edef\halftailseparation{\the\pgf@ya} + % + % Create the basic points on the dart (for the backgroundo path). + % + \pgfextract@process\tippoint{% + \centerpoint% + \advance\pgf@x\dartlength\relax% + \advance\pgf@x-\deltax\relax% + }% + \pgfextract@process\tailcenterpoint{% + \centerpoint% + \advance\pgf@x-\deltax\relax% + }% + \pgfextract@process\lefttailpoint{% + \centerpoint% + \advance\pgf@x-\deltax\relax% + \advance\pgf@x-\taillength\relax% + \advance\pgf@y\halftailseparation\relax% + }% + \pgfextract@process\righttailpoint{% + \centerpoint% + \advance\pgf@x-\deltax\relax% + \advance\pgf@x-\taillength\relax% + \advance\pgf@y-\halftailseparation\relax% + }% + % + % Calculate the miter vectors. At the dart tip... + % + \pgfextract@process\tipmiter{% + \pgfmathcosec@{\halftipangle}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y0pt\relax% + }% + % + % ...at the tail center... + % + \pgfextract@process\tailcentermiter{% + \pgfmathcosec@{\halftailangle}% + \pgf@x-\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y0pt\relax% + }% + % + % ...at the left tail... + % + \pgfmathsubtract@{\halftailangle}{\halftipangle}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\angle\pgfmathresult% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \pgfmathadd@{\angle}{90}% + \pgfmathsubtract{\pgfmathresult}{\halftailangle}% + \pgfmathsincos@{\pgfmathresult}% + \pgf@ya\pgfmathresultx\pgf@x% + \pgf@xa\pgfmathresulty\pgf@x% + \pgfextract@process\lefttailmiter{% + \pgf@x-\pgf@xa% + \pgf@y\pgf@ya% + }% + % + % ...and the right tail. + % + \pgfextract@process\righttailmiter{% + \pgf@x-\pgf@xa% + \pgf@y-\pgf@ya% + }% + % + % Create the border points. + % + \pgfextract@process\tipborderpoint{% + \pgfpointadd{\tippoint}{\tipmiter} + }% + \pgfextract@process\tailcenterborderpoint{% + \pgfpointadd{\tailcenterpoint}{\tailcentermiter}% + }% + \pgfextract@process\lefttailborderpoint{% + \pgfpointadd{\lefttailpoint}{\lefttailmiter}% + }% + \pgfextract@process\righttailborderpoint{% + \pgfpointadd{\righttailpoint}{\righttailmiter}% + }% + % + % Calculate the angles between the centerpoint + % and the *unrotated* borderpoints. + % + \pgfmathanglebetweenpoints{\centerpoint}{\tipborderpoint}% + \let\angletotip\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\tailcenterborderpoint}% + \let\angletotailcenter\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\lefttailborderpoint}% + \let\angletolefttail\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\righttailborderpoint}% + \let\angletorighttail\pgfmathresult% + % + % Calculate the angles between the *inversly rotated* + % basepoint and the *unrotated* borderpoints. + % + \pgfextract@process\rotatedbasepoint{% + \pgfmathrotatepointaround{\basepoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\tipborderpoint}% + \let\baseangletotip\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\tailcenterborderpoint}% + \let\baseangletotailcenter\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\lefttailborderpoint}% + \let\baseangletolefttail\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedbasepoint}{\righttailborderpoint}% + \let\baseangletorighttail\pgfmathresult% + % + % Calculate the angles between the *inversly rotated* + % midpoint and the *unrotated* borderpoints. + % + \pgfextract@process\rotatedmidpoint{% + \pgfmathrotatepointaround{\midpoint}{\centerpoint}{-\rotate}% + }% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\tipborderpoint}% + \let\midangletotip\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\tailcenterborderpoint}% + \let\midangletotailcenter\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\lefttailborderpoint}% + \let\midangletolefttail\pgfmathresult% + \pgfmathanglebetweenpoints{\rotatedmidpoint}{\righttailborderpoint}% + \let\midangletorighttail\pgfmathresult% + % + % Rotate the background path points. + % + \pgfextract@process\tippoint{% + \pgfmathrotatepointaround{\tippoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\tailcenterpoint{% + \pgfmathrotatepointaround{\tailcenterpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\lefttailpoint{% + \pgfmathrotatepointaround{\lefttailpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\righttailpoint{% + \pgfmathrotatepointaround{\righttailpoint}{\centerpoint}{\rotate}% + }% + % + % Calculate a radius guaranteed to be outside the dart. + % + \pgfextractx\pgf@xa{\pgfpointdiff{\lefttailborderpoint}{\tipborderpoint}}% + \pgfextracty\pgf@ya{\pgfpointdiff{\lefttailborderpoint}{\righttailborderpoint}}% + \ifdim\pgf@xa<0pt\relax% + \pgf@xa-\pgf@xa% + \fi% + \ifdim\pgf@ya<0pt\relax% + \pgf@ya-\pgf@ya% + \fi% + \ifdim\pgf@xa>\pgf@ya% + \edef\externalradius{\the\pgf@xa}% + \else% + \edef\externalradius{\the\pgf@ya}% + \fi% + % + % Rotate the border anchor points. + % + \pgfextract@process\tipborderpoint{% + \pgfmathrotatepointaround{\tipborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\tailcenterborderpoint{% + \pgfmathrotatepointaround{\tailcenterborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\lefttailborderpoint{% + \pgfmathrotatepointaround{\lefttailborderpoint}{\centerpoint}{\rotate}% + }% + \pgfextract@process\righttailborderpoint{% + \pgfmathrotatepointaround{\righttailborderpoint}{\centerpoint}{\rotate}% + }% + % + % Save everything. + % + \addtosavedmacro{\rotate}% + \addtosavedmacro{\externalradius}% + % + \addtosavedmacro{\tippoint}% + \addtosavedmacro{\tailcenterpoint}% + \addtosavedmacro{\lefttailpoint}% + \addtosavedmacro{\righttailpoint}% + % + \addtosavedmacro{\tipborderpoint}% + \addtosavedmacro{\tailcenterborderpoint}% + \addtosavedmacro{\lefttailborderpoint}% + \addtosavedmacro{\righttailborderpoint}% + % + \addtosavedmacro{\angletotip}% + \addtosavedmacro{\angletotailcenter}% + \addtosavedmacro{\angletolefttail}% + \addtosavedmacro{\angletorighttail}% + % + \addtosavedmacro{\baseangletotip}% + \addtosavedmacro{\baseangletotailcenter}% + \addtosavedmacro{\baseangletolefttail}% + \addtosavedmacro{\baseangletorighttail}% + % + \addtosavedmacro{\midangletotip}% + \addtosavedmacro{\midangletotailcenter}% + \addtosavedmacro{\midangletolefttail}% + \addtosavedmacro{\midangletorighttail}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint}% + \anchor{base}{\basepoint}% + \anchor{base west}{% + \installdartparameters% + \let\pgf@dartanchorborderreferencepoint\basepoint% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{base east}{% + \installdartparameters% + \let\pgf@dartanchorborderreferencepoint\basepoint% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{mid}{\midpoint}% + \anchor{mid west}{% + \installdartparameters% + \let\pgf@dartanchorborderreferencepoint\midpoint% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{mid east}{% + \installdartparameters% + \let\pgf@dartanchorborderreferencepoint\midpoint% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{north}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% + } + \anchor{south}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% + } + \anchor{east}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{west}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{north east}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% + } + \anchor{south west}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% + } + \anchor{south east}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% + } + \anchor{north west}{% + \installdartparameters% + \csname pgf@anchor@dart@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% + } + \anchor{tip}{% + \installdartparameters% + \tipborderpoint} + \anchor{left tail}{% + \installdartparameters% + \lefttailborderpoint} + \anchor{right tail}{% + \installdartparameters% + \righttailborderpoint} + \anchor{tail center}{% + \installdartparameters% + \tailcenterborderpoint} + \anchor{left side}{% + \installdartparameters% + \pgfpointlineattime{0.5}{\tipborderpoint}{\lefttailborderpoint}} + \anchor{right side}{% + \installdartparameters% + \pgfpointlineattime{0.5}{\tipborderpoint}{\righttailborderpoint}} + \backgroundpath{% + \installdartparameters% + \pgfpathmoveto{\tippoint}% + \pgfpathlineto{\lefttailpoint}% + \pgfpathlineto{\tailcenterpoint}% + \pgfpathlineto{\righttailpoint}% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % This allows anchors base east, base west, mid east and mid west, + % to redefine the `center' of the node to correctly calculate the + % border points. + % + \pgfutil@ifundefined{pgf@dartanchorborderreferencepoint}% + {\let\referencepoint\centerpoint}% + {\let\referencepoint\pgf@dartanchorborderreferencepoint}% + % + % Adjust the location of the external + % point relative to the reference point. + % + \referencepoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Install the required points and angles. + % + \installdartparameters% + % + % Get the angle of the external point relative to \referencepoint. + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + % + % *Subtract* the rotation from the external angle. + % + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + % + % Get the set of angles for the appropriate border point. + % + \ifx\referencepoint\basepoint% + \let\angletotip\baseangletotip% + \let\angletotailcenter\baseangletotailcenter% + \let\angletolefttail\baseangletolefttail% + \let\angletorighttail\baseangletorighttail% + \else% + \ifx\referencepoint\midpoint% + \let\angletotip\midangletotip% + \let\angletotailcenter\midangletotailcenter% + \let\angletolefttail\midangletolefttail% + \let\angletorighttail\midangletorighttail% + \fi\fi% + % + % Locate the appropriate line on the border... + % + \ifdim\externalangle pt<\angletotip pt\relax% + \let\firstpoint\tipborderpoint% + \let\secondpoint\righttailborderpoint% + \else% + \ifdim\externalangle pt<\angletolefttail pt\relax% + \let\firstpoint\lefttailborderpoint% + \let\secondpoint\tipborderpoint% + \else% + \ifdim\externalangle pt<\angletotailcenter pt\relax% + \let\firstpoint\lefttailborderpoint% + \let\secondpoint\tailcenterborderpoint% + \else% + \ifdim\externalangle pt<\angletorighttail pt\relax% + \let\firstpoint\righttailborderpoint% + \let\secondpoint\tailcenterborderpoint% + \else% + \let\firstpoint\tipborderpoint% + \let\secondpoint\righttailborderpoint% + \fi% + \fi% + \fi% + \fi% + % + % ...and thus the point on the border. + % + \pgfpointintersectionoflines{\referencepoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + }% +} + + + +% Keys for shape circular sector: +% +% /pgf/circular sector angle : the angle at the center of the sector. +% +\pgfkeys{/pgf/circular sector angle/.initial=60} + +% Shape circular sector +% +\pgfdeclareshape{circular sector}{% + \savedmacro\installcircularsectorparameters{% + % + % Define a \centerpoint, \basepoint and \midpoint. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Half of the sector angle is more useful. + % + \pgfmathmod{\pgfkeysvalueof{/pgf/circular sector angle}}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\angle\pgfmathresult% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\halfangle\pgfmathresult% + % + % Get some useful trigonometric stuff. + % + \pgfmathsin@{\halfangle}% + \let\sinehalfangle\pgfmathresult% + \pgfmathreciprocal@{\pgfmathresult}% + \let\cosechalfangle\pgfmathresult% + \pgfmathabs@{\halfangle}% + \pgfmathcos@{\pgfmathresult}% + \let\coshalfangle\pgfmathresult% + \pgf@x\pgfmathresult pt\relax% + \pgf@x\cosechalfangle\pgf@x% + \edef\cothalfangle{\pgfmath@tonumber{\pgf@x}}% + % + % Calculate the miter length at the center, + % according to the outer sep. + % + \pgf@x\outersep\relax% + \pgf@x\cosechalfangle\pgf@x% + \edef\centermiter{\the\pgf@x}% + % + % Get the start and end angles of the arc. + % + \pgfmathsubtract@{180}{\halfangle}% + \let\startangle\pgfmathresult% + \pgfmathadd@{180}{\halfangle}% + \let\endangle\pgfmathresult% + % + % Get (half) the node dimensions. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + % Calculate the radius of the sector and the `center offset', + % which is the distance between the center of the node and the + % center of the sector. + % + \ifpgfshapeborderusesincircle% + % + % Get the rotation. + % + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + % + % Calculate the incircle radius. + % + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + \pgf@xa\cosechalfangle\pgf@x% + % + % xa is the radius, xb the offset. + % + \pgf@xb\pgf@xa% + \advance\pgf@xa\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % Swap the height and width for relevant angles. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + % + % xa is the radius, xb the offset. + % + \pgf@xa\cosechalfangle\pgf@y% + \pgf@xa\coshalfangle\pgf@xa% + \advance\pgf@xa\pgf@x% + \pgf@xb\pgf@xa% + \advance\pgf@xa\pgf@x% + \pgfmathveclen@{\the\pgf@xa}{\the\pgf@y}% + \pgf@xa\pgfmathresult pt\relax% + \fi% + % + % Adjust for minimum height and width. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}% + \pgf@x.5\pgf@x% + \pgfmathsec@{\halfangle}% + \pgf@xc\pgfmathresult\pgf@xb% + \ifdim\pgf@xc<0pt\relax% + \pgf@xc-\pgf@xc% + \fi% + \ifdim\pgf@xc<\pgf@x% + \pgfmathreciprocal{\pgfmath@tonumber{\pgf@xc}}% + \pgf@xc\pgfmathresult\pgf@x% Increase by ratio. + \pgf@xa\pgfmath@tonumber{\pgf@xc}\pgf@xa% + \pgf@xb\pgfmath@tonumber{\pgf@xc}\pgf@xb% + \fi% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@xa<\pgf@y% + \pgfmathreciprocal{\pgfmath@tonumber{\pgf@xa}}% + \pgf@xc\pgfmathresult\pgf@y% Increase by ratio. + \pgf@xa\pgf@y% + \pgf@xb\pgfmath@tonumber{\pgf@xc}\pgf@xb% + \fi% + \edef\centeroffset{\the\pgf@xb}% + \edef\radius{\the\pgf@xa}% + % + % Calculate the radius at sector border and the arc corners. + % + \advance\pgf@xa\outersep\relax% + \edef\borderradius{\the\pgf@xa}% + \pgf@x\outersep\relax% + \pgf@x\cosechalfangle\pgf@x% + \pgf@x\coshalfangle\pgf@x% + \advance\pgf@xa\pgf@x% + \edef\cornerradius{\the\pgf@xa}% + % + % Calculate the *unrotated* points for the background path. + % + \pgfextract@process\sectorcenter{% + \centerpoint% + \advance\pgf@x\centeroffset% + }% + \pgfextract@process\arcstart{% + \pgfqpointpolar{\startangle}{\radius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \sectorcenter% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Calculate the *unrotated* points for the anchor border. + % + \pgfextract@process\sectorcenterborder{% + \sectorcenter% + \advance\pgf@x\centermiter\relax% + }% + \pgfextract@process\arcstartborder{% + \pgfqpointpolar{\startangle}{\borderradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \sectorcenter% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfextract@process\arcendborder{% + \pgfqpointpolar{\endangle}{\borderradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \sectorcenter% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfextract@process\arcstartcorner{% + \pgfqpointpolar{\startangle}{\cornerradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \sectorcenterborder% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfextract@process\arcendcorner{% + \pgfqpointpolar{\endangle}{\cornerradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \sectorcenterborder% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Calculate the *unrotated* corner angles to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\sectorcenterborder}% + \let\angletosectorcenterborder\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcstartborder}% + \let\angletoarcstartborder\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcendborder}% + \let\angletoarcendborder\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcstartcorner}% + \let\angletoarcstartcorner\pgfmathresult% + \pgfmathanglebetweenpoints{\centerpoint}{\arcendcorner}% + \let\angletoarcendcorner\pgfmathresult% + % + % Rotate the background path points around the note center. + % + \pgfextract@process\sectorcenter{% + \pgfmathrotatepointaround{\sectorcenter}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcstart{% + \pgfmathrotatepointaround{\arcstart}{\centerpoint}{\rotate}% + }% + % + % Rotate the border points around the note center. + % + \pgfextract@process\sectorcenterborder{% + \pgfmathrotatepointaround{\sectorcenterborder}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcstartborder{% + \pgfmathrotatepointaround{\arcstartborder}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcendborder{% + \pgfmathrotatepointaround{\arcendborder}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcstartcorner{% + \pgfmathrotatepointaround{\arcstartcorner}{\centerpoint}{\rotate}% + }% + \pgfextract@process\arcendcorner{% + \pgfmathrotatepointaround{\arcendcorner}{\centerpoint}{\rotate}% + }% + % + % Add the rotation to the start and end angles. + % + \pgfmathadd@{\startangle}{\rotate}% + \let\startangle\pgfmathresult% + \pgfmathadd@{\endangle}{\rotate}% + \let\endangle\pgfmathresult% + % + % Save everything. + % + % NB \addtosavedmacro is currently experimental. May get changed. + % + \addtosavedmacro{\rotate}% + \addtosavedmacro{\centeroffset}% + % + \addtosavedmacro{\radius}% + \addtosavedmacro{\borderradius}% + \addtosavedmacro{\cornerradius}% + % + \addtosavedmacro{\endangle}% + \addtosavedmacro{\startangle}% + % + \addtosavedmacro{\sectorcenter}% + \addtosavedmacro{\arcstart}% + % + \addtosavedmacro{\sectorcenterborder}% + \addtosavedmacro{\arcstartborder}% + \addtosavedmacro{\arcendborder}% + \addtosavedmacro{\arcstartcorner}% + \addtosavedmacro{\arcendcorner}% + % + \addtosavedmacro{\angletosectorcenterborder}% + \addtosavedmacro{\angletoarcstartborder}% + \addtosavedmacro{\angletoarcendborder}% + \addtosavedmacro{\angletoarcstartcorner}% + \addtosavedmacro{\angletoarcendcorner}% + }% + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt\relax% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint} + \anchor{base}{\basepoint} + \anchor{mid}{\midpoint} + \anchor{arc start}{% + \installcircularsectorparameters% + \arcstartcorner% + } + \anchor{arc end}{% + \installcircularsectorparameters% + \arcendcorner% + } + \anchor{sector center}{% + \installcircularsectorparameters% + \sectorcenterborder% + } + \anchor{arc center}{% + \installcircularsectorparameters% + \pgfmathadd@{\rotate}{180}% + \let\angle\pgfmathresult% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpointpolar{\angle}{\cornerradius}}% + } + \anchor{north}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{0pt}{\cornerradius}}% + } + \anchor{south}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{0pt}{-\cornerradius}}% + } + \anchor{east}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{0pt}}% + } + \anchor{west}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{0pt}}% + } + \anchor{north west}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{\cornerradius}}% + } + \anchor{south west}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{-\cornerradius}{-\cornerradius}}% + } + \anchor{north east}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{\cornerradius}}% + } + \anchor{south east}{% + \installcircularsectorparameters% + \csname pgf@anchor@circular sector@border\endcsname{\pgfqpoint{\cornerradius}{-\cornerradius}}% + } + \backgroundpath{% + \installcircularsectorparameters% + \pgfpathmoveto{\sectorcenter}% + \pgfpathlineto{\arcstart}% + \ifdim\endangle pt>360pt\relax% + \ifdim\startangle pt>360pt\relax% + \pgfpatharc{\startangle}{\endangle}{\radius}% + \else% + \pgfpatharc{\startangle}{360}{\radius}% + \pgfpatharc{0}{\endangle}{\radius}% + \fi% + \else% + \pgfpatharc{\startangle}{\endangle}{\radius}% + \fi% + \pgfpathclose% + }% + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Install the required points and angles. + % + \installcircularsectorparameters% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + \let\externalangle\pgfmathresult% + % + % *Subtract* the rotation from the external angle. + % + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\angle\pgfmathresult% + % + % Determine if the line will cross the sector arc. + % + \ifdim\angle pt>\angletoarcendcorner pt\relax% + \let\firstpoint\arcendcorner% + \let\secondpoint\sectorcenterborder% + \else% + \ifdim\angle pt>\angletoarcendborder pt\relax% + \let\firstpoint\arcendborder% + \let\secondpoint\arcendcorner% + \else% + \ifdim\angle pt>\angletoarcstartborder pt\relax% + \let\firstpoint\pgfutil@empty% + \let\secondpoint\pgfutil@empty% + \else% + \ifdim\angle pt>\angletoarcstartcorner pt\relax% + \let\firstpoint\arcstartborder + \let\secondpoint\arcstartcorner + \else% + \let\firstpoint\sectorcenterborder% + \let\secondpoint\arcstartcorner% + \fi% + \fi% + \fi% + \fi% + \ifx\firstpoint\pgfutil@empty + % + % Calculate the angle from the centre of the semicircle to the + % point on the semicircle arc which intersects the line from + % the external point to the reference point... + % + \pgfmathanglebetweenlines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\sectorcenter}{\centerpoint}% + \pgfmathsin@{\pgfmathresult}% + \let\sineangle\pgfmathresult% + \pgf@x\borderradius\relax% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@x}}% + \let\reciprocalradius\pgfmathresult% + \pgf@x\centeroffset\relax% + \pgf@x\sineangle\pgf@x% + \pgf@x\reciprocalradius\pgf@x% + \pgfmathasin@{\pgfmath@tonumber{\pgf@x}}% + \pgf@x\pgfmathresult pt\relax% + \advance\pgf@x\externalangle pt\relax% + \edef\angle{\pgfmath@tonumber{\pgf@x}}% + % + % ...and thus the point on the border. + % + \pgfpointadd{\sectorcenter}{\pgfqpointpolar{\angle}{\borderradius}}% + \else% + % + % Calculate the the point where the semicircle chord intersects + % the line from the external point to the reference point. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + \fi% + }% +} + + + +% Keys for shape cylinder +% +% /pgf/shape aspect : Ratio between the x and y radii of the cylinder end. +% /pgf/cylinder uses custom fill : Use a custom fill for the cylinder. +% /pgf/cylinder end fill : Custom color for the cylinder end. +% /pgf/cylinder body fill : Custom color for the cylinderbody. +% + +\newif\ifpgfcylinderusescustomfill +\pgfkeys{/pgf/.cd, + cylinder uses custom fill/.is if=pgfcylinderusescustomfill, + cylinder end fill/.initial=white, + cylinder body fill/.initial=white +} + + +\pgfdeclareshape{cylinder}{% + \savedmacro\getcylinderpoints{% + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgf@x\pgf@xc% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}% + \pgf@y\pgf@yc% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \ifpgfshapeborderusesincircle% + \pgfmathsetmacro\rotate{\pgfkeysvalueof{/pgf/shape border rotate}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \else% + \pgf@y\pgf@x% + \fi% + \pgf@x1.414213\pgf@x% + \pgf@y1.414213\pgf@y% + \else% + \pgfmathmod{\pgfkeysvalueof{/pgf/shape border rotate}}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \pgfmathsetcount\c@pgf@counta{+\pgfmathresult}% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \edef\rotate{\the\c@pgf@counta}% + \ifnum\c@pgf@counta=90\relax% + \pgf@xa\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xa% + \pgf@yc\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xa\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xa% + \pgf@yc\pgf@xc% + \fi% + \fi% + \fi% + \addtosavedmacro\rotate% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfutil@tempdima\pgfshapeaspect\pgf@ya% + \pgfutil@tempdimb\pgf@ya% + % + % Adjust for minimum height. + % + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgfutil@tempdimb<.5\pgf@xc\relax% + \pgfutil@tempdimb.5\pgf@xc% + \pgf@ya\pgfutil@tempdimb% + \fi% + % + % Calculate how far the node contents can extend into the cylinder bottom. + % + \pgf@yb\pgfutil@tempdimb% + \advance\pgf@yb-\pgf@yc% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@yb}}{\pgfmath@tonumber{\pgfutil@tempdimb}}% + \pgfmathasin@{\pgfmathresult}% + \pgfmathcos@{\pgfmathresult}% + \let\angle\pgfmathresult% + \pgf@xb\pgfmathresult\pgfutil@tempdima% + % + % Adjust for minimum width. + % + \pgf@x.5\pgflinewidth% + \advance\pgf@x2.0\pgf@xa% + \advance\pgf@x3.0\pgfutil@tempdima% + \advance\pgf@x-\pgf@xb% + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<\pgf@xc% + \advance\pgf@xc-\pgf@x% + \advance\pgf@xa.5\pgf@xc% + \fi% + % + % Add the larger of the outer sep to the radii. + % + \pgf@x\pgfutil@tempdima\relax% + \pgf@y\pgfutil@tempdimb\relax% + \pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xc>\pgf@yc% + \advance\pgf@x\pgf@xc% + \advance\pgf@y\pgf@xc% + \edef\outersep{\the\pgf@xc}% + \else% + \advance\pgf@x\pgf@yc% + \advance\pgf@y\pgf@yc% + \edef\outersep{\the\pgf@yc}% + \fi% + \edef\xradius{\the\pgf@x}% + \edef\yradius{\the\pgf@y}% + \addtosavedmacro\xradius% + \addtosavedmacro\yradius% + \addtosavedmacro\outersep% + % + \pgfextract@process\cylindercenter{% + \pgf@x\pgfutil@tempdima% + \advance\pgf@x.5\pgflinewidth% + \advance\pgf@x\pgf@xb% + \pgf@x.5\pgf@x% + \pgf@y0pt% + }% + \addtosavedmacro\cylindercenter% + % + \pgfextract@process\beforetop{% + \pgf@x\pgf@xa% + \advance\pgf@x\pgfutil@tempdima% + \advance\pgf@x.5\pgflinewidth% + \pgf@y\pgf@ya% + }% + \pgfextract@process\afterbottom{% + \pgf@x-\pgf@xa% + \advance\pgf@x\pgf@xb% + \pgf@y\pgf@ya% + }% + \addtosavedmacro\beforetop% + \addtosavedmacro\afterbottom% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/outer ysep}}% + \pgfextract@process\beforetopanchor{% + \beforetop% + \advance\pgf@y\pgf@yc% + }% + \pgfextract@process\afterbottomanchor{% + \afterbottom% + \advance\pgf@y\pgf@yc% + }% + \addtosavedmacro\beforetopanchor% + \addtosavedmacro\afterbottomanchor% + % + \beforetopanchor% + \advance\pgf@x\xradius\relax% + \ifdim\pgf@x>\pgf@y% + \edef\externalradius{\the\pgf@x}% + \else% + \edef\externalradius{\the\pgf@y}% + \fi% + \addtosavedmacro\externalradius% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + }% + \anchor{center}{\centerpoint} + \anchor{shape center}{% + \getcylinderpoints% + \pgfmathrotatepointaround{\pgfpointadd{\cylindercenter}{\centerpoint}}% + {\centerpoint}{\rotate}% + }% + \anchor{mid}{\midpoint}% + \anchor{mid east}{% + \getcylinderpoints% + \let\pgf@cylinder@referencepoint\midpoint% + \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}% + }% + \anchor{mid west}{% + \getcylinderpoints% + \let\pgf@cylinder@referencepoint\midpoint% + \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{base}{\basepoint}% + \anchor{base east}{% + \getcylinderpoints% + \let\pgf@cylinder@referencepoint\basepoint% + \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}% + }% + \anchor{base west}{% + \getcylinderpoints% + \let\pgf@cylinder@referencepoint\basepoint% + \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{north}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{0pt}{\externalradius}}% + }% + \anchor{south}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{0pt}{-\externalradius}}% + }% + \anchor{east}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{0pt}}% + }% + \anchor{west}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{0pt}}% + }% + \anchor{north east}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{\externalradius}}% + }% + \anchor{south west}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{-\externalradius}}% + }% + \anchor{south east}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{\externalradius}{-\externalradius}}% + }% + \anchor{north west}{% + \getcylinderpoints% + \pgf@anchor@cylinder@border{\pgfqpoint{-\externalradius}{\externalradius}}% + }% + \anchor{before top}{% + \getcylinderpoints% + \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor}{\centerpoint}}{\centerpoint}{\rotate}% + } + \anchor{top}{% + \getcylinderpoints% + \pgfmathrotatepointaround{% + \pgfpointadd{% + \beforetop% + \pgf@y0pt\relax% + \advance\pgf@x\xradius\relax% + }{\centerpoint}}{\centerpoint}{\rotate}% + } + \anchor{after top}{% + \getcylinderpoints% + \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}{\centerpoint}{\rotate}% + } + \anchor{before bottom}{% + \getcylinderpoints% + \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}{\centerpoint}{\rotate}% + } + \anchor{bottom}{% + \getcylinderpoints% + \pgfmathrotatepointaround{% + \pgfpointadd{% + \afterbottom% + \pgf@y0pt\relax% + \advance\pgf@x-\xradius\relax% + }{\centerpoint}}{\centerpoint}{\rotate}% + } + \anchor{after bottom}{% + \getcylinderpoints% + \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor}{\centerpoint}}{\centerpoint}{\rotate}% + } + \backgroundpath{% + \getcylinderpoints% + {% + \pgf@x\xradius\relax% + \advance\pgf@x-\outersep\relax% + \edef\xradius{\the\pgf@x}% + \pgf@y\yradius\relax% + \advance\pgf@y-\outersep\relax% + \edef\yradius{\the\pgf@y}% + \pgftransformshift{\centerpoint}% + \pgftransformrotate{\rotate}% + \pgfpathmoveto{\afterbottom}% + \pgfpatharc{90}{270}{\xradius and \yradius}% + \pgfpathlineto{\beforetop\pgf@y-\pgf@y}% + \pgfpatharc{-90}{90}{\xradius and \yradius}% + \pgfpathclose% + \pgfpathmoveto{\beforetop}% + \pgfpatharc{90}{270}{\xradius and \yradius}% + }% + }% + \behindbackgroundpath{% + \ifpgfcylinderusescustomfill% + \getcylinderpoints% + \pgf@x\xradius\relax% + \advance\pgf@x-\outersep\relax% + \edef\xradius{\the\pgf@x}% + \pgf@y\yradius\relax% + \advance\pgf@y-\outersep\relax% + \edef\yradius{\the\pgf@y}% + {% + \pgftransformshift{\centerpoint}% + \pgftransformrotate{\rotate}% + \pgfpathmoveto{\afterbottom}% + \pgfpatharc{90}{270}{\xradius and \yradius}% + \pgfpathlineto{\beforetop\pgf@y-\pgf@y}% + \pgfpatharc{270}{90}{\xradius and \yradius}% + \pgfpathclose% + \expandafter\pgfsetfillcolor\expandafter{\pgfkeysvalueof{/pgf/cylinder body fill}}% + \pgfusepath{fill}% + % + \pgfpathmoveto{\beforetop}% + \pgfpatharc{90}{-270}{\xradius and \yradius}% + \pgfpathclose + \expandafter\pgfsetfillcolor\expandafter{\pgfkeysvalueof{/pgf/cylinder end fill}}% + \pgfusepath{fill}% + }% + \fi% + }% + \anchorborder{% + \pgfextract@process\externalpoint{}% + \getcylinderpoints% + \pgfutil@ifundefined{pgf@cylinder@referencepoint}{\let\referencepoint\centerpoint}{% + \let\referencepoint\pgf@cylinder@referencepoint}% + \pgfextract@process\externalpoint{% + \externalpoint% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \referencepoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + % + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\afterbottomanchor}{\centerpoint}}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\beforetopanchor}{\centerpoint}}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathrotatepointaround{% + \pgfmathpointintersectionoflineandarc% + {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}% + {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}% + {% + \beforetop% + \pgf@xa\pgf@x% + \centerpoint% + \advance\pgf@x\pgf@xa% + }% + {0}{90}{\xradius and \yradius}% + }{\centerpoint}{\rotate}% + \else% + \pgfpointintersectionoflines{% + \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor}{\centerpoint}}% + {\centerpoint}{\rotate}}{% + \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor}{\centerpoint}}% + {\centerpoint}{\rotate}}% + {\referencepoint}{\externalpoint}% + \fi% + \else% + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}% + \ifdim\externalangle pt>\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\referencepoint}{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}% + \ifdim\externalangle pt>\pgfmathresult pt\relax% + \pgfmathrotatepointaround{% + \pgfmathpointintersectionoflineandarc% + {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}% + {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}% + {% + \beforetop% + \pgf@xa\pgf@x% + \centerpoint + \advance\pgf@x\pgf@xa% + }% + {270}{360}{\xradius and \yradius}% + }{\centerpoint}{\rotate}% + \else% + \pgfpointintersectionoflines{% + \pgfmathrotatepointaround{\pgfpointadd{\afterbottomanchor\pgf@y-\pgf@y}{\centerpoint}}% + {\centerpoint}{\rotate}}{% + \pgfmathrotatepointaround{\pgfpointadd{\beforetopanchor\pgf@y-\pgf@y}{\centerpoint}}% + {\centerpoint}{\rotate}}% + {\referencepoint}{\externalpoint}% + \fi% + \else% + \pgfmathrotatepointaround{% + \pgfmathpointintersectionoflineandarc% + {\pgfmathrotatepointaround{\externalpoint}{\centerpoint}{-\rotate}}% + {\pgfmathrotatepointaround{\referencepoint}{\centerpoint}{-\rotate}}% + {% + \afterbottom% + \pgf@xa\pgf@x% + \centerpoint + \advance\pgf@x\pgf@xa% + }% + {90}{270}{\xradius and \yradius}% + }{\centerpoint}{\rotate}% + \fi% + \fi% + } +} |