
Tikz possui vários componentes úteis de circuito digital, básicos ou complexos. Aqui, eu precisoalgunsde minha autoria, não necessariamente nem mesmo um dos convenientes. Mas vamos dar um exemplo bastante conveniente: um comparador de magnitude.
Eu gostaria de ter issocomparador de magnitudecomponente para minha tarefa, com suas portas de sinal definidas como anchor
s. Posso fazer uma caixa com etiquetas nas portas e um nome nela, mas isso éinsuficiente!
Preciso mostrar o que há por dentro também. Os detalhes não devem ultrapassar os portões, não quero os transistores por perto, mas preciso dos portões.
Aqui está o que tenho em mãos até agora, a maior parte apenas copiada/imitada deeste (famoso?) exemplo de flip-flop de dados:
\makeatletter
% Magnitude Comparator (magn comparator) shape
\pgfdeclareshape{magn comparator}
{
% The 'minimum width' and 'minimum height' keys, not the content, determine
% the size
\savedanchor\northeast
{%
\pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
\pgfmathsetlength\pgf@y{\pgfshapeminheight}%
\pgf@x=0.5\pgf@x
\pgf@y=0.5\pgf@y
}
% This is redundant, but makes some things easier:
\savedanchor\southwest
{%
\pgfmathsetlength\pgf@x{\pgfshapeminwidth}%
\pgfmathsetlength\pgf@y{\pgfshapeminheight}%
\pgf@x=-0.5\pgf@x
\pgf@y=-0.5\pgf@y
}
% Inherit from rectangle
\inheritanchorborder[from=rectangle]
% Define same anchor a normal rectangle has
\anchor{center}{\pgfpointorigin}
\anchor{north}{\northeast \pgf@x=0pt}
\anchor{east}{\northeast \pgf@y=0pt}
\anchor{south}{\southwest \pgf@x=0pt}
\anchor{west}{\southwest \pgf@y=0pt}
\anchor{north east}{\northeast}
\anchor{north west}{\northeast \pgf@x=-\pgf@x}
\anchor{south west}{\southwest}
\anchor{south east}{\southwest \pgf@x=-\pgf@x}
\anchor{text}
{
\pgfpointorigin
\advance\pgf@x by -.5\wd\pgfnodeparttextbox%
\advance\pgf@y by -.5\ht\pgfnodeparttextbox%
\advance\pgf@y by +.5\dp\pgfnodeparttextbox%
}
% Define anchors for input signal ports
\anchor{input gt}
{
\pgf@process{\southwest}%
\pgf@y=-.5\pgf@y%
}
\anchor{input eq}
{
\pgf@process{\southwest}%
\pgf@y=0pt%
}
\anchor{input lt}
{
\pgf@process{\southwest}%
\pgf@y=.5\pgf@y%
}
\anchor{input a}
{
\pgf@process{\northeast}%
\pgf@x=-.3\pgf@x%
}
\anchor{input b}
{
\pgf@process{\northeast}%
\pgf@x=.3\pgf@x%
}
% Define anchors for output signal ports
\anchor{output gt}
{
\pgf@process{\northeast}%
\pgf@y=.5\pgf@y%
}
\anchor{output eq}
{
\pgf@process{\northeast}%
\pgf@y=0pt%
}
\anchor{output lt}
{
\pgf@process{\northeast}%
\pgf@y=-.5\pgf@y%
}
% Draw the rectangle box and the port labels
\backgroundpath
{
% Rectangle box
\pgfpathrectanglecorners{\southwest}{\northeast}
% \node [and gate] (kek) at (0, 0) {};
}
}
% Define default style for this node
\tikzset
{
every magn comparator node/.style =
{
draw,
minimum width = 2cm,
minimum height = 2cm,
thick,
inner sep = 1mm,
outer sep = 0pt,
cap = round
}
}
\makeatother
Isso está em um arquivo separado que incluo no preâmbulo do meu arquivo LaTeX principal.
Não há portões aqui, apenas desenha a caixa. Tentei simplesmente colocar uma porta AND aleatória da maneira usual que faço fora dessa \pgfdeclareshape
coisa, o que obviamente não funcionou. Eu comentei isso, essa tentativa.
Deveria haver uma maneira de definir outras formas além das formas existentes. O que é?
Editar:Espero ter algo assim em minhas mãos, que devo ser capaz de colocar e portas que posso alcançar facilmente como âncoras, semelhante a uma porta AND/OR/NOR/XOR/NAND:
Observe que o interior da caixa não funciona realmente como um comparador de magnitude, é apenas um exemplo fictício do que espero.
Responder1
Dependendo da complexidade de seus casos de uso e de quantas dessas formas você precisa… aqui está um começo.
A resposta consiste no seguinte:
Uma declaração de forma que empresta a
rectangle ee
definição de (que é apenas uma formacircuits.ee
emprestada com e âncoras).rectangle
.input
.output
Eu também peguei emprestado do linkTeXamplepara o texto dentro da definição de uma forma. As âncoras são definidas com
\pgfpointlineattime
(isso é semelhante àpos
chave ao longo de uma linha reta ou ao fator dentrocalc
da($(<p1>)!<factor>!(<p2>)$)
notação).Se você tiver muito mais dessas formas que precisam de várias âncoras diferentes ao longo da borda de um retângulo, isso pode ser serializado com chaves fey e um loop dentro da declaração da forma. Isto também se aplica aos textos.
Agora que temos uma forma com âncoras e textos podemos utilizá-la. Para um formato de circuito adequado, declaramos um símbolo com
circuit declare symbol
e o configuramos comset <symbol name> graphic
.Os
circuit symbol size
conjuntos de teclasminimum width
eminimum height
em relação aocircuit symbol unit
(uma dimensão TeX sob o capô). Isso o torna escalável em relação a outros símbolos de circuito. Atransform shape
chave é necessária para fazê-lo girar ao longocircuits
dosto
caminhos.A
path picture
que usa código proposto deoutra resposta minha. Para configurar um sistema de coordenadas local que gira e é dimensionado com seu nó: A coordenada(0, 0)
está no centro do nó. Oxvetor aponta paraeast
(=output
), osimvetor para a âncora norte. Isso é importante para especificações de coordenadas,(left:.2)
pois usa.2
metade da dimensão horizontal do nóea rotação aplicada.Os símbolos do circuito dentro
path picture
obtêm as opçõesgray
(assim como as linhas) ecircuit symbol unit=.1cm
reduzem os símbolos para um tamanho apropriado. Pode ser necessário brincar com esse valor para obter o tamanho correto. Também pode ser possível tornar isso dependente do sistema de coordenadas locais mencionado acima com as dimensões\pgf@xx
e\pgf@yy
.Obviamente, se você precisar de vários símbolos com o mesmo layout de âncora e conexão, mas com portas diferentes, é possível tornar a definição das formas maleável de acordo com três chaves de valor que seriam definidas neste caso como
not gate
,nand gate
enor gate
.
Eu usei o meupaths.ortho
bibliotecapara as conexões dentro do path picture
. Obviamente, você pode usar qualquer maneira de conectar essas linhas.
Código
\documentclass[tikz]{standalone}
\usetikzlibrary{circuits.ee,circuits.logic.US,paths.ortho}
\makeatletter
\pgfdeclareshape{my complicated box}{%
\inheritsavedanchors[from=rectangle ee]
\inheritanchor[from=rectangle ee]{center}
\inheritanchor[from=rectangle ee]{north}
\inheritanchor[from=rectangle ee]{south}
\inheritanchor[from=rectangle ee]{east}
\inheritanchor[from=rectangle ee]{west}
\inheritanchor[from=rectangle ee]{north east}
\inheritanchor[from=rectangle ee]{north west}
\inheritanchor[from=rectangle ee]{south east}
\inheritanchor[from=rectangle ee]{south west}
\inheritanchor[from=rectangle ee]{input}
\inheritanchor[from=rectangle ee]{output}
\inheritanchorborder[from=rectangle ee]
\inheritbackgroundpath[from=rectangle ee]
\anchor{eq in} {\pgf@sh@reanchor{\pgf@sm@shape@name}{input}}
\anchor{eq out}{\pgf@sh@reanchor{\pgf@sm@shape@name}{output}}
\anchor{lt in}{%
\pgfpointlineattime{.2}{\southwest}
{\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}}
\anchor{gt in}{%
\pgfpointlineattime{.8}{\southwest}
{\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}}
\anchor{gt out}{%
\pgfpointlineattime{.3}{\northeast}
{\southwest\pgf@yc\pgf@y\northeast\pgf@y\pgf@yc}}
\anchor{lt out}{%
\pgfpointlineattime{.7}{\northeast}
{\southwest\pgf@yc\pgf@y\northeast\pgf@y\pgf@yc}}
\anchor{a}{%
\pgfpointlineattime{.4}
{\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}{\northeast}}
\anchor{b}{%
\pgfpointlineattime{.6}
{\southwest\pgf@xc\pgf@x\northeast\pgf@x\pgf@xc}{\northeast}}
\beforebackgroundpath{%
\begingroup
\tikzset{my complicated box/labels/.try}\tikz@textfont
\pgf@sh@reanchor{\pgf@sm@shape@name}{eq in}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{eq}_{\mathrm{in}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{eq out}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{eq}_{\mathrm{out}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{gt in}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{gt}_{\mathrm{in}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{gt out}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{gt}_{\mathrm{out}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{lt in}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},left,%
x=\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{lt}_{\mathrm{in}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{lt out}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},right,%
x=-\pgfkeysvalueof{/pgf/inner xsep}]{$\mathrm{lt}_{\mathrm{out}}$}
\pgf@sh@reanchor{\pgf@sm@shape@name}{a}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},top,%
y=-\pgfkeysvalueof{/pgf/inner ysep}]{a\vphantom{b}}
\pgf@sh@reanchor{\pgf@sm@shape@name}{b}
\pgftext[at=\pgfqpoint{\pgf@x}{\pgf@y},top,%
y=-\pgfkeysvalueof{/pgf/inner ysep}]{b}
\endgroup}
}
\makeatother
\tikzset{my complicated box/labels/.style={font=\footnotesize, inner sep=.1667em}}
\tikzset{
circuit declare symbol=my complicated symbol,
set my complicated symbol graphic={
draw, shape=my complicated box, circuit symbol size=width 10 height 8,
transform shape,
path picture={
\expandafter\let\expandafter\tfn\csname tikz@fig@name\endcsname
\pgftransformshift{\pgfpointanchor{\tfn}{center}}%
\pgfsetxvec{\pgfpointdiff{\pgfpointanchor{\tfn}{center}}
{\pgfpointanchor{\tfn}{east}}}%
\pgfsetyvec{\pgfpointdiff{\pgfpointanchor{\tfn}{center}}
{\pgfpointanchor{\tfn}{north}}}
\tikzset{every circuit symbol/.append style={circuit symbol unit=.1cm, gray}}
\path[thin, draw=gray]
(\tfn.eq in) to[not gate=near end] (\tfn.eq out)
(\tfn.lt out) to ++ (left:.2)
node[anchor=output, logic gate inputs=nn, nand gate] (\tfn-nand) {}
(\tfn-nand.input 2) to[-|-=.6] (\tfn.lt in)
(\tfn-nand.input 1) to[-|] (\tfn.a)
(\tfn.gt out) to ++ (left:.2)
node[anchor=output, logic gate inputs=nn, nor gate] (\tfn-nor) {}
(\tfn-nor.input 2) to[-|-=.6] (\tfn.gt in)
(\tfn-nor.input 1) to[-|] (\tfn.b);
}},
}
\begin{document}
\begin{tikzpicture}[circuit logic US]
\draw (0,0) to[my complicated symbol] ++ (30:4);
\end{tikzpicture}
\end{document}
Saída
Responder2
Uma possível solução com pics
. É difícil de usar pic-anchors
para posicionamento (Ancorando fotos TiKZ), mas servem como pontos de referência para estabelecer ligações entre eles.
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning,circuits.logic.US, fit}
\tikzset{
mycircuit/.pic={
\begin{scope}[circuit logic US]
\node[gray, thick, draw, nor gate] (-gt) at (2,0.75) {};
\node[gray, thick, draw, not gate] (-eq) at (2,0) {};
\node[gray, thick, draw, nand gate] (-lt) at (2,-0.75) {};
\draw[gray] (-gt.output)--++(3mm,0)
coordinate[label={[black]left:$\mathrm{gt}_\mathrm{out}$}] (-gtout);
\draw[gray] (-eq.output)--(-eq.output-|-gtout)
coordinate[label={[black]left:$\mathrm{eq}_\mathrm{out}$}] (-eqout);
\draw[gray] (-lt.output)--(-lt.output-|-gtout)
coordinate[label={[black]left:$\mathrm{lt}_\mathrm{out}$}] (-eqout);
\draw[gray] (-gt.input 1)-|++(-3mm,.5cm)
coordinate[label={[black]below:$\mathrm{b}$}] (-b);
\draw[gray] (-lt.input 1)-|([xshift=-6mm]-b.center)
coordinate[label={[black]below:$\mathrm{a}$}] (-a);
\draw[gray] (-eq.input)--++(-2cm,0)
coordinate[label={[black]right:$\mathrm{eq}_\mathrm{in}$}] (-eqin);
\draw[gray] (-gt.input 2)--++(-1.2cm,0) |- ([yshift=1cm]-eqin.center)
coordinate[label={[black]right:$\mathrm{gt}_\mathrm{in}$}] (-gtin);
\draw[gray] (-lt.input 2)--++(-1.2cm,0) |- ([yshift=-1cm]-eqin.center)
coordinate[label={[black]right:$\mathrm{lt}_\mathrm{in}$}] (-ltin);
\node[draw, fit={(-ltin) (-b) ([yshift=-.5cm]-lt.input 2) (-gtout)},
inner sep=0pt] (-box) {};
\end{scope}
}}
\begin{document}
\begin{tikzpicture}
\pic (a) at (0,0) {mycircuit};
\pic (b) at (5,1) {mycircuit};
\draw (a-gtout) -- (b-gtin);
\draw ([yshift=2cm]a-a) coordinate (aux)--(a-a);
\draw ([yshift=-5mm]aux)-|(b-a);
\end{tikzpicture}
\end{document}