# How can I make my logic circuits look “better”?

I'm new to this, I'm trying to use circuiTikz to draw logic diagrams and I can't get it quite right,

Is there anything I can do to avoid the lines getting merged when they shouldn't? also, is there any way I can align node X to the first entry in the R gate?

here is the code btw:

\begin{tikzpicture}
\ctikzset{
logic ports=ieee,
logic ports/scale=0.6,
}

\draw

node[not port] (not1) at  (4,7.5) {}
node[not port] (not2) at  (4,6.5) {}
node[not port] (not3) at  (4,5.5) {}

node[nor port, number inputs=3] (norR) at (6,8) {R}
node[nor port] (norS) at (6,6) {S}
node[and port] (andT) at (6,4) {T}

node[or port, number inputs = 3] (orF) at  (8,6) {}

node[] (X) at (2,8.25) {X}
node[] (Y) at (2,4.25) {Y}
node[] (Z) at (2,3.75) {Z}
node[] at (8.75,6) {F}

(not1) -| (norR.in 2)
(not2) -| (norR.in 3)
(not2) -| (norS.in 1)
(not3) -| (norS.in 2)
(norR.out) -| (orF.in 1)
(norS.out) -| (orF.in 2)
(andT.out) -| (orF.in 3)

(X) -| (norR.in 1)
(X) -| (not3.in)

(Y) -| (andT.in 1)
(Y) -| (not1.in)

(Z) -| (andT.in 2)
(Z) -| (not2.in)

;
\end{tikzpicture}


@js-bibra answer is an elegant way to reduce the tangliness, so go for it, unless you want the inputs strictly on the left.

I will post a modification of your code, though, to show how I would do the minimum modification to keep the diagram a bit cleaner and how to "stagger" the cables to avoid your overwritten vertical one.

The trick is to use relative coordinate when possible, perpendicular coordinates, and then to "enlarge" a bit the inputs leads for some input. I have commented in the code...

\documentclass[border=10pt]{standalone}
\usepackage[siunitx, RPvoltages]{circuitikz}
\begin{document}

\begin{tikzpicture}
\ctikzset{
logic ports=ieee,
logic ports/scale=0.6,
}

\draw

node[not port] (not1) at  (4,7.5) {}
node[not port] (not2) at  (4,6.5) {}
node[not port] (not3) at  (4,5.5) {}

node[nor port, number inputs=3] (norR) at (6,8) {R}
node[nor port] (norS) at (6,6) {S}
node[and port] (andT) at (6,4) {T}

node[or port, number inputs = 3] (orF) at  (8,6) {}

% use relative coordinates here, to align with port inputs

node[] (X) at ([xshift=-4cm] norR.in 1) {X}
node[] (Y) at (X|-andT.in 1) {Y}  % in the same place vertical as X!
node[] (Z) at (X|-andT.in 2) {Z}
node[right] at (orF.out) {F}

% not output connections (reverse for staggering, use .out anchor!)
(norR.in 2) --++(-0.5,0) |- (not1.out)
(norR.in 3) |- (not2.out)
(norS.in 1) |- (not2.out)
(norS.in 2) |- (not3.out)

(norR.out) -| (orF.in 1)
(norS.out) -| (orF.in 2)
(andT.out) -| (orF.in 3)

% connection the other way around to easily "stagger" them

(norR.in 1) |- (X)
(not3.in) |- (X)

(andT.in 1) |- (Y)
(not1.in)   --++(-0.5,0) |- (Y)

(andT.in 2) |- (Z)
(not2.in) -- ++(-1,0) |- (Z)

;
\end{tikzpicture}
\end{document}



Anyway, let me propose another variation. I like to use input rails when there are more than a couple of variables, to make the connection easily to follow and to add dots when connecting them (even they are not strictly needed, they highlights the connection and made clear that the bare crossings are just that, crossings).

I use more than one \draw command too, to be able to use macros to simplify things and easily create loops.

\documentclass[border=10pt]{standalone}
\usepackage[siunitx, RPvoltages]{circuitikz}

\newcommand{\gotorail}[2]{\draw (#1) to[short,-*] (#1 -| #2);}

\begin{document}

\begin{tikzpicture}
\ctikzset{
logic ports=ieee,
logic ports/scale=0.6,
}

\draw
node[not port] (not1) at  (4,7.5) {}
node[not port] (not2) at  (4,6.5) {}
node[not port] (not3) at  (4,5.5) {}
node[nor port, number inputs=3] (norR) at (6,8) {R}
node[nor port] (norS) at (6,6) {S}
node[and port] (andT) at (6,4) {T}
node[or port, number inputs = 3] (orF) at  (8,6) {};

% input rails
\coordinate (rail) at ([xshift=-5cm, yshift=0.5cm] norR.north);
\foreach [count=\i] \n in {X, Y, Z} {
\path (rail) ++({\i/2},0) node[above](\n){\n};
\draw (\n) -- (\n |- andT.south);
}

% output
\node[right] at (orF.out) {F};

% not output connections
\draw
(norR.in 2) --++(-0.5,0) |- (not1.out)
(norR.in 3) |- (not2.out)
(norS.in 1) |- (not2.out)
(norS.in 2) |- (not3.out)
;

% port connections
\draw
(norR.out) -| (orF.in 1)
(norS.out) -| (orF.in 2)
(andT.out) -| (orF.in 3)
;
% connection the other way around to easily "stagger" them

% input rail connection
\gotorail{norR.in 1}{X}
\gotorail{not3.in}{X}

\gotorail{andT.in 1}{Y}
\gotorail{not1.in}{Y}

\gotorail{andT.in 2}{Z}
\gotorail{not2.in}{Z}

\end{tikzpicture}
\end{document}


• You missed the * (or cic) between R and S. – John Kormylo Feb 18 at 12:48
• @JohnKormylo yes, you're right... although it's not really needed, given that I put the others... – Rmano Feb 18 at 13:44

\documentclass[10pt,a4paper]{article}

\usepackage{circuitikz}
\usetikzlibrary{positioning, calc}

\begin{document}
\begin{tikzpicture}
\ctikzset{
logic ports=ieee,
logic ports/scale=0.6,
},
\tikzset{
between/.style args={#1 and #2}{
at = ($(#1)!0.5!(#2)$)
}
}
\draw
node[nor port, number inputs=3] at (6,7.5) (norR)  {R}
node[nor port, below=of norR] (norS)  {S}
node[and port, below=of norS] (andT)  {T}

coordinate[between=norR.in 3 and norS.in 1] (aux) {}

node[not port, left=2cm of aux] (not2) {}
node[not port, left=2cm of norR.in 2] (not1) {}
node[not port, left=2cm of norS.in 2] (not3) {}
%
node[or port, number inputs = 3, right=of norS] (orF)  {}
%%
node[left=2cm of not3] (Y) {Y}
node[right=1mm of Y] (Z)  {Z}
node[right=1mm of Z] (X)  {X}
node[right=1mm of orF]   {F}
%%
(not1) -| (norR.in 2)
(not2) -| (norR.in 3)
(not2) -| (norS.in 1)
(not3) -| (norS.in 2)
(norR.out) -| (orF.in 1)
(norS.out) -| (orF.in 2)
(andT.out) -| (orF.in 3)
%
(X)--++(0,2.5cm) -| (norR.in 1)
(X) |- (not3.in)
%
(Y) |- (andT.in 1)
(Y) |- (not1.in)
%
(Z) |- (andT.in 2)
(Z) |- (not2.in)
%
;
\end{tikzpicture}
\end{document}

• Really elegant, +1 – Rmano Feb 18 at 9:42