Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to split a path into two branches as in the following MWE.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};
  \draw [->, rounded corners=1cm] (A) -| +(2cm,0cm) |- (B);
  \draw [->, rounded corners=1cm] (A) -| +(2cm,0cm) |- (C);
\end{tikzpicture}
\end{document}

This is the result:

an awkward result

There are many things wrong with that.

  1. The left quater circle to C goes in the wrong direction
  2. The circles should be a tangent to each other
  3. They should meet in exactly the middle of A and BC

I think I still didn't get the thing about positioning in TikZ. Can someone help me?

share|improve this question
add comment

2 Answers

up vote 10 down vote accepted

Old Style

Positioning

Without the on grid option nodes are placed so that the distance between their border is correct. With on grid the .center anchors are used for calculation.

Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning}
\tikzset{
    every node/.style={draw,fill,fill opacity=.1},
    helper node/.style={draw=none,fill=none,fill opacity=1},
    ruler/.style={line width=1.2\pgflinewidth,red,|-|,shorten >=-.5\pgflinewidth,shorten <=-.5\pgflinewidth},
    helper/.style={line width=1.2\pgflinewidth,red,-,dashed},
    } % for debugging purposes

\begin{document}
\begin{tikzpicture}
    \draw[help lines] (-1,-2) grid (5,2);
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};

  \draw[ruler] (A.north east) -- (A.north east |- B.south west) node[left,pos=.5,helper node] {1\,cm};
  \draw[helper] (A.north east |- B.south west) -- (B.south east);
  \draw[ruler] (A.north east) -- (A.north east -| B.south west) node[above,pos=.5,helper node] {4\,cm};
  \draw[helper] (A.north east -| B.south west) -- (B.north west);
\end{tikzpicture}

\begin{tikzpicture}[on grid]
    \draw (-1,-2) grid (5,2);
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};

  \draw[ruler] (A.center) -- (A.center |- B.center) node[left,pos=.5,helper node] {1\,cm};
  \draw[helper] (A.center |- B.center) -- (B.east);
  \draw[ruler] (A.center) -- (A.center -| B.center) node[above,pos=.5,helper node] {4\,cm};
  \draw[helper] (A.center -| B.center) -- (B.north);
\end{tikzpicture}
\end{document}

Output

enter image description here

Weird vertical lines

Don’t use -| for the first part of the path as the next point (2cm,0cm) is in fact already horizontal to the start point. Why is the weird line missing to C? Because it is the same as to B, apparently TikZ does a >= comparison with the y-values of the start and the target coordinate to calculate in which direction (left or right) the rounded circle have to go.

Code

  \draw [->, rounded corners=1cm] (A) -| +(2cm, 0cm   ) |- (B);
  \draw [->, rounded corners=1cm] (A) -| +(2cm,-0.01cm) |- (C);

Output

enter image description here

Rounded circles

A rounded-circle radius of 1cm needs at least 2cm to do a full 90-degree-left and 90-degree-right turn. So you either have to use .5cm (= half of vertical distance) in the on grid version or calculate the needed radius within the path operation.

The easiest way to do this is the let … in operation which needs the calc library.
I provide a curvy style that takes one optional argument (default: 2cm).

Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning,calc}
\tikzset{
    curvy/.style={
        to path={
            let \p1=(\tikztostart),
                \p2=(\tikztotarget),
                \n1={abs(\y2-\y1)/2}
            in
            [rounded corners=\n1]
            (\tikztostart) -- + (0:#1) |- (\tikztotarget) \tikztonodes
        }
    },
    curvy/.default=2cm,
}
\begin{document}
\begin{tikzpicture}
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};
  \draw [->] (A) to[curvy]     (B);
  \draw [->] (A) to[curvy=3cm] (C);
\end{tikzpicture}

\begin{tikzpicture}[on grid]
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};
  \draw [->] (A) to[curvy]     (B);
  \draw [->] (A) to[curvy=1cm] (C);
\end{tikzpicture}
\end{document}

Output

enter image description here

New Style

You might want to check out the tree-producing facilities of TikZ.

Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{positioning,calc}
\begin{document}
\begin{tikzpicture}[
    grow'=right,% clockwise, not counterclockwise (which would be "grow")
    level 1/.style={level distance=4cm,sibling distance=2cm},
    level 2/.style={level distance=2cm,sibling distance=1.5cm},
    edge from parent path={% the let ... in operator is only used to set rounded corners 
                           % to zero if parent and child are on the same height, but due to
                           % imprecision in the math-engine the comparison value is 0.001
        let \p1=(\tikzparentnode\tikzparentanchor),
            \p2=(\tikzchildnode\tikzchildanchor),
            \n1={abs(\y2-\y1) > 0.001} 
        in
        [rounded corners=\n1*\tikzsiblingdistance/4]
             (\tikzparentnode\tikzparentanchor)
            -- + (0:\tikzleveldistance/2)
            |-   (\tikzchildnode\tikzchildanchor)
    }
]
\node {A}
    child {node {B} 
        child {node {B1}}
        child {node {B2}}
        child {node {B3}}
    }
    child {node {C}}
;
\end{tikzpicture}

Output

enter image description here

share|improve this answer
add comment

Is it like this?

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \node (A) [rectangle] {A};
  \node (B) [rectangle,above right=1cm and 4cm of A] {B};
  \node (C) [rectangle,below right=1cm and 4cm of A] {C};
  \draw [->, rounded corners=.7cm] (A) -- (0:2cm)  |- (B);
  \draw [->, rounded corners=.7cm] (A) -- (0:2cm) |- (C);
\end{tikzpicture}
\end{document}
share|improve this answer
    
Yes, this is how it should look like. Is there way to let 0.7 (which I suppose is 2^-0.5) be calculated automatically? –  helami Dec 26 '12 at 0:13
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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