[Tex/LaTex] Tikz-Connecting nodes with multiple lines

blockdiagramsnodespositioningtikz-pgf

I am trying to reproduce the following image I made in "Power point".

enter image description here

Although, there is no difficulty in designing the boxes, I find it rather hard to properly position the red and black lines. One solution is to use pure coordinates, but I think that there must be an easiest way to do it, since I have defined nodes.

My code is

    \documentclass{standalone}
    \usepackage{tikz}
    \usetikzlibrary{positioning}

    \begin{document}

    \begin{tikzpicture}

    \tikzstyle{blockYellow}=[top color=white, bottom color=yellow!60, draw=yellow!90!black!100, minimum size=1cm, rounded corners]
    \tikzstyle{blockBrown}=[top color=white, bottom color=brown!60, draw=brown!90!black!100, minimum size=1cm, rounded corners]
    \tikzstyle{blockBlack}=[top color=white, bottom color=black!60, draw=black!90!black!100, minimum width=1cm, minimum height=5cm, rounded corners]
    \tikzstyle{blockBlue}=[top color=white, bottom color=blue!60, draw=blue!90!black!100, minimum size=1cm, rounded corners]

    \pgfdeclarelayer{background}
    \pgfsetlayers{background,main}

  %PreAmp
 \node[blockYellow] (PreAmp) {\eng{(Pre)Amp}};
 %Detectors
 \node [blockBrown, left of=PreAmp, node distance=3.5cm, anchor=east] (E2) {$E_2$};
 \node [blockBrown, above of=E2, node distance=2cm] (E1) {$E_1$};
 \node [blockBrown, below of=E2, node distance=2cm] (E3) {$E_3$};
 \node [blockBrown, above of=PreAmp, node distance=3.5cm] (DE2) {$\Delta E_2$};
 \node [blockBrown, left of=DE2, node distance=2cm] (DE1) {$\Delta E_1$};
 \node [blockBrown, right of=DE2, node distance=2cm] (DE3) {$\Delta E_3$};
 %ADC
 \node [blockBlack, right of=PreAmp, node distance=10cm] (ADC) {\textcolor{white}{$ADC$}};
 %Disc
 \node [blockBlue, below of=PreAmp, node distance=5cm] (Disc) {$Discriminator$};
 %FIFO
 \node [blockBlue, right of=Disc, node distance=5cm] (FIFO) {$FIFO$};
 %DGG
 \node [blockBlue, below of=ADC, node distance=5cm] (DGG) {$DGG$};
 %cables
 \draw[red,very thick] (PreAmp)--(Disc);
 %\draw[red,very thick] (PreAmp.north)--(Disc.north);
 \draw[red,very thick] (Disc)--(FIFO);
 \draw[red,very thick] (FIFO)--(DGG);
 \draw[red,very thick] (DGG)--(ADC);
 \draw[very thick] (DE2)--(PreAmp);
 \draw[red, very thick] (E2)--(PreAmp);
 \draw[red, very thick] ($(PreAmp.south west)!0.33!(PreAmp.south east)$)coordinate (a)--(a|-Disc.north);
 \draw[red, very thick] ($(PreAmp.south west)!0.66!(PreAmp.south east)$)coordinate (b)--(b|-Disc.north);
 %\draw[red, very thick] ($(Disc.north east)!0.33!(Disc.south east)$)coordinate (c)--(c|-FIFO.west);
 \draw[red, very thick] ($(Disc.north east)!0.33!(Disc.south east)$) -- ($(FIFO.north west)!0.33!(FIFO.south west)$);
 \draw[red, very thick] ($(Disc.north east)!0.66!(Disc.south east)$) -- ($(FIFO.north west)!0.66!(FIFO.south west)$);
 \draw[very thick] ($(PreAmp.north east)!1/7!(PreAmp.south east)$)--+(0:8.525cm);%(c|-[]ADC.north);%-- ($(ADC.north west)!0.166!(ADC.south west)$);
 \draw[very thick] ($(PreAmp.north east)!2/7!(PreAmp.south east)$)--+(0:8.525cm);
 \draw[very thick] ($(PreAmp.north east)!3/7!(PreAmp.south east)$)--+(0:8.525cm);
 \draw[red, very thick] ($(PreAmp.north east)!4/7!(PreAmp.south east)$)--+(0:8.525cm);
 \draw[red, very thick] ($(PreAmp.north east)!5/7!(PreAmp.south east)$)--+(0:8.525cm);
 \draw[red, very thick] ($(PreAmp.north east)!6/7!(PreAmp.south east)$)--+(0:8.525cm);
    \end{tikzpicture}
    \end{document}

and my output is

enter image description here

How to draw the lines using nodes instead of coordinates? I am thinking something like

\draw[very thick] (PreAmp.south/3)--(Disc.north/3);

i.e. not having to define the line's length, just to connect the two nodes.

Straight Lines

EDIT After @ClaudioFiandrino 's suggestion on a personal chat I used the following code to connect the nodes.

\draw ($(PreAmp.south west)!0.33!(PreAmp.south east)$)coordinate (a)--(a|-Disc.north);

Although this works for the vertical lines, I can't get it to work for the horizontal one because when I use

\draw ($(Disc.north east)!0.33!(Disc.south east)$)coordinate (c)--(c|-FIFO.west);

I get a vertical line as shown below in the black line. I insist in using calc and |- because the nodes in this picture don't have the same dimensions.

enter image description here

"Curved" Lines

The only way to reproduce the curved lines is to use relative coordinates, but I feel that there must a more convenient way.

So I used

%curved cables
 \draw[red, very thick] (E1.east)-- ++(1.3cm,0) -- ++(0,-1.5cm)-- ++(1.3cm,0);%($(PreAmp.north west)!1/3!(PreAmp.south west)$);
 \draw[red, very thick] (E3.east)-- ++(1.3cm,0) -- ++(0,1.5cm)-- ++(1.3cm,0);
 \draw[very thick] (DE3.south)-- ++(0,-1.1cm) -- ++(-1.5cm,0)-- ++(0,-1.15cm);
 \draw[very thick] (DE1.south)-- ++(0,-1.1cm) -- ++(1.5cm,0)-- ++(0,-1.15cm);

and the output is

enter image description here

Best Answer

You can use the calc-library to set the connection-points for your lines. It's a simple approach which should be enough in the most situations. A small MWE:

\documentclass[tikz, border=5mm]{standalone}
\usetikzlibrary{calc}

\begin{document}
 \begin{tikzpicture}
  \node at (0,0) [draw, rectangle, minimum height=2cm, minimum width=.5cm] (mynode) {};
  \foreach \y in {-.75,-.5,-.25}{
    \draw [red, ->] (-1,\y) -- ($(mynode.west) +(0,\y)$);
  }
  % ... more lines
 \end{tikzpicture}
\end{document}

rendered image

Is this information satisfying enough for you or do you need more input?

Edit: Usage of percentual values depending on nodes The following code uses the calc-library to position the line-connectors on an percentual value of the node's edge. (Assumed this from your answer)

The nodes need the same width/height to make use of this!

\documentclass[tikz, border=5mm]{standalone}
\usetikzlibrary{calc, positioning}

\begin{document}
 \begin{tikzpicture}
  \node [draw, rectangle, minimum width=3cm, minimum height=1cm] (PreAmp) {PreAmp};
  \node [draw, rectangle, minimum height=1cm, right=2cm of PreAmp] (ADC) {ADC};
  \node [draw, rectangle, minimum width=3cm, below=1cm of PreAmp] (Disc) {Discriminator};
  \foreach \x in {.25,.5,.75} {
   \draw ($(PreAmp.south west)!\x!(PreAmp.south east)$) -- ($(Disc.north west)!\x!(Disc.north east)$);
   \draw ($(PreAmp.north east)!\x!(PreAmp.south east)$) -- ($(ADC.north west)!\x!(ADC.south west)$);
  }
 \end{tikzpicture}
\end{document}

rendered image

To show the two solutions side-by-side: Relative positioning (1 point) vs. percentual positioning (edge)

  • Blue: percentual positioning on node's edge (the nodes need the same width/height)
  • Red: relative positioning using node's anchors (the node's centers need to be on one axis to make this work)

Code:

\documentclass[tikz, border=5mm]{standalone}
\usetikzlibrary{calc, positioning}

\begin{document}
 \begin{tikzpicture}
  \node [draw, rectangle, minimum width=3cm, minimum height=1cm] (PreAmp) {PreAmp};
  \node [draw, rectangle, minimum height=1cm, right=2cm of PreAmp] (ADC) {ADC};
  \node [draw, rectangle, minimum width=3cm, below=1cm of PreAmp] (Disc) {Discriminator};
  \foreach \x in {.25,.5,.75} {
   % Percentual on node edge
   \draw [ultra thick, blue] ($(PreAmp.south west)!\x!(PreAmp.south east)$) -- ($(Disc.north west)!\x!(Disc.north east)$);
   \draw [ultra thick, blue] ($(PreAmp.north east)!\x!(PreAmp.south east)$) -- ($(ADC.north west)!\x!(ADC.south west)$);
  }
  \foreach \x in {-.25,0,.25} {
   % Relative to one point
   \draw [red] ($(PreAmp.south) +(\x,0)$) -- ($(Disc.north) +(\x,0)$);
   \draw [red] ($(PreAmp.east)  +(0,\x)$) -- ($(ADC.west) +(0,\x)$);
  }
 \end{tikzpicture}
\end{document}

rendered image