4

This is what I have right now:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,automata}
\definecolor{light-gray}{gray}{0.6}
\begin{document}
\begin{tikzpicture}[line width=.1cm,shorten >=0pt,auto,on grid=false, every state/.style={minimum size=0pt}, level distance=2.0cm, level 1/.style={sibling distance=2cm}, level 2/.style={sibling distance=1cm}, level 3/.style={sibling distance=.5cm}]
\tikzstyle{every node}=[font=\tiny , circle, outer sep=0pt, inner sep=0pt]
           \node[state] (S) {}
           child {node[state] (S1) {}
              child {node[state] (S11) {}
                 child {node[state] (S111) {} }
                 child {node[state] (S112) {} }
              }
              child {node[state] (S12) {}
                 child {node[state] (S121) {} }
                 child {node[state] (S122) {} }
              }
           }
           child {node[state] (S2) {}
              child {node[state] (S21) {}
                 child {node[state] (S211) {} }
                 child {node[state] (S212) {} }
              }
              child {node[state] (S22) {}
                 child {node[state] (S221) {} }
                 child {node[state] (S222) {} }
              }
           };
\end{tikzpicture}
\end{document}

TikZ Tree

I want something like this:

TikZ Tree with curves and arrows

Actually, this is just the top portion of the bigger tree I'm working on and I have to do this for a lot of paths in the tree, so I don't want to calculate the control points manually. I would rather just specify the points which the curve should surround(S, S1, S11, S111) and a distance which should be maintained between the points and the curve.

Is this possible? Any help would be appreciated!

Edit:

I tried what percusse and Torbjørn T. suggested. Added this code in the tikzpicture:

           \node[draw=none, above=5mm of S] (1p1) {};
           \node[draw=none, left =5mm of S1] (1p2) {};
           \node[draw=none, left =5mm of S11] (1p3) {};
           \node[draw=none, below left =5mm and 2mm of S111] (1p4) {};
           \node[draw=none, below right=5mm and 2mm of S111] (1p5) {};
           \node[draw=none, right=5mm of S11] (1p6) {};
           \node[draw=none, right=5mm of S1] (1p7) {};
           \node[draw=none, below right=5mm and 2mm of S] (1p8) {};
           \draw[black, line width=0.05cm] plot [smooth cycle] coordinates {(1p1) (1p2) (1p3) (1p4) (1p5) (1p6) (1p7) (1p8)};

           \node[font=\small,rectangle,inner sep=5pt, above left=1.0cm and 0.5cm of 1p2] (curve) {Curve};
           \path[->] (1p2) edge (curve);

The end result looks like this:

TikZ tree with surrounded nodes

and contrary to my expectation, its pretty easy to use this method for a lot of paths just by copy-pasting and using regular expressions. While this solves my problem for now, it is not the solution to my question. A proper solution would still be really helpful!

user34812
  • 325
  • 1
    Use the hobby package from Andrew Stacey http://tex.stackexchange.com/questions/54771/curve-through-a-sequence-of-points-with-metapost-and-tikz . You can search for examples on the main site. – percusse Aug 09 '13 at 05:56
  • @percusse I don't think that solves my problem. the hobby package still requires the points through which the curve should pass! – user34812 Aug 09 '13 at 06:06
  • 1
    So use the node anchors of the tree children? – percusse Aug 09 '13 at 06:13
  • No. I don't want the curve to pass through the nodes themselves. I want it to surround them. I think I made that pretty clear in the image. – user34812 Aug 09 '13 at 06:16
  • 1
    Again, you can use children nodes to give some relevant points such as 3mm left of S12 or 1cm above of S11 etc. They are not necessarily meant to be the nodes themselves – percusse Aug 09 '13 at 07:16
  • Okay, but is there a simpler way? I have to do this for a lot of paths, so using this approach, I will have to make one or two new nodes per existing node. Furthermore, the paths can be in any zig-zag shape, which makes it even more cumbersome. – user34812 Aug 09 '13 at 07:25
  • Related, though my answer is not what you're after: http://tex.stackexchange.com/questions/35059/tikz-marking-nodes-in-a-binary-tree/ – Torbjørn T. Aug 09 '13 at 08:19
  • 1
    Also related: http://tex.stackexchange.com/q/71638/86 – Andrew Stacey Aug 09 '13 at 08:34
  • Does each curve enclose the same number of nodes? – Herr K. Aug 09 '13 at 08:50
  • @KevinC: Let's say they do. Does it help? – user34812 Aug 09 '13 at 10:21
  • 1
    If the number of nodes enclosed is always the same, then you can define a macro for once, and use it repeatedly. The one I tried is this: \newcommand\enclose[4]{ \draw[thin,red,rounded corners] ($(#1.north)+(0,3mm)$) -- ($(#1.west) +(-3mm,0)$) -- ($(#2.west) +(-3mm,0)$) -- ($(#3.west) +(-3mm,0)$) -- ($(#4.west) +(-3mm,0)$) -- ($(#4.south)+(0,-2mm)$) -- ($(#4.east) +(2mm,0)$) -- ($(#3.east) +(2mm,0)$) -- ($(#2.east) +(2mm,0)$) -- ($(#1.east) +(2mm,0)$) -- cycle; }. To use it: put \enclose{S}{S1}{S11}{S111} or \enclose{S}{S2}{S21}{S212} after the tree. – Herr K. Aug 09 '13 at 11:53
  • BTW, you need to load the calc library for the above method. If the number of enclosed nodes varies, then I think a variation of the method in Andrew Stacey's link would work (but I haven't tried). – Herr K. Aug 09 '13 at 11:56

1 Answers1

2

Here's my attempt. Basically it draws a "double line" beneath the path of the selected nodes in such a way that the lines appear to have "enclosed" the selected nodes with a curve. (Note that I also change the use of obsolete command \tikzstyle to \tikzset)

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning,automata,backgrounds}
\definecolor{light-gray}{gray}{0.6}

\begin{document}

\begin{tikzpicture}[line width=.1cm,shorten >=0pt,auto,on grid=false, every state/.style={minimum size=0pt}, level distance=2.0cm, level 1/.style={sibling distance=2cm}, level 2/.style={sibling distance=1cm}, level 3/.style={sibling distance=.5cm}]
\tikzset{every node/.style={font=\tiny , circle, outer sep=0pt, inner sep=0pt}}
           \node[state] (S) {}
           child {node[state] (S1) {}
              child {node[state] (S11) {}
                 child {node[state] (S111) {} }
                 child {node[state] (S112) {} }
              }
              child {node[state] (S12) {}
                 child {node[state] (S121) {} }
                 child {node[state] (S122) {} }
              }
           }
           child {node[state] (S2) {}
              child {node[state] (S21) {}
                 child {node[state] (S211) {} }
                 child {node[state] (S212) {} }
              }
              child {node[state] (S22) {}
                 child {node[state] (S221) {} }
                 child {node[state] (S222) {} }
              }
           };

\begin{scope}[on background layer]
\draw[double distance=5mm,line width=0.05cm,line join=round,line cap=round,red]
  (S)--(S1)--(S12); % loose enclosure
\draw[double distance=2mm,line width=0.05cm,line join=round,line cap=round,blue]
  (S)--(S2)--(S21)--(S212); % tight enclosure
\end{scope}

\end{tikzpicture}
\end{document}

enter image description here

Herr K.
  • 17,946
  • 4
  • 61
  • 118