![锚点和 pgfkeys 的问题](https://linux22.com/image/391463/%E9%94%9A%E7%82%B9%E5%92%8C%20pgfkeys%20%E7%9A%84%E9%97%AE%E9%A2%98.png)
在如何正确地将新选项应用于 makeshape 包的 \pgfdeclareshape\ifx
我在包含其中时遇到了问题\pgfdeclareshape
,已由@marmot 解决。
目前,我正尝试使用 来包含选项。但是,现在在 中工作时,\pgfkeys
我无法检测到 中的选项。\anchor
\setpath
这里是代码:
\documentclass[a4paper,10pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{valvula.tex}
\makeatletter
% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.
\def\gap{0mm}
\newdimen\radio@llave \radio@llave=2mm
\newdimen\x@llave \x@llave=1.5mm
\newdimen\y@llave \y@llave=1.32mm
\def\f@maniv{0.9} % Proporción de la longitud de la manivela
\pgfkeys{ % Colores de las mariposas de las válvulas:
/tikz/.cd,
color izquierda/.initial=\pgfutil@empty,
color derecha/.initial=\pgfutil@empty,
}
\pgfkeys{
/tikz/posicion manivela/.is choice,
/tikz/posicion manivela/izquierda/.code={\def\pos@manivela{-1}},
/tikz/posicion manivela/derecha/.code={\def\pos@manivela{1}}
}
%% Anchor path:
\def\generalanchor{} % No es necesario, el nodo no llevará texto.
%% Background path:
\def\valvulaborder{ % Obtiene la caja de texto correcta:
% La parte anterior no es necesaria, no llevará texto el nodo
% Triángulo izquierdo:
%
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
\pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
\pgfpathclose
%\typeout{\tikz@fillcolor}
%\typein{}
\edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color izquierda}}
\ifx\pgfutil@tmpa\empty
\ifx\tikz@fillcolor\empty
\pgfusepath{stroke}
\else
\pgfusepath{fill,stroke}
\fi
\else
\pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
\pgfusepath{fill,stroke}
\fi
%
% Triángulo derecho:
%
%\typeout{derecha\pgfkeysvalueof{/tikz/color derecha}}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
\pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
\pgfpathclose
\edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color derecha}}
\ifx\pgfutil@tmpa\pgfutil@empty
\ifx\tikz@fillcolor\empty
\pgfusepath{stroke}
\else
\pgfsetfillcolor{\tikz@fillcolor}
\pgfusepath{fill,stroke}
\fi
\else
\pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
\pgfusepath{fill,stroke}
\fi
}
%% Declaración de la forma:
\pgfdeclareshape{valvula de esfera}{
\setpaths{\generalanchor}{%
\valvulaborder
% La manivela de la válvula:
\pgfpathmoveto{\pgfpoint{0em}{0em}}
\pgfpathlineto{\pgfpoint{0em}{\radio@llave}}
\ifnum\pos@manivela=-1 % a izquierda
\pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
\pgfpathlineto{\pgfpoint{-\f@maniv\x@llave}{\radio@llave}}
\else % a derecha
\pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
\pgfpathlineto{\pgfpoint{ \f@maniv\x@llave}{\radio@llave}}
\fi
}
\savedanchor{\centerpoint}{
\pgf@x = \ctbnex
\pgf@y = \ctbney
\advance\pgf@x by \gap
\advance\pgf@y by \gap
\mincorrect{\pgf@x}{\pgfshapeminwidth}
\mincorrect{\pgf@y}{\pgfshapeminheight}
\advance\pgf@x\pgfshapeouterxsep
\advance\pgf@y\pgfshapeouterysep
}
\inheritsavedanchors[from=valvula]
\inheritanchorborder[from=valvula]
\inheritanchor[from=valvula]{c}
\inheritanchor[from=valvula]{ur}
\inheritanchor[from=valvula]{r}
\inheritanchor[from=valvula]{dr}
\inheritanchor[from=valvula]{dl}
\inheritanchor[from=valvula]{l}
\inheritanchor[from=valvula]{ul}
% De la manivela de la válvula
\anchor{tc}{\centerpoint \pgf@x=0\pgf@x \pgf@y=\radio@llave}
\anchor{tm}{\ifnum\pos@manivela=-1 % a izquierda
\centerpoint \pgf@x=-\f@maniv\x@llave \pgf@y=\radio@llave
\else
\centerpoint \pgf@x= \f@maniv\x@llave \pgf@y=\radio@llave
\fi}
}
\makeatother
\end{filecontents*}
\usepackage{tikz}
\usepackage{makeshape}
\tikzset{
st texto/.style={
font=\sffamily\footnotesize,
circle,black,fill=white,inner sep=0.1em
},
st valvula/.style={
draw=blue,minimum width=6mm,minimum height=3mm,line width=0.2mm
},
st linea nodo/.style={line width=0.1mm,latex-,orange}
}
\input{valvula.tex}
\begin{document}
\begin{tikzpicture}[
x=1mm,y=1mm,remember picture, overlay,shift={(current page.center)}
]
\begin{scope}[shift={(0,0)}]
\node[%
valvula de esfera,st valvula,posicion manivela=izquierda,
color izquierda=yellow!50,color derecha=cyan!25
] (v3) at (0,0) {};
\draw[st linea nodo] (v3.tc) -- ++(90:10) node[st texto] {tc};
\draw[st linea nodo] (v3.tm) -- ++(110:10) node[st texto] {tm};
\end{scope}
\begin{scope}[shift={(50,0)},posicion manivela=derecha]
\node[%
valvula de esfera,st valvula,
color izquierda=yellow!50,color derecha=cyan!25
] (v4) at (0,0) {};
\draw[st linea nodo] (v4.tc) -- ++(90:10) node[st texto] {tc};
\draw[st linea nodo] (v4.tm) -- ++(70:10) node[st texto] (ntm) {tm};
%
\node[above of= ntm,red,align=center] (comentm) {Here tm should\\ be at right};
\path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);
\end{scope}
\end{tikzpicture}
\end{document}
我收到以下错误:
! Undefined control sequence. \pgf@anchor@valvula de esfera@tm ...\pos@manivela
我非常困惑。请问有人能帮我吗?我要放弃所有这些。
答案1
这是另一个建议,其中的键不是全局的。我留下了一些\typeout
s,以便指示调试此类代码的可能方法。
\documentclass[a4paper,10pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{valvula.tex}
\makeatletter
% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.
\def\gap{0mm}
\newdimen\radio@llave \radio@llave=2mm
\newdimen\x@llave \x@llave=1.5mm
\newdimen\y@llave \y@llave=1.32mm
\def\f@maniv{0.9} % Proporción de la longitud de la manivela
\pgfkeys{ % Colores de las mariposas de las válvulas:
/tikz/.cd,
color izquierda/.initial=\pgfutil@empty,
color derecha/.initial=\pgfutil@empty,
}
\pgfkeys{
/tikz/posicion manivela/.is choice,
/tikz/posicion manivela/izquierda/.code={\tikzset{posicion manivela value=-1}},
/tikz/posicion manivela/derecha/.code={\tikzset{posicion manivela value=1}},
/tikz/posicion manivela value/.initial=-1
%/tikz/posicion manivela/.default=izquierda
}
%% Anchor path:
\def\generalanchor{} % No es necesario, el nodo no llevará texto.
%% Background path:
\def\valvulaborder{ % Obtiene la caja de texto correcta:
% La parte anterior no es necesaria, no llevará texto el nodo
% Triángulo izquierdo:
%
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
\pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
\pgfpathclose
%\typeout{\tikz@fillcolor}
%\typein{}
\edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color izquierda}}
\ifx\pgfutil@tmpa\empty
\ifx\tikz@fillcolor\empty
\pgfusepath{stroke}
\else
\pgfusepath{fill,stroke}
\fi
\else
\pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
\pgfusepath{fill,stroke}
\fi
%
% Triángulo derecho:
%
%\typeout{derecha\pgfkeysvalueof{/tikz/color derecha}}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
\pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
\pgfpathclose
\edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color derecha}}
\ifx\pgfutil@tmpa\pgfutil@empty
\ifx\tikz@fillcolor\empty
\pgfusepath{stroke}
\else
\pgfsetfillcolor{\tikz@fillcolor}
\pgfusepath{fill,stroke}
\fi
\else
\pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
\pgfusepath{fill,stroke}
\fi
}
%% Declaración de la forma:
\pgfdeclareshape{valvula de esfera}{
\setpaths{\generalanchor}{%
\valvulaborder
% La manivela de la válvula:
\pgfpathmoveto{\pgfpoint{0em}{0em}}
\pgfpathlineto{\pgfpoint{0em}{\radio@llave}}
\typeout{\pgfkeysvalueof{/tikz/posicion manivela value}}
\ifnum\pgfkeysvalueof{/tikz/posicion manivela value}=-1 % a izquierda
\typeout{\pgfkeysvalueof{/tikz/posicion manivela value} worked}
\pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
\pgfpathlineto{\pgfpoint{-\f@maniv\x@llave}{\radio@llave}}
\else % a derecha
\pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
\pgfpathlineto{\pgfpoint{ \f@maniv\x@llave}{\radio@llave}}
\fi
}
\savedanchor{\centerpoint}{
\pgf@x = \ctbnex
\pgf@y = \ctbney
\advance\pgf@x by \gap
\advance\pgf@y by \gap
\mincorrect{\pgf@x}{\pgfshapeminwidth}
\mincorrect{\pgf@y}{\pgfshapeminheight}
\advance\pgf@x\pgfshapeouterxsep
\advance\pgf@y\pgfshapeouterysep
}
\inheritsavedanchors[from=valvula]
\inheritanchorborder[from=valvula]
\inheritanchor[from=valvula]{c}
\inheritanchor[from=valvula]{ur}
\inheritanchor[from=valvula]{r}
\inheritanchor[from=valvula]{dr}
\inheritanchor[from=valvula]{dl}
\inheritanchor[from=valvula]{l}
\inheritanchor[from=valvula]{ul}
% De la manivela de la válvula
\anchor{tc}{\centerpoint \pgf@x=0\pgf@x \pgf@y=\radio@llave}
\anchor{tm}{\typeout{\pgfkeysvalueof{/tikz/posicion manivela value}}
\ifnum\pgfkeysvalueof{/tikz/posicion manivela value}=-1 % a izquierda
\typeout{\pgfkeysvalueof{/tikz/posicion manivela value} worked}
\centerpoint \pgf@x=-\f@maniv\x@llave \pgf@y=\radio@llave
\else
\centerpoint \pgf@x= \f@maniv\x@llave \pgf@y=\radio@llave
\fi}
}
\makeatother
\end{filecontents*}
\usepackage{tikz}
\usepackage{makeshape}
\tikzset{
st texto/.style={
font=\sffamily\footnotesize,
circle,black,fill=white,inner sep=0.1em
},
st valvula/.style={
draw=blue,minimum width=6mm,minimum height=3mm,line width=0.2mm
},
st linea nodo/.style={line width=0.1mm,latex-,orange}
}
\input{valvula.tex}
\begin{document}
\begin{tikzpicture}[
x=1mm,y=1mm,remember picture, overlay,shift={(current page.center)}
]
\begin{scope}[shift={(0,0)}]
\node[%
valvula de esfera,st valvula,posicion manivela=izquierda,
color izquierda=yellow!50,color derecha=cyan!25
] (v3) at (0,0) {};
\draw[st linea nodo] (v3.tc) -- ++(90:10) node[st texto] {tc};
\draw[st linea nodo] (v3.tm) -- ++(110:10) node[st texto] {tm};
\end{scope}
\begin{scope}[shift={(50,0)},posicion manivela=derecha]
\node[%
valvula de esfera,st valvula,
color izquierda=yellow!50,color derecha=cyan!25
] (v4) at (0,0) {};
\draw[st linea nodo] (v4.tc) -- ++(90:10) node[st texto] {tc};
\draw[st linea nodo] (v4.tm) -- ++(70:10) node[st texto] (ntm) {tm};
%
\node[above of= ntm,red,align=center] (comentm) {Here tm should\\ be at right};
%\path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);
\end{scope}
\end{tikzpicture}
\end{document}
最后一行\path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);
似乎需要一个锚点,tr
但据我所知,该锚点尚未定义。
答案2
我找到了解决方案。非常简单。我有点茫然,但最后我能够清晰地思考。
我已经替换了
\pgfkeys{
/tikz/posicion manivela/.is choice,
/tikz/posicion manivela/izquierda/.code={\def\pos@manivela{-1}},
/tikz/posicion manivela/derecha/.code={\def\pos@manivela{1}}
}
经过
\pgfkeys{
/tikz/posicion manivela/.is choice,
/tikz/posicion manivela/izquierda/.code={\xdef\pos@manivela{-1}},
/tikz/posicion manivela/derecha/.code={\xdef\pos@manivela{1}}
}
现在它正在工作。