Problemas con anclajes y pgfkeys

Problemas con anclajes y pgfkeys

EnCómo utilizar correctamente nuevas opciones en \pgfdeclareshape del paquete makeshapeTuve un problema al incluirlo \ifxy \pgfdeclareshapelo resolvió @marmot.

En este momento, estoy intentando incluir opciones usando \pgfkeys. Sin embargo, ahora no puedo detectar opciones en \anchor, mientras trabajo en \setpath.

Aquí el código:

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

Obtuve el siguiente error:

! Undefined control sequence.
\pgf@anchor@valvula de esfera@tm ...\pos@manivela

Estoy extremadamente confundido. ¿Me puede ayudar alguien, por favor? Voy a renunciar a todo esto.

Respuesta1

He aquí otra propuesta en la que las claves no se globalizan. Dejé algunos \typeoutmensajes para indicar una posible forma de depurar dichos códigos.

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

La última línea \path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);parece requerir un ancla trque, por lo que puedo ver, no está definida.

ingrese la descripción de la imagen aquí

Respuesta2

He encontrado la solución. Fue muy facil. Estaba un poco aturdido pero al final pude pensar con claridad.

he sustituido

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\def\pos@manivela{-1}},
    /tikz/posicion manivela/derecha/.code={\def\pos@manivela{1}}
}

por

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\xdef\pos@manivela{-1}},
    /tikz/posicion manivela/derecha/.code={\xdef\pos@manivela{1}}
}

y ahora está funcionando.

información relacionada