
Tikz hat eine Reihe nützlicher digitaler Schaltkreiskomponenten, ob einfach oder komplex. Hier brauche ichmanchevon mir, nicht unbedingt eines der bequemen. Aber nehmen wir ein ziemlich bequemes Beispiel: einen Größenkomparator.
Das hätte ich gerneMagnitudenkomparatorKomponente für meine Aufgabe, mit seinen Signal-Ports definiert als anchor
s. Ich kann eine Box mit Beschriftungen auf den Ports und einem Namen darauf erstellen, aber das istnicht genug!
Ich muss auch zeigen, was im Inneren ist. Details dürfen nicht über die Gates hinausgehen, ich möchte die Transistoren nicht herumliegen haben, aber ich brauche die Gates.
Hier ist, was ich bisher in meinen Händen habe, das meiste davon ist nur kopiert/nachgeahmt vondieses (berühmte?) Daten-Flip-Flop-Beispiel:
\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
Dies befindet sich in einer separaten Datei, die ich in die Präambel meiner Haupt-LaTeX-Datei einfüge.
Hier gibt es keine Gatter, es wird nur die Box gezeichnet. Ich habe versucht, einfach ein zufälliges UND-Gatter zu setzen, so wie ich es außerhalb dieses \pgfdeclareshape
Dings normalerweise mache, was natürlich nicht funktioniert hat. Ich habe diesen Versuch auskommentiert.
Es sollte eine Möglichkeit für mich geben, über den vorhandenen Formen weitere Formen zu definieren. Wie sieht diese Möglichkeit aus?
Bearbeiten:Ich gehe davon aus, dass ich so etwas in den Händen halten werde, was ich platzieren können sollte und dessen Ports ich leicht als Anker erreichen kann, ähnlich wie es bei einem AND/OR/NOR/XOR/NAND-Gatter der Fall ist:
Beachten Sie, dass das Innere der Box nicht wirklich als Größenkomparator fungiert, sondern nur ein Blindbeispiel meiner Erwartung ist.
Antwort1
Abhängig von der Komplexität Ihrer Anwendungsfälle und davon, wie viele dieser Formen Sie benötigen … hier ist ein Anfang.
Die Antwort lautet wie folgt:
Eine Formdeklaration, die die
rectangle ee
Definition voncircuits.ee
(was lediglich eine geliehenerectangle
Form mit.input
und.output
Ankern ist) übernimmt.Ich leihe mir auch den verlinktenTeXamplefür den Text innerhalb der Definition einer Form. Die Anker werden mit gesetzt
\pgfpointlineattime
(ähnlich der Notationpos
„Schlüssel entlang einer geraden Linie“ oder „Faktor innerhalbcalc
“($(<p1>)!<factor>!(<p2>)$)
).Wenn Sie viele dieser Formen haben, die mehrere verschiedene dieser Anker entlang der Grenzen eines Rechtecks benötigen, kann dies mit einem Fey-Schlüssel und einer Schleife innerhalb der Deklaration der Form serialisiert werden. Dies gilt auch für die Texte.
Jetzt, da wir eine Form mit Ankern und Texten haben, können wir sie verwenden. Für eine richtige Schaltkreisform deklarieren wir ein Symbol mit
circuit declare symbol
und richten es mit einset <symbol name> graphic
.Die Schlüsselsätze
circuit symbol size
undminimum width
inminimum height
Bezug aufcircuit symbol unit
(eine TeX-Dimension unter der Haube). Dies macht es skalierbar in Bezug auf andere Schaltsymbole. Dertransform shape
Schlüssel wird benötigt, um es entlangcircuits
'to
Pfaden rotieren zu lassen.A
path picture
, das vorgeschlagenen Code verwendet vonnoch eine Antwort von mir. So richten Sie ein lokales Koordinatensystem ein, das mit seinem Knoten rotiert und skaliert: Die Koordinate(0, 0)
befindet sich im Mittelpunkt des Knotens.XVektor zeigt aufeast
(=output
), diejVektor zum Nordanker. Dies ist wichtig für Koordinatenangaben wie, da es die Hälfte der horizontalen Dimension des Knotens(left:.2)
verwendet.2
Unddie angewandte Drehung.Die Schaltsymbole im Inneren
path picture
erhalten die Optionengray
(ebenso wie die Leitungen) und skalieren die Symbole auf eine geeignete Größe. Möglicherweise müssen Sie mit diesem Wert herumspielen, um die richtige Größe zu erhalten. Es ist möglicherweise auch möglich, dies mit den Abmessungen undcircuit symbol unit=.1cm
vom oben genannten lokalen Koordinatensystem abhängig zu machen .\pgf@xx
\pgf@yy
Wenn Sie mehrere Symbole mit demselben Anker- und Verbindungslayout, aber mit unterschiedlichen Gates benötigen, ist es natürlich möglich, die Formdefinition entsprechend dreier Wertschlüssel formbar zu machen, die in diesem Fall auf
not gate
,nand gate
und gesetzt würdennor gate
.
Ich habe meinepaths.ortho
Bibliothekfür die Verbindungen innerhalb des path picture
. Sie können diese Leitungen natürlich auf jede beliebige Weise verbinden.
Code
\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}
Ausgabe
Antwort2
Eine mögliche Lösung mit pics
. Es ist schwierig, es pic-anchors
zur Positionierung zu verwenden (TiKZ-Bilder verankern), aber sie dienen als Bezugspunkte, um Verbindungen zwischen ihnen herzustellen.
\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}