
Ich möchte einen Ringoszillator zeichnen, also eine ungerade Anzahl von Logikinvertern in einem Ring. Ich habe einige echte Probleme, den Ring so zu platzieren, dass er den Invertern entspricht, siehe beigefügten Code. Gibt es irgendwelche Vorschläge, wie man das erreichen kann?
\begin{center}\begin{circuitikz}
\draw
(0,3) node[not port,rotate=-360] (mynot1) {}
(2.2,1.4) node[not port,rotate=-72] (mynot2) {}
(2,-1.4) node[not port,rotate=-144] (mynot3) {}
(-2,-2) node[not port,rotate=-206] (mynot4) {}
(-2.2,1.4) node[not port,rotate=-288] (mynot5) {}
(mynot1.out) to[bend left] (mynot2.in)
(mynot2.out) to[bend left] (mynot3.in)
(mynot3.out) to[bend left] (mynot4.in)
(mynot4.out) to[bend left] (mynot5.in)
(mynot5.out) to[bend left] (mynot1.in);
\end{circuitikz} \end{center}
Antwort1
Eine Möglichkeit hierfür wäre die Verwendung von Polarkoordinaten:
\documentclass[margin=5pt]{standalone}
\usepackage{circuitikz}
\begin{document}
\begin{circuitikz}
\draw ( -0:3) node[not port,rotate= -90] (mynot1) {}
( -72:3) node[not port,rotate=-162] (mynot2) {}
(-144:3) node[not port,rotate=-234] (mynot3) {}
(-216:3) node[not port,rotate=-306] (mynot4) {}
(-288:3) node[not port,rotate=-378] (mynot5) {}
(mynot1.out) to[bend left] (mynot2.in)
(mynot2.out) to[bend left] (mynot3.in)
(mynot3.out) to[bend left] (mynot4.in)
(mynot4.out) to[bend left] (mynot5.in)
(mynot5.out) to[bend left] (mynot1.in);
\end{circuitikz}
\end{document}
Durch die Verwendung des \foreach
Loop-Makros können wir den wiederholten Code vermeiden:
\Dokumentenklasse
\documentclass[margin=5pt][margin=5pt]{standalone}
\usepackage{circuitikz}
\begin{document}
\begin{circuitikz}
\foreach \i in {0,...,4} {
\draw (-\i * 72:3) node[not port,rotate=-90 - \i * 72] (mynot\i) {};
}
\foreach[remember=\i as \j (initially 4)] \i in {0,...,4} {
\draw (mynot\j.out) to[bend left] (mynot\i.in);
}
\end{circuitikz}
\end{document}
Einen perfekten Kreis zu erhalten ist schwieriger. Ein Problem besteht darin, dass der circutikz
Nicht-Gate-Knoten bereits gerade Liniensegmente enthält, die wir nicht einfach entfernen können.
Wenn Sie dieses Gate nicht verwenden möchten und bereit sind, es gegen das Not-Gate aus pgf
der circuits.logic.US
Bibliothek von einzutauschen, ist es etwas einfacher. Das einzige Problem ist, dass der center
Anker dieses Knotens nicht wirklich in der Mitte seiner input
und output
Anker liegt, sodass ein wenig mehr Trickserei erforderlich ist, um sicherzustellen, dass alle Ein- und Ausgänge tatsächlich im selben Zyklus liegen.
Aus diesem Grund zeichne ich zunächst einen falschen Knoten, den ich messen und dann die korrekten Koordinaten für jeden Knoten berechnen kann. Anschließend kann ich mithilfe einiger mathematischer Berechnungen den richtigen Winkel und Radius für jeden Bogen ermitteln, der die Tore verbindet.
\documentclass[margin=5pt]{standalone}
\usepackage{circuitikz}
\usetikzlibrary{circuits.logic.US}
\begin{document}
\begin{circuitikz}[not/.style={circuit logic US,not gate}]
\newcommand\radius{2}
\newcommand\ngates{5}
% draw a hidden not gate so we can measure the distance between its input and output
\begin{pgfinterruptboundingbox}
\node[not,anchor=input,transform canvas={scale=0}] at (0, \radius) (dummynot) {};
\end{pgfinterruptboundingbox}
\foreach \i in {1,...,\ngates} {
\draw let \p0 = (dummynot.output) in % \x0 is now the "length" of the node, \y0 is the radius
(-\i * 360 / \ngates:\y0) % this is the position on the circle
++(-90 - \i * 360 / \ngates:-\x0 / 2) % this is the offset that makes the input and output lie at the same distance from the center
node[not,anchor=input,rotate=-90 - \i * 360 / \ngates] (mynot\i) {};
}
\foreach \i in {1,...,\ngates} {
\draw let \p0 = (mynot\i.output),
\p1 = (mynot\i.input),
\p2 = (dummynot.output) in
(\p0) arc[start angle={atan2(\y0, \x0)},delta angle={2 * atan2(\x2 / 2, \y2) - 360 / \ngates},radius={veclen(\p0)}];
}
\end{circuitikz}
\end{document}