CircuiTikZ - Ringoszillator

CircuiTikZ - Ringoszillator

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}

Bildbeschreibung hier eingeben

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}

Ausgabe

Durch die Verwendung des \foreachLoop-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 circutikzNicht-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 pgfder circuits.logic.USBibliothek von einzutauschen, ist es etwas einfacher. Das einzige Problem ist, dass der centerAnker dieses Knotens nicht wirklich in der Mitte seiner inputund outputAnker 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}

5 Tore 11 Tore 4 Tore 2 Tore 1 Tor

verwandte Informationen