Tikz/PGF 自定义节点不工作

Tikz/PGF 自定义节点不工作

我正在编写一个简单的包来定义我在工作中经常做的一些绘图任务。有许多符号经常被重复使用,我想将它们添加为自定义节点。我看过pgf/tikz 节点自定义形状创建节点形状;我发现两者都很有用,并且阅读了第 49.5 章关于从tikz/pgf 手册(特别是第 335 页的示例。两者都非常有用。但是,我仍然遇到一个问题,我怀疑它很简单。

以下是与该问题相关的代码片段:

    \tikzset{leverage/.initial={}}

    \pgfdeclareshape{circle player}{
        \inheritsavedanchors[from=circle]
        \inheritanchorborder[from=circle]
        \inheritanchor[from=circle]{center}
        \inheritanchor[from=circle]{south}
        \inheritanchor[from=circle]{west}
        \inheritanchor[from=circle]{north}
        \inheritanchor[from=circle]{east}

        \inheritbackgroundpath[from=circle]
        \beforebackgroundpath{
            % get and set options
            \pgfkeys{/tikz/leverage/.get=\tmp}
            \expandafter\tikzset\expandafter{\tmp}
            \tikz@options

        % get north and south coordinates
        \north \pgf@xa=\pgf@x \pgf@ya=\pgf@y
        \south \pgf@xb=\pgf@x \pgf@yb=\pgf@y

        % draw the line starting from north
        \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
        \pgfpathclose
        }
    }
    \begin{tikzpicture}
    \node[circle player, draw=black] at (240,90) {};
    \end{tikzpicture}

形状声明出现在 .sty 文件中(其中我不需要\makeatletter\makeatother,并且没有遇到任何问题),以及杠杆选项的声明(目前未使用,但将来会使用)。我已通过编写其他命令、在文档的序言中使用并执行这些命令来验证 .sty 文件是否正常工作。问题似乎集中在节点的新形状声明上。我无法弄清楚为什么会出现问题;我在尝试使用新定义的节点形状时\usepackage总是遇到这个问题。undefined control sequence

我遗漏了什么? 可能非常简单。

答案1

我不知道它应该用 beforebackgroundpath 做什么但是这个至少可以编译为一条垂直线。

\documentclass[tikz, border=1cm]{standalone}
\makeatletter
\pgfdeclareshape{circle player}{
    \inheritsavedanchors[from=circle]
    \inheritanchorborder[from=circle]
    \inheritanchor[from=circle]{center}
    \inheritanchor[from=circle]{south}
    \inheritanchor[from=circle]{west}
    \inheritanchor[from=circle]{north}
    \inheritanchor[from=circle]{east}

    \inheritbackgroundpath[from=circle]
    \saveddimen\radius{%
      \pgf@ya=.5\ht\pgfnodeparttextbox%
      \advance\pgf@ya by.5\dp\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/inner ysep}}%
      \advance\pgf@ya by\pgf@yb%
      \pgf@xa=.5\wd\pgfnodeparttextbox%
      \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/inner xsep}}%
      \advance\pgf@xa by\pgf@xb%
      \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgf@xa}{\pgf@ya}}}%
      \ifdim\pgf@x>\pgf@y\c@pgf@counta=\pgf@x\ifnum\c@pgf@counta=0\relax%
          \else%
            \divide\c@pgf@counta by 255\relax\pgf@xa=16\pgf@xa\relax%
            \divide\pgf@xa by\c@pgf@counta \pgf@xa=16\pgf@xa\relax%
          \fi%
        \else%
          \c@pgf@counta=\pgf@y\ifnum\c@pgf@counta=0\relax\else%
            \divide\c@pgf@counta by 255\relax\pgf@ya=16\pgf@ya\relax%
            \divide\pgf@ya by\c@pgf@counta \pgf@xa=16\pgf@ya\relax\fi%
      \fi%
      \pgf@x=\pgf@xa%
      \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/minimum width}}%  
      \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/minimum height}}%  
      \ifdim\pgf@x<.5\pgf@xb \pgf@x=.5\pgf@xb \fi%
      \ifdim\pgf@x<.5\pgf@yb \pgf@x=.5\pgf@yb \fi%
      \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%  
      \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%  
      \ifdim\pgf@xb<\pgf@yb%
        \advance\pgf@x by\pgf@yb%
      \else%
        \advance\pgf@x by\pgf@xb%
      \fi%
    }%
    \backgroundpath{%
    \centerpoint\advance\pgf@y by\radius%
    \pgf@xa=\pgf@x \pgf@ya=\pgf@y%
    \centerpoint\advance\pgf@y by-\radius%
    \pgf@xb=\pgf@x \pgf@yb=\pgf@y%
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}%
    }%
}
\makeatother

\begin{document}
    \begin{tikzpicture}
    \node[circle player, draw=black] at (240pt,90pt) {};
    \end{tikzpicture}
\end{document}

答案2

我和 @percusse 有同样的疑问。假设您只想绘制一个从北到南的垂直线圆,这也可以完成工作。

\documentclass{standalone}
\usepackage{tikz}
\tikzset{circle player/.style={circle,append after command={%
\pgfextra{\draw (\tikzlastnode.north)--(\tikzlastnode.south);}}}}
\begin{document}
    \tikzset{leverage/.initial={}}
    \begin{tikzpicture}
    \node[circle player, draw=black] at (240,90) {};
    \end{tikzpicture}
\end{document}

并闪现出@percusse 的评论(谢谢!):

\documentclass{standalone}
\usepackage{tikz}
\tikzset{circle player/.style={circle,
path picture = {
\draw
(path picture bounding box.north) -- (path picture bounding box.south);
                                                   }}}
\begin{document}
    \tikzset{leverage/.initial={}}
    \begin{tikzpicture}
    \node[circle player, draw=blue] at (240,90) {};
    \end{tikzpicture}
\end{document}

答案3

根据其他人的观察,我能够使用以下代码解决我的问题。我不得不手动找到北方和南方,而我假设它们是保存的锚点。

\pgfdeclareshape{circle player}{
    \inheritsavedanchors[from=circle]
    \inheritanchorborder[from=circle]
    \inheritanchor[from=circle]{center}
    \inheritanchor[from=circle]{south}
    \inheritanchor[from=circle]{west}
    \inheritanchor[from=circle]{north}
    \inheritanchor[from=circle]{east}

    \inheritbackgroundpath[from=circle]

    \beforebackgroundpath{

        % get and set options
        \pgfkeys{/tikz/leverage/.get=\tmp}
        \expandafter\tikzset\expandafter{\tmp}
        \tikz@options

        % get the center and radius
        \radius \pgf@xa=\pgf@x
        \centerpoint \pgf@xb=\pgf@x \pgf@yb=\pgf@y

        % draw line from north to south
        \advance\pgf@yb by\pgf@xa
        \pgfpathmoveto{\pgfpoint{\pgf@xb}{\pgf@yb}}
        \advance\pgf@yb by -2\pgf@xa
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
        \pgfusepath{draw}
    }
}

谢谢!

相关内容