我想画一个“系统动力学”流程图,大致如下随机图像。深灰色阀门状盒子代表rates
,灰色矩形代表levels
。
我设法定义了一个看起来不错的形状,但我很难修改锚点east
,以便它始终落在阀门的交叉点上。
平均能量损失
\documentclass{scrartcl}
\usepackage{tikz}
\makeatletter
\pgfdeclareshape{rate}{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\savedanchor\centerpoint{\pgf@x=0cm \pgf@y=0cm}
\saveddimen\halfheight{
\pgf@x=\ht\pgfnodeparttextbox
\advance\pgf@x by\pgfshapeinnerysep
\pgfmathsetlength\pgf@xa{.5\pgfkeysvalueof{/pgf/minimum height}}
\ifdim\pgf@x<\pgf@xa\pgf@x=\pgf@xa\fi}
\anchor{east}{%
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y%
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y%
\pgf@x=\pgf@xb \advance\pgf@x by5pt
\pgf@y=\pgf@ya \advance\pgf@y by\halfheight
}
\backgroundpath{
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y%
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y%
% offset of valve part
\pgf@xc=10pt \pgf@yc=4pt%
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}%
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}%
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}%
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\pgfpoint{\pgf@xc}{\pgf@yc}}}%
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\pgfpoint{\pgf@xc}{-\pgf@yc}}}%
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}%
\pgfpathclose%
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[draw,shape=rate,fill=gray!10,inner sep=5pt] at (0,0) (fres) {\ttfamily FRES};
\draw[black] (fres.east) -- +(0,-1);
\end{tikzpicture}
\end{document}
产生
所有这些魔法和普通 TeX 的文档\pgf@
对我来说仍然很晦涩难懂。我怎样才能将锚点放在east
我想要的位置?
答案1
东锚的 y 位置只是顶部和底部 y 值的平均值。x 位置取决于阀门部分左侧和右侧的相对高度,因此我将右侧的高度设为左侧高度的一半,将交叉点置于 2/3 处。
\documentclass{scrartcl}
\usepackage{tikz}
\makeatletter
\pgfdeclareshape{rate}{
\inheritsavedanchors[from=rectangle] % this is nearly a rectangle
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{west}
\savedanchor\centerpoint{\pgfpointorigin}
\anchor{east}{%
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
\advance\pgf@x by8pt
\pgf@y=\dimexpr 0.5\pgf@ya + 0.5\pgf@yb
}
\backgroundpath{
% store lower right in xa/ya and upper right in xb/yb
\southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y%
\northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y%
% offset of valve part
\pgf@xc=12pt \pgf@yc=\dimexpr 0.25\pgf@yb - 0.25\pgf@ya
% construct main path
\pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}%
\pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}%
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}%
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@ya}}{\pgfpoint{\pgf@xc}{\pgf@yc}}}%
\pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xb}{\pgf@yb}}{\pgfpoint{\pgf@xc}{-\pgf@yc}}}%
\pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}%
\pgfpathclose%
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[draw,shape=rate,fill=gray!10,inner sep=5pt] at (0,0) (fres) {\ttfamily FRES};
\draw[black] (fres.east) -- +(0,-1);
\end{tikzpicture}
\end{document}