Beschreibung „flüssiger“ Schaltkreise in circuitikz

Beschreibung „flüssiger“ Schaltkreise in circuitikz

Vor ein paar Tagen wollte ich meinen ersten Schaltkreis zeichnen circuitikz– es ist ein ziemlich einfaches hierarchisches Logikgatter – und ich hatte mehr Mühe, als ich nach dem Betrachten einiger Beispiele erwartet hatte. Ich musste mich mit vielen absoluten Positionierungen herumschlagen; einige Dinge waren zu breit; aber am wichtigsten war, dass ich entweder nur einen Knoten platzierte oder einen Draht zeichnete. Jedes Beispiel, das ich gesehen hatte, hatte nur wenige semantische Gruppen von Zeichenbefehlen, und meine waren, nun ja, klumpig.

Schließlich ging ich von

\begin{circuitikz}
    \draw
    (0,4) node[left](A){$A$}
    (0,3) node[left](B){$B$}
    (0,2) node[left](C){$C$}
    (0,1) node[left](D){$D$}
    (0,0) node[left](E){$E$}
    (2,3.5) node[or port](AoB){}
    (A) -| (AoB.in 1)
    (B) -| (AoB.in 2)
    (2,1.5) node[or port](CoD){}
    (C) -| (CoD.in 1)
    (D) -| (CoD.in 2)
    (5,2.5) node[and port](t1){}
    (AoB.out) -| (t1.in 1)
    (CoD.out) -| (t1.in 2)
    (8, 1.25) node[or port](Y){} ++(1,0) node[right]{$Y$}
    (t1.out) -| (Y.in 1)
    (E) -| (Y.in 2);
\end{circuitikz}

Zu

\begin{circuitikz}
    \draw

    (0,4) node[left](A){$A$}
    ++(0,-1) node[left](B){$B$}
    ++(2,0.5) node[or port](AoB){}

    (A) -| (AoB.in 1)
    (B) -| (AoB.in 2)

    (0,2) node[left](C){$C$}
    ++(0,-1) node[left](D){$D$}
    ++(2,0.5) node[or port](CoD){}

    (C) -| (CoD.in 1)
    (D) -| (CoD.in 2)

    (5,2.5) node[and port](t1){}
    (AoB.out) -| (t1.in 1)
    (CoD.out) -| (t1.in 2)

    (0,0) node[left](E){$E$}

    (8, 1.25) node[or port](Y){} ++(1,0) node[right]{$Y$}
    (t1.out) -| (Y.in 1)
    (E) -| (Y.in 2);

\end{circuitikz}

Aber keines von beiden fühlt sich idiomatisch oder fließend an.

Ergebnis des zweiten Codes

Ich entschuldige mich, wenn das zu subjektiv ist; es fällt mir schwer zu beschreiben, was mir an dem Code nicht gefällt.arbeiten. Ich habe immer noch das Gefühl, dass mir etwas Grundlegendes fehlt, das es einfacher machen würde, mehr Struktur im Code zu erkennen.

Antwort1

Dies ist ein Vorschlag zum Erhalt von:

  • eine kompakte Zeichnung (vielleicht zu viel?)
  • die Liste der Eingänge in konstantem vertikalen Abstand
  • eine fast automatische Positionierung (Sie haben nur eine magische Zahl, die Verschiebung auf Position ) (A).

Der Trick besteht darin, ein ODER mit 3 Eingängen für die Gates 1 und 2 zu verwenden, sodass sie sich beim Stapeln nicht berühren (vielleicht sollte ich mir eine bessere Möglichkeit überlegen, dies zu erreichen? Einen anderen Parameter für die Ports? Das Problem besteht darin, dass es zu komplex ist, darüber bei einer allgemeinen Anzahl innerer/äußerer Eingänge nachzudenken).

\documentclass[border=10pt]{standalone}
\usepackage[siunitx, RPvoltages]{circuitikz}
\ctikzset{logic ports=ieee}
% we will use 3-inputs ports with just input 1 and 2. We suppress
% input leads to use them.
\tikzset{asymmetric/.style={no input leads, number inputs=3}}

\begin{document}
\begin{circuitikz}
    % first gate to "guide" everything.
    \draw (0,10) node[or port, asymmetric](OR1){};
    % inputs position
    \draw (OR1.bin 1) -- ++(-1,0) node[left](A){$A$};
    \draw (OR1.bin 3) -- (OR1.bin 3-|A.east) node[left](B){$B$};
    % use calc to put the input at the same vertical distance
    \foreach \inode [count=\iy from 2] in {C, D, E}
        \path ($(A.east)!\iy!(B.east)$) node [left](\inode){$\inode$};
    % position second or an connect it
    \draw (C.east) -- (C.east -| OR1.bin 1)
        node [or port, asymmetric, anchor=bin 1](OR2){};
    \draw (D.east) -- (OR2.bin 3);
    % position the and port (this is a normal 2-port)
    \node [and port, anchor=west](AND1) at ($(OR1.out)!0.5!(OR2.out)$) {};
    \draw (OR1.out) -- (AND1.in 1) (AND1.in 2) -- (OR2.out);
    % find the position for the last OR; first move (E) under AND1
    \coordinate (E1) at (E.east -| AND1.out);
    % position the or and connect
    \node [or port, anchor=west](OR3) at ($(AND1.out)!0.5!(E1)$) {};
    \draw (AND1.out) -- (OR3.in 1) (OR3.in 2) |- (E.east);
    % and output
    \node [right](Y) at (OR3.out) {Y};
\end{circuitikz}
\end{document}

Bildbeschreibung hier eingeben

Beachten Sie, dass ein negativer Effekt hier darin besteht, dass die Verwendung so vieler verschiedener \drawPfadvereinigungen alles andere als perfekt ist (die Verwendung von to [short, .-.]wird eine bessere Vereinigung ergeben; ändern Sie zum Beispiel

\draw (OR1.out) -- (AND1.in 1) (AND1.in 2) -- (OR2.out);

Zu

\draw (OR1.out) to[short, .-.] (AND1.in 1) 
      (AND1.in 2) to[short, .-.]  (OR2.out);

verwandte Informationen