%20como%20si%20fuera%20un%20nodo.png)
Estoy confundido acerca de las fotos tikz. Puedo definirlos libremente sin problemas, e incluso agregar coordenadas dentro que estarán disponibles por herencia de nombres, como (-A)
por ejemplo en \pic (S) at (0,0) {myPic}; \draw (S-A) -- ++(0,0);
. Todo esto está documentado alrededor de la p. 255 del manual de páginas.
Sin embargo, no entiendo por qué no es posible darle un nombre a una imagen como la de arriba si no se define ninguna coordenada en su interior. Por defecto, sería fantástico si pudiera comportarse como un nodo normal.
MWE:
\documentclass{minimal}
\usepackage{tikz}
\tikzset{
myBlock/.pic = {
\node[draw,minimum width=1cm,minimum height=0.5cm] at (0,0) {};
},
myBlockNamed/.pic = {
\node[draw,minimum height=1cm,minimum width=0.5cm] (-m) at (0,0) {};
},
}
\begin{document}
\begin{tikzpicture}
\pic () at (0,0) {myBock}; % can't give it a name
\pic (S) at (3,0) {myBlockNamed}; % can give it a name
\draw (S-A) -- ++(2,0);
\end{tikzpicture}
\end{document}
El punto subyacente es que estoy trabajando en una biblioteca de bloques de control (para que podamos detener el chat a continuación con @Alenanno). Por ejemplo, aquí está la definición de un operador matemático.
\tikzset{
mySum background/.style = {
circle, minimum size=1.5em, fill=white,
},
mySum edge/.style = {
draw=black, circle, minimum size=1.5em, line width=.5pt,
},
pics/bOp/.style = {
code = {
\node [mySum background] {};
\foreach \t [count=\i] in {#1}{
\pgfmathsetmacro{\angle}{\i*90}
\node[anchor=center, font=\tiny] at (\angle:0.45em) {$\t$};
}
\node [mySum edge] {};
},
},
}
Respuesta1
Hay un truco que se puede utilizar en algunas circunstancias y que aprovecha el hecho de que a pic
se coloca dentro de a scope
y se puede nombrar con la local bounding box
clave. Tenga en cuenta que esto no funcionará en árboles o gráficos.
\documentclass[tikz,border=5]{standalone}
\tikzset{pics/.cd,
pic a/.style={code={
\node [fill=red!20, shape=circle] {A};
}}
}
\begin{document}
\begin{tikzpicture}
\pic [local bounding box=A1] at (0,0) {pic a};
\pic [local bounding box=A2] at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
\draw [red, ->] (\i:1) -- (A1);
\draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}
También es posible utilizar el nombre dado al pic
definiendo una clave "contenedora" que agrega explícitamente un alcance al código:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{fit}%
\makeatletter
\tikzset{pics/named scope code/.style={code={\tikz@fig@mustbenamed%
\begin{scope}[local bounding box/.expanded=\tikz@fig@name]#1\end{scope}%
}}}
\makeatother
\tikzset{pics/.cd,
pic a/.style={named scope code={
\node [fill=red!20, shape=circle] {A};
}}
}
\begin{document}
\begin{tikzpicture}
\pic (A1) at (0,0) {pic a};
\pic (A2) at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
\draw [red, ->] (\i:1) -- (A1);
\draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}
El resultado es el mismo que antes.
Respuesta2
Desde elManual Pgf (versión 3.0.0), página 252:
A diferencia de los nodos, no se puede hacer referencia a las fotografías más adelante. Puedes hacer referencia a nodos que están dentro de una imagen, pero no a “la imagen en sí”. En particular, no puedes dibujar líneas entre imágenes de la misma manera que puedes dibujarlas entre nodos. En general, siempre que tenga sentido que algún dibujo pueda conectarse con otras cosas parecidas a nodos, entonces un nodo es mejor que una imagen.
Si se utilizan imágenes para emular toda la potencia de un nodo (lo cual es posible, en principio), su construcción será más lenta y consumirán más memoria que un nodo que logre el mismo efecto.
Entonces, si estás haciendo algo que un nodo hace bien y no hay ninguna razón particular para usar pic
, es mejor que uses un nodo. Hay una solución alternativa en la respuesta a la pregunta "Cómo darle un nombre a \pic", pero es exactamente eso, una solución alternativa.
Sin embargo, si desea poder colocar nodos alrededor de otro nodo, puede consultar esta pregunta que hice hace algún tiempo (¿Cómo colocar nodos alrededor de otro nodo en TiKZ?) o usas un Tikz foreach con un nodo normal.
Respuesta actualizada
Ahora que sé lo que necesitas, aquí tienes una solución con Tikz. El nuevo comando \mySumn
(puede cambiarle el nombre) toma dos argumentos como \mySumn{#1}{#2}
, donde #1
está el nombre del nodo y #2
es la posición.
Intenté agregar un argumento opcional usando above of
pero no lo logré. Sin embargo puedes hacer lo mismo con este código pero de forma diferente. Considera lo siguiente:
\mySumn{p1}{0,0};
\mySumn{p2}{$(p1.north east)+(1em,1em)$};
Colocará un nodo p1
en las coordenadas (0,0)
y luego colocará otro nodo p2
en el noreste de p1 +1em en los ejes xey (en diagonal arriba a la derecha).
Por supuesto, aún puedes dibujar bordes de un nodo al otro.
Producción
Código
\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usepackage{xparse}
\usetikzlibrary{calc,arrows.meta,positioning}
\tikzset{
mySumbk/.style = {
draw, circle, minimum size=1.5em, fill=white,
},
}
\newcommand{\mySumn}[2]{
\node[mySumbk,fill=white] (#1) at (#2) {};
\foreach \angle/\maop in {
90/+,
180/-
}{
\node[anchor=center, font=\tiny] at ($(#1)+(\angle:.45em)$) {$\maop$};
}}
\begin{document}
\begin{tikzpicture}[>=latex]
\mySumn{p1}{0,0};
\mySumn{p2}{$(p1.north east)+(1em,1em)$};
\draw (p1) -- (3,0);
\draw (p1) edge[out=90,in=180] (p2);
\end{tikzpicture}
\end{document}
Respuesta3
Antigua pregunta, pero no estaba contento con la local bounding box
solución ya que no pude encontrar una manera de tener un mejor control sobre ella (distancia al contenido interno, por ejemplo).
Mi solución fue utilizar una imagen anidada en el archivo pic
, junto con la remember picture
opción. Los nombres se pasan como argumentos en forma de cascada. Con esto, no sólo puedes hacer referencia a pic
como un nodo (porque en realidad es un nodo) sino también hacer referencia a su contenido.
Otro punto es que con esta solución el contenido de a pic
siempre está centralizado, que también era lo que buscaba cuando trabajaba en este código.
Tenga en cuenta:
- Tienes que compilar el documento dos veces debido a
remember picture
. - Los nodos anidados pueden ser complicados debido a la herencia.
Aquí está el código:
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[remember picture]
\tikzset{
mine/.pic={
\node[draw](#1){
\begin{tikzpicture}[remember picture]
\node[draw](#1-1){#1-1};
\node[draw, right=of #1-1](#1-2){#1-2};
\end{tikzpicture}
};
},
}
\pic{mine=a};
\pic[right=of a]{mine=b};
\draw[thick, blue, <->](a-1)to[out=90, in=90](b-1);
\draw[thick, blue, <->](a-2)to[out=-90, in=-90](b-2);
\draw[thick, red](a)to(b);
\end{tikzpicture}
\end{document}
Respuesta4
Parece que si defino un comando como para mi operador:
\tikzset{
mySum background/.style = {
circle, minimum size=1.5em, fill=white,
},
mySum edge/.style = {
draw=black, circle, minimum size=1.5em, line width=.5pt,
},
}
\newcommand{\bOp}[1]{
\tikz[outer sep=0pt]{
\node [mySum background] {};
\foreach \t [count=\i] in {#1}{
\pgfmathsetmacro{\angle}{\i*90}
\node[anchor=center, font=\tiny] at (\angle:0.45em) {$\t$};
}
\node [mySum edge] {};
}
}
Entonces es posible crear un nodo que contenga una imagen falsa, ya que lo que está arriba es exactamente lo que se usaría para definir una imagen.
\node (1) at (0,0) {\bOp{+,-,,}};
\draw (4,0) -- (1);