Описание «текучих» схем в circuitikz

Описание «текучих» схем в circuitikz

Я начал рисовать свою первую схему circuitikzнесколько дней назад — это довольно простой иерархический логический вентиль — и я боролся больше, чем я думал, после того как посмотрел на некоторые примеры. Мне пришлось бороться с большим количеством абсолютного позиционирования; некоторые вещи были слишком широкими; но самое главное, я либо размещал только один узел, либо рисовал один провод. Каждый пример, который я видел, имел всего несколько семантических групп команд рисования, и мои были, ну, комковатыми.

В конце концов я ушел от

\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}

к

\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}

но ни одно из них не кажется идиоматичным или беглым.

результат второго кода

Я извиняюсь, если это слишком субъективно; мне трудно описать, что мне не нравится в коде. Онработа. Я все еще чувствую, что мне не хватает чего-то фундаментального, что помогло бы легче увидеть структуру кода.

решение1

Это предложение для получения:

  • компактный рисунок (может быть слишком?)
  • список входов на постоянном вертикальном расстоянии
  • почти автоматическое позиционирование (у вас просто есть магическое число, сдвиг в положение (A).

Хитрость заключается в использовании 3-входового ИЛИ для вентилей 1 и 2 так, чтобы при наложении они не соприкасались (может быть, мне следует придумать лучший способ добиться этого? Другой параметр для портов? Проблема в том, что сложно думать об этом для общего числа внутренних/внешних входов).

\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}

введите описание изображения здесь

Обратите внимание, что здесь есть один негативный эффект: использование стольких различных \drawобъединений путей далеко от совершенства (использование to [short, .-.]создаст лучшее объединение; например, изменение

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

к

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

Связанный контент