如何在自定义 TikZ 形状中定位自定义锚点?

如何在自定义 TikZ 形状中定位自定义锚点?

我想画一个“系统动力学”流程图,大致如下随机图像。深灰色阀门状盒子代表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}

新形态

相关内容