锚点和 pgfkeys 的问题

锚点和 pgfkeys 的问题

如何正确地将新选项应用于 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

这是另一个建议,其中的键不是全局的。我留下了一些\typeouts,以便指示调试此类代码的可能方法。

\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}}
}

现在它正在工作。

相关内容