
Fui a dibujar mi primer circuito circuitikz
hace unos días (es una puerta lógica jerárquica bastante simple) y luché más de lo que pensé después de mirar algunas muestras. Tuve que luchar mucho con el posicionamiento absoluto; algunas cosas eran demasiado amplias; pero lo más importante es que solo estaba colocando un nodo o dibujando un cable. Cada ejemplo que había visto tenía sólo unos pocos grupos semánticos de comandos de dibujo, y los míos eran, bueno, grumosos.
Al final pasé de
\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}
a
\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}
pero ninguno se siente idiomático o fluido.
Pido disculpas si esto es demasiado subjetivo; Es difícil para mí describir lo que no me gusta del código. Lo hacetrabajar. Todavía siento que me falta algo fundamental que haría más fácil ver más estructura en el código.
Respuesta1
Esta es una sugerencia para obtener:
- un dibujo compacto (¿tal vez demasiado?)
- la lista de entradas a una distancia vertical constante
- un posicionamiento casi automático (sólo tienes un número mágico, el cambio a posición
(A)
.
El truco consiste en usar un OR de 3 entradas para las puertas 1 y 2 para que cuando se apilen no se toquen (¿tal vez debería pensar en una mejor manera de lograr esto? ¿Otro parámetro para los puertos? El problema es que es complejo pensar en ello). para un número genérico de entradas internas/externas).
\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}
Tenga en cuenta que un efecto negativo aquí es que el uso de tantas \draw
uniones de ruta diferentes está lejos de ser perfecta (usar to [short, .-.]
hará una mejor unión; por ejemplo, cambie
\draw (OR1.out) -- (AND1.in 1) (AND1.in 2) -- (OR2.out);
a
\draw (OR1.out) to[short, .-.] (AND1.in 1)
(AND1.in 2) to[short, .-.] (OR2.out);