%20como%20se%20fosse%20um%20n%C3%B3.png)
Estou confuso sobre as fotos do tikz. Posso defini-los livremente sem problemas e até mesmo adicionar coordenadas internas que estarão disponíveis por herança de nome, como (-A)
por exemplo em \pic (S) at (0,0) {myPic}; \draw (S-A) -- ++(0,0);
. Tudo isso está documentado por volta da p. 255 do manual pgf.
Porém não entendo porque não é possível dar um nome a uma foto como a acima se nenhuma coordenada estiver definida dentro dela. Por padrão, seria ótimo se pudesse se comportar como um nó 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}
O ponto principal é que estou trabalhando em uma biblioteca de blocos de controle (para que possamos interromper o bate-papo abaixo com @Alenanno). Por exemplo, aqui está a definição de um 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] {};
},
},
}
Responder1
Existe um truque que pode ser usado em algumas circunstâncias que explora o fato de que a pic
é colocado dentro de a scope
que pode ser nomeado com a local bounding box
chave. Observe que isso não funcionará em árvores ou 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}
Também é possível usar o nome dado pic
ao definindo uma chave "wrapper" que adiciona explicitamente um escopo ao 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}
O resultado é o mesmo de antes.
Responder2
DeManual Pgf (versão 3.0.0), página 252:
Ao contrário dos nós, as fotos não podem ser referenciadas posteriormente. Você pode fazer referência a nós que estão dentro de uma foto, mas não “à foto em si”. Em particular, você não pode desenhar linhas entre fotos da mesma forma que pode desenhá-las entre nós. Em geral, sempre que faz sentido que algum desenho possa ser conectado a outras coisas semelhantes a nós, então um nó é melhor que uma foto.
Se pics forem usados para emular todo o poder de um nó (o que é possível, em princípio), eles serão mais lentos para construir e ocuparão mais memória do que um nó que obtenha o mesmo efeito.
Portanto, se você estiver fazendo algo que um nó faz bem e não houver nenhum motivo específico para usá-lo pic
, é melhor usar um nó. Há uma solução alternativa na resposta à pergunta "Como dar um nome para \pic", mas é exatamente isso, uma solução alternativa.
No entanto, se você quiser posicionar nós em torno de outro nó, você pode verificar esta pergunta que fiz há algum tempo (Como posicionar nós em torno de outro nó no TiKZ?) ou você usa um foreach Tikz com um nó regular.
Resposta atualizada
Agora que sei o que você precisa, aqui está uma solução com o Tikz. O novo comando \mySumn
(você pode renomeá-lo) leva dois argumentos como \mySumn{#1}{#2}
, onde #1
é o nome do nó e #2
é a posição.
Tentei adicionar um argumento opcional usando, above of
mas não tive sucesso. No entanto, você pode fazer o mesmo com este código, mas de uma maneira diferente. Considere o seguinte:
\mySumn{p1}{0,0};
\mySumn{p2}{$(p1.north east)+(1em,1em)$};
Ele colocará um nó p1
nas coordenadas (0,0)
e, em seguida, colocará outro nó p2
no nordeste +1em de p1 nos eixos xey (diagonalmente acima à direita).
É claro que você ainda pode desenhar arestas de um nó para outro.
Saída
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}
Responder3
Pergunta antiga, mas não fiquei satisfeito com a local bounding box
solução pois não consegui encontrar uma forma de ter um controle melhor sobre ela (distância do conteúdo interno, por exemplo).
Minha solução foi usar uma imagem aninhada no pic
, junto com a remember picture
opção. Os nomes são passados como argumentos em cascata. Com isso, você pode não apenas referenciar o pic
como um nó (porque na verdade é um nó), mas também referenciar seu conteúdo.
Outro ponto é que com essa solução o conteúdo de a pic
fica sempre centralizado, o que também era o que eu procurava ao trabalhar nesse código.
Estar ciente:
- você tem que compilar o documento duas vezes por causa de
remember picture
. - nós aninhados podem ser complicados por causa da herança.
Aqui está o 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}
Responder4
Parece que se eu definir um comando como para o meu 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] {};
}
}
É então possível criar um nó que contenha uma foto falsa, pois o que está acima é exatamente o que se usaria para definir uma foto.
\node (1) at (0,0) {\bOp{+,-,,}};
\draw (4,0) -- (1);