我正在编写一个简单的包来定义我在工作中经常做的一些绘图任务。有许多符号经常被重复使用,我想将它们添加为自定义节点。我看过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}
}
}
谢谢!