# Configuring node placement and width with TikZ, overlapping nodes

I've created a simple feedback structure but cannot cause the utmost right block not to overlap with the circle. I've tried altering this block's width with minimum width and text width, but it doesn't do the trick. What do I need to change, to move the block to the right?

\begin{tikzpicture}[auto, node distance=2cm,>=latex']
\tikzstyle{block} = [draw, rectangle, minimum height=2em, minimum width=3em, text centered, text depth=0pt]
\tikzstyle{sum} = [draw, circle, node distance=1.5cm]

\node (input) {};
\node [above, above of=input] (gyro_input) {};
\node [block, right of=input] (error) { $\hat{R}^T \bar{R}$ };
\node [block, right of=error] (normalize) {$P_a(\tilde{R})$};
\node [block, right of=normalize] (gain) {$C(s)$};
\node [sum, right of=gain] (sum2) {};
\node [block, right of=sum2] (correction) {$\dot{\hat{R}} = \hat{R} ( \bar{\Omega}_\times + C(s) P_a (\tilde{R}))$};
\node [right of=correction] (output) {};
\node [block, above of=sum2] (R_dynamics) {$\bar{\Omega}_\times$};
\node [block, below of=error] (transpose) {$\hat{R}^T$};

\draw [->] (input) node [above] {$\bar{R}$} -- (error);
\draw [->] (error) -- (normalize) node [midway, above] {$\tilde{R}$};
\draw [->] (normalize) -- (gain);
\draw [->] (gain) -- (sum2);
\draw [->] (sum2) -- (correction);
\draw [->] (correction) -- node (fork) {} (output) node [above] {$\hat{R}$};
\draw [->] (gyro_input) node [above] {$\bar{\Omega}$} -- (R_dynamics);
\draw [->] (R_dynamics) -- (sum2);
\draw [->] (fork) |- (transpose);
\draw [->] (transpose) -- (error);
\end{tikzpicture}


The outcome of the above is:

-

The problem occurs because the node distance is set to 1.5cm. And this distance refers to the distance between node centres, not distance between side of nodes. In this case your overlapping node has a width that is far greater than this and thus it will overlap.

You can circumvent it by locally overwriting the node distance:

\node [block, right of=sum2,node distance=3.5cm]


which will do you good.

Another idea which can turn out nice is to explicitly use the nodes anchors to position them. This will yield a consistent distance between the side of the nodes. I can't remember if this is implemented in some sort, but it can be done manually like this:

\tikzstyle{my below of} = [below=of #1.south]
\tikzstyle{my right of} = [right=of #1.east]
\tikzstyle{my left of} = [left=of #1.west]
\tikzstyle{my above of} = [above=of #1.north]
\begin{tikzpicture}[auto, node distance=.75cm,>=latex']
\tikzstyle{block} = [draw, rectangle, minimum height=2em, minimum width=3em, text centered, text depth=0pt]
\tikzstyle{sum} = [draw, circle]

\node (input) {};
\node [above, my above of=input] (gyro_input) {};
\node [block, my right of=input] (error) { $\hat{R}^T \bar{R}$ };
\node [block, my right of=error] (normalize) {$P_a(\tilde{R})$};
\node [block, my right of=normalize] (gain) {$C(s)$};
\node [sum, my right of=gain] (sum2) {};
\node [block, my right of=sum2] (correction) {$\dot{\hat{R}} = \hat{R} ( \bar{\Omega}_\times + C(s) P_a (\tilde{R}))$};
\node [my right of=correction] (output) {};
\node [block,my above of=sum2] (R_dynamics) {$\bar{\Omega}_\times$};
\node [block,my below of=error] (transpose) {$\hat{R}^T$};

\draw [->] (input) node [above] {$\bar{R}$} -- (error);
\draw [->] (error) -- (normalize) node [midway, above] {$\tilde{R}$};
\draw [->] (normalize) -- (gain);
\draw [->] (gain) -- (sum2);
\draw [->] (sum2) -- (correction);
\draw [->] (correction) -- node (fork) {} (output) node [above] {$\hat{R}$};
\draw [->] (gyro_input) node [above] {$\bar{\Omega}$} -- (R_dynamics);
\draw [->] (R_dynamics) -- (sum2);
\draw [->] (fork) |- (transpose);
\draw [->] (transpose) -- (error);
\end{tikzpicture}


Notice that node distance now tells you the distance between the node sides and not the node centres. You do need to ensure correct spacing with your positioning of the gyro_input node. However, that can easily be done.

On a side note, consider using \coordinate for nodes with no text. That will behave more expected as your coordinate input will actually have a finite size. And thus the anchors north/south/east/west will not be a single point. Try inserting:

\draw[blue] (gyro_input.north) -- (gyro_input.south);


and see the size of that node. This is due to inner sep and outer sep.

-
Thanks for the answer and all tips. –  mmm Mar 12 '12 at 13:43

With such a regular structure, I prefer to use a matrix to place nodes. Values column sep and row sep represent the distance between node borders but you can fix different values for every column and row. In following example &[-8mm] subtracts 8 mm to default column separation between all nodes in first and second column.

A second comment about your code, you can use coordinate nodes instead of empty ones.

\documentclass[border=3mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{matrix,arrows}

\begin{document}

\begin{tikzpicture}[auto, node distance=2cm,>=latex']
\tikzstyle{block} = [draw, rectangle, minimum height=2em, minimum width=3em, text centered, text depth=0pt]
\tikzstyle{sum} = [draw, circle, node distance=1.5cm]

\matrix[column sep=1.2cm, row sep=8mm]{
\coordinate[label=above:$\bar{\Omega}$] (gyro input); &[-8mm] & & &[-7mm] \node [block] (R_dynamics) {$\bar{\Omega}_\times$}; &[-7mm] \\
\coordinate[label=above:$\bar{R}$] (input);
&
\node [block] (error) { $\hat{R}^T \bar{R}$ };
&
\node [block] (normalize) {$P_a(\tilde{R})$};
&
\node [block] (gain) {$C(s)$};
&
\node [sum] (sum2) {};
&
\node [block] (correction) {$\dot{\hat{R}} = \hat{R} ( \bar{\Omega}_\times + C(s) P_a (\tilde{R}))$};
&
\coordinate (output) {}; \\
&
\node [block] (transpose) {$\hat{R}^T$};\\
};

\draw [->] (gyro input) -- (R_dynamics);
\draw [->] (R_dynamics) -- (sum2);

\draw [->] (input)--(error);
\draw[->] (error) -- (normalize) node [midway, above] {$\tilde{R}$};
\draw [->] (normalize) -- (gain);
\draw [->] (gain) -- (sum2);
\draw [->] (sum2) -- (correction);
\draw [->] (transpose) -- (error);
\draw [->] (transpose) -| (output)--(correction) node [above,midway] {$\hat{R}$};
\end{tikzpicture}

\end{document}


-

A solution with schemabloc package (see also Schéma-blocs avec PGF/TIKZ sous LaTeX [French]).

\documentclass{article}
\usepackage{tikz}

\usepackage{schemabloc}

\begin{document}

\begin{tikzpicture}
\sbEntree{input}
\sbBloc[4]{error}{$\hat{R}^T \bar{R}$ }{input} \sbRelier[$\bar{R}$]{input}{error}
\sbBloc[3]{normalize}{$P_a(\tilde{R})$ }{error} \sbRelier[$\tilde{R}$]{error}{normalize}
\sbBlocL{gain}{$C(s)$}{normalize}
\sbCompSum*[5]{sum2}{gain}{ }{ }{ }{ } \sbRelier{gain}{sum2}
\sbBlocL{correction}{$\dot{\hat{R}} = \hat{R} ( \bar{\Omega}_\times + C(s) P_a (\tilde{R}))$}{sum2}
\sbSortie[3]{output}{correction}
\sbRelier[$\hat{R}$]{correction}{output}
\sbDecaleNoeudy[-6]{input}{gyro input}
\node[above of=gyro input]{$\bar{\Omega}$};
\sbBlocL[20.5]{R_dynamics}{$\bar{\Omega}_\times$}{gyro input}
\sbDecaleNoeudy[6]{input}{transpose}
\sbBloc[4]{transpose}{$\hat{R}^T$}{transpose}
\sbRelieryx{correction-output}{transpose}
\sbRelier{transpose}{error}
\sbRelier{R_dynamics}{sum2}
\end{tikzpicture}

\end{document}


-
Thanks for the alternate solution. Can anything be done to place \hat{\Omega} right above the input bar? –  mmm Mar 20 '12 at 8:12
replace \node[above of=gyro input]{$\bar{\Omega}$}; by \node[above =0em of gyro input]{$\bar{\Omega}$};</pre> –  rpapa Mar 22 '12 at 17:19