You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4417 lines
157 KiB
4417 lines
157 KiB
% 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{pgflibraryshapes.geometric.code.tex}
|
|
|
|
\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{%
|
|
%
|
|
% Calculate ``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%
|
|
%
|
|
% Calculate ``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 height, if necessary
|
|
%
|
|
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/minimum height}}%
|
|
\ifdim\pgf@y<.5\pgf@yc%
|
|
\pgf@y=.5\pgf@yc%
|
|
\fi%
|
|
%
|
|
% Adjust width, if necessary
|
|
%
|
|
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/minimum width}}%
|
|
\ifdim\pgf@x<.5\pgf@xc%
|
|
\pgf@x=.5\pgf@xc%
|
|
\fi%
|
|
%
|
|
% Add outer sep
|
|
%
|
|
\pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
|
|
\pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
|
|
\advance\pgf@x by\pgf@xb%
|
|
\advance\pgf@y by\pgf@yb%
|
|
}%
|
|
|
|
%
|
|
% 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 compatibility 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.
|
|
%
|
|
\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 compatibility 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 rectangular 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}%
|
|
}%
|
|
%
|
|
% Calculate 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 radius 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 vertices
|
|
% 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 *inversely 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 background 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 *inversely 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 *inversely 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@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\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 cylinder body.
|
|
%
|
|
|
|
\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%
|
|
}%
|
|
}%
|
|
|