7

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

8
  • You can find valid answers in High level digital design in TikZ. – Claudio Fiandrino Sep 2 '14 at 9:50
  • @ferahfeza : Thank you very much for your comment. I tried using \draw ($(PreAmp)!0.33!(Disc)$)--++(-90:0.5); but this move the line vertically... I don't know how to move it along the x axis. I'll edit my question to illustrate that. – Thanos Sep 2 '14 at 10:23
  • That's because (-90:0.5) says: ''go in direction -90 degrees for 0.5cm''. Note that you're not force to use this syntax. For instance, if you say \draw ($(PreAmp)!0.33!(Disc)$)--++(-1,0); that would draw a horizontal line towards left of 1cm. And so on... – Claudio Fiandrino Sep 2 '14 at 10:29
  • @ClaudioFiandrino : I want a vertical line to start at 1/3 of the yellow node. Using this \draw[very thick] ($(PreAmp)!0.33!(Disc)$)--++(0,-1); I get a vertical line, but it starts from the center. – Thanos Sep 2 '14 at 10:34
  • then that code would never work. What you're after is \draw[very thick] ($(PreAmp.north west)!0.33!(PreAmp.north)$)--++(0,-1); or south. This is stated in my linked answer. – Claudio Fiandrino Sep 2 '14 at 10:37
4

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

3
  • Thank you very much for your answer! What I am trying to avoid is to define the starting and ending coordinates. For instance this would be great draw (PreAmp.south/3)--(Disc.north/3) but such a command doesn't exist as far as I know. – Thanos Sep 2 '14 at 10:37
  • Thank's for your edited answer! I think it is coming to end! Any idea on how to control each line, in order to draw the "curved" lines? – Thanos Sep 2 '14 at 11:19
  • For this have a look at the pgfmanual section 2.4 (Curved Path Construction) or pgfplots for plotting functions. – moospit Sep 2 '14 at 11:21
3

Next code shows another possibility for drawing parallel lines between nodes without using calc tikzlibrary. It uses (node.angle) syntax for starting points and |- or -| intersection coordinate for ending ones.

If you want exact coordinates like 1/3 of node's vertical length you need calc library, but if you can accept something just visually good enough, can make some test to find the correct angle.

\documentclass[tikz, border=5mm]{standalone}
\usetikzlibrary{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 {-7,0,7} {
   \draw [ultra thick, blue] (PreAmp.\x) -- (PreAmp.\x-|ADC.west);
   \draw [red] (PreAmp.\x) -- (PreAmp.\x-|ADC.west);
  }
  \foreach \x in {210,270,330} {
   \draw [ultra thick, blue] (PreAmp.\x) -- (PreAmp.\x|-Disc.north);
  }
  \foreach \x in {250,270,290} {
   \draw [red] (PreAmp.\x) -- (PreAmp.\x|-Disc.north);
  }
    \draw[purple,dashed] (PreAmp.center) -- ++(7:2cm);
    \draw[purple,dashed] (PreAmp.center) -- ++(330:2cm);
 \end{tikzpicture}
\end{document}

enter image description here

8
  • Thank you very much for your answer! The thing is that I want to avoid using lengths and try to use calc and intersecting coordinates -| and |-. – Thanos Sep 3 '14 at 10:32
  • @Thanos I don't use lengths in my example. \draw[purple,dashed] (PreAmp.center) -- ++(7:2cm); is only used to show that top most horizontal path starts at PreAmp.7. – Ignasi Sep 3 '14 at 10:41
  • You are right, but using angles, i think it's a bit similar to using lengths i.e. for the starting position of the node. – Thanos Sep 3 '14 at 10:52
  • @Thanos Sure. In fact I think it's even worse because the distance between parallel lines depends on radius. I just wanted to shown an alternative solution. – Ignasi Sep 3 '14 at 11:23
  • Now I see! It is indeed useful, therefore I voted it up! Thank you very much for your time and help! Any idea on how to control the lines using intersecting coordinates? – Thanos Sep 3 '14 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.