journal-article/tikzlibrarytree-triangle-fit.code.tex

185 lines
5.7 KiB
TeX
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

% %%%%%%%
% % From http://tex.stackexchange.com/questions/314053/how-to-declare-a-tikz-directory-or-group-of-keys/314065?noredirect=1#comment765927_314065
% \pgfkeys{
% /handlers/.is directory/.code={
% \pgfkeysedef{\pgfkeyscurrentpath}{
% \noexpand\pgfkeys{\pgfkeyscurrentpath/.cd,##1}
% }
% }
% }
% %%%%%%%
\ifx\pgfmathsign\relax%
\tikzmath{
function sign(\x) {
if (\x < 0) then {
return -1;
} else {
if (\x > 0) then {
return 1;
} else {
return 0;
};
};
};
}
\fi%
\newif\iftrianglefitisosceles
\newif\iftrianglefitbackground
\tikzset{
triangle fit current style/.style={},
triangle fit current background style/.style={},
triangle fit/.unknown/.code={
% \message{triangle fit unknown:\pgfkeyscurrentkeyRAW=#1^^J}
\let\trianglefitstorekey=\pgfkeyscurrentkeyRAW
\edef\triangleExp{
\noexpand\tikzset{
/tikz/triangle fit current style/.append style={
\trianglefitstorekey=\noexpand#1
}
}
}
\triangleExp
%\pgfqkeys{/tikz}{}
},
triangle fit/triangle sep/.initial=0.15em,
triangle fit/triangle sep/.default=0.15em,
triangle fit/top space/.initial=1.5ex,
triangle fit/top space/.default=1.5ex,
triangle fit/bottom space/.initial=0ex,
triangle fit/bottom space/.default=0ex,
triangle fit/top/.initial=,
triangle fit/nodes/.initial=,
triangle fit/no rounded corners/.style={/tikz/rounded corners=0pt},
every triangle fit/.style={
triangle sep=.15em,
rounded corners=5pt,
isosceles,
},
triangle fit/isosceles/.is if=trianglefitisosceles,
triangle fit/not isosceles/.style={isosceles=false},
triangle fit/bg/.code={
\tikzset{
triangle fit current background style/.style={#1},
}
},
triangle fit/.code={
\tikzset{
/tikz/triangle fit current style/.style={},
/tikz/triangle fit/.cd,
/tikz/every triangle fit,
#1,
}
% \node[draw, /tikz/every triangle fit] {EEE}
% \edef\currenttrianglestyle{\pgfkeysvalueof{/tikz/triangle fit/style}}
% \message{\currenttrianglestyle}
% \tikzset{
% triangle fit current style/.style=\currenttrianglestyle,
% }
% Compute the minimum and maxiumum slope, as well as the maximum y (i.e. height) for the triangle.
\tikzmath{
coordinate \pt,\ttop;
% int \found;
% \found{top} = 0;
% \found{bot} = 0;
\ttop=([yshift=\pgfkeysvalueof{/tikz/triangle fit/top space}]\pgfkeysvalueof{/tikz/triangle fit/top});
\slopeleft = 0;
\sloperight = 0;
\maxdy = 0;
}
% Foreach loop over all nodes, which computes the max and min slopes and triangle height
\edef\triangleFitItems{\pgfkeysvalueof{/tikz/triangle fit/nodes}}
\foreach \i in \triangleFitItems{
\foreach \ii in {(\i.north east),(\i.south east),(\i.south west),(\i.north west)} {
\tikzmath{
\pt = \ii;
\dx = \ptx - \ttopx;
\dx = \dx + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dx);
\dy = \ttopy - \pty;
\dy = \dy + \pgfkeysvalueof{/tikz/triangle fit/triangle sep} * sign(\dy);
\slope = \dx / \dy;
if \slope > \sloperight then {
\sloperight = \slope;
};
if \slope < \slopeleft then {
\slopeleft = \slope;
};
if \dy > \maxdy then {
\maxdy = \dy;
};
}
\global\let\sloperight\sloperight%
\global\let\slopeleft\slopeleft%
\global\let\maxdy\maxdy%
% \message{\ii, ptx=\ptx, pty=\pty, dx=\dx, dy=\dy, slope=\slope, sloperight=\sloperight, slopeleft=\slopeleft, maxdy=\maxdy^^J}
}
}
\tikzmath{
\maxdy = \maxdy + \pgfkeysvalueof{/tikz/triangle fit/bottom space};
}
\iftrianglefitisosceles
\tikzmath{
if -\sloperight < \slopeleft then {
\slopeleft = -\sloperight;
};
if -\slopeleft > \sloperight then {
\sloperight = -\slopeleft;
};
}
\fi
% Draw the triangle:
\draw[/tikz/triangle fit current style]
(\ttopx,\ttopy)
-- +(\sloperight*\maxdy pt,-\maxdy pt)
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
-- cycle;
% Draw the background
\begin{pgfonlayer}{background}
\path[/tikz/triangle fit current background style]
(\ttopx,\ttopy)
-- +(\sloperight*\maxdy pt,-\maxdy pt)
-- +(\slopeleft*\maxdy pt,-\maxdy pt)
-- cycle;
\end{pgfonlayer}
}
}
\def\nodx{
node[draw, every triangle fit, triangle fit={top={\fittriangletop},nodes={\fittriangletop\foresteoption{fit these}}}] {nodes:\fittriangletop\foresteoption{fit these}}
}
% \forestset{
% % every triangle fit/.forward to=/tikz/every triangle fit,
% every triangle fit/append/.forward to=/tikz/every triangle fit/append,
% every triangle fit/style/.forward to=/tikz/every triangle fit/style,
% declare toks={fit these}{},
% triangle fit whole subtree/.style={
% delay={
% temptoksa=,
% for descendants={%
% temptoksa+/.wrap pgfmath arg={,##1}{name()},
% },
% fit these/.register=temptoksa,
% delay={
% % /utils/exec={
% % \pgfmathsetmacro{\fittriangletop}{name()}
% % \message{^^JFIT THESE=\foresteoption{fit these}, NAME=\fittriangletop^^J}
% % },
% % append after command={
% % \nodx
% % },
% tikz+={
% \pgfmathsetmacro{\fittriangletop}{name()}
% % \message{\foresteoption{fit these}}
% \path[triangle fit={
% top=\fittriangletop.north,
% nodes={\fittriangletop\foresteoption{fit these}},
% #1
% }];
% },
% },
% },
% },
% }