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.

To make it simple, I want to highlight a group of tikz nodes like in the following picture

It was borrowed from the JLatexEditor. I would like to know which Tikz commands I can use to do the job in order to automatize this task for several trees I have to make. It is important to keep the blending effect of colors like in node g. Here is the MWE also borrowed from JLatexEditor:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{arrows,backgrounds,calc,trees}

\begin{document}
\thispagestyle{empty}

\begin{tikzpicture}
\node (f) {f}
    child { node (g) {g}
      child { node (a) {a}
    }
      child { node (b) {b}
    }
  }
    child { node (h) {h}
      child { node (c) {c}
    }
  };
\end{tikzpicture}

\end{document}
share|improve this question

2 Answers 2

up vote 13 down vote accepted

You can use Jake's answer to padded boundary of convex hull and layers:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,backgrounds,calc,trees}

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


\newcommand{\convexpath}[2]{
[   
    create hullnodes/.code={
        \global\edef\namelist{#1}
        \foreach [count=\counter] \nodename in \namelist {
            \global\edef\numberofnodes{\counter}
            \node at (\nodename) [draw=none,name=hullnode\counter] {};
        }
        \node at (hullnode\numberofnodes) [name=hullnode0,draw=none] {};
        \pgfmathtruncatemacro\lastnumber{\numberofnodes+1}
        \node at (hullnode1) [name=hullnode\lastnumber,draw=none] {};
    },
    create hullnodes
]
($(hullnode1)!#2!-90:(hullnode0)$)
\foreach [
    evaluate=\currentnode as \previousnode using \currentnode-1,
    evaluate=\currentnode as \nextnode using \currentnode+1
    ] \currentnode in {1,...,\numberofnodes} {
-- ($(hullnode\currentnode)!#2!-90:(hullnode\previousnode)$)
  let \p1 = ($(hullnode\currentnode)!#2!-90:(hullnode\previousnode) - (hullnode\currentnode)$),
    \n1 = {atan2(\x1,\y1)},
    \p2 = ($(hullnode\currentnode)!#2!90:(hullnode\nextnode) - (hullnode\currentnode)$),
    \n2 = {atan2(\x2,\y2)},
    \n{delta} = {-Mod(\n1-\n2,360)}
  in 
    {arc [start angle=\n1, delta angle=\n{delta}, radius=#2]}
}
-- cycle
}

\begin{document}
\thispagestyle{empty}

\begin{tikzpicture}
\node (f) {f}
    child { node (g) {g} 
      child { node (a) {a}
    }
      child { node (b) {b}
    }
  }
    child { node (h) {h}
      child { node (c) {c}
    }
  };
\begin{pgfonlayer}{background}
\fill[red,opacity=0.3] \convexpath{a,g,b}{8pt};
\fill[blue,opacity=0.3] \convexpath{g,f,h,c,h,f}{8pt};
\end{pgfonlayer}
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
    
Muchas gracias!! –  Felipe Aguirre Sep 10 '12 at 21:02
1  
I found a particularity of your method that I think it is worth signaling in this post. The nodes have to be enumerated in the order of the clockwise direction (As it was stated in Jake's question). Otherwise, it will render a wrong convex hull. So, \convexpath{a,g,b} is correct, but \convexpath{a,b,g} is not. –  Felipe Aguirre Sep 11 '12 at 12:58

The use of the hobby package here leads to a very similar result to the picture posted by the OP:

enter image description here

I was in doubt if posting this answer because it's pretty much the same of the one given in Highlighting some nodes of a TikZ binomial tree, but it could be seen as a better example of use of the hobby package. The point is that in the answer Highlighting some nodes of a TikZ binomial tree several [tension in]s were used, but I saw that the result could be improved by simply adding more points along the curve. This from one hand complicate a bit the path definition, but I think is a good price to pay seeing the result.

The code:

\documentclass[a4paper,11pt]{article}
\usepackage{tikz}
\usetikzlibrary{hobby,backgrounds,calc,trees}

\begin{document}
\begin{tikzpicture}
\node (f) {f}
    child { node (g) {g}
      child { node (a) {a}
    }
      child { node (b) {b}
    }
  }
    child { node (h) {h}
      child { node (c) {c}
    }
  };

  \begin{pgfonlayer}{background}
  \draw[blue,fill=blue,opacity=0.2](f.north) to[closed,curve through={($(f.south west)!0.5!(g.north west)$) .. (g.south west) .. (h.south west) .. (c.south west) .. (c.south east) .. ($(c.north east)!0.5!(h.south east)$) .. (h.east).. ($(h.north east)!0.5!(f.south east)$)}](f.north);
  \draw[red,fill=red,opacity=0.2](g.north) to[closed,curve through={($(g.south west)!0.5!(a.north west)$) .. (a.south west) .. (a.south east) ..(b.south west) .. (b.south east) .. ($(b.north east)!0.5!(g.south east)$) }] (g.north);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}
share|improve this answer
    
Woah, that looks really good! Can you combine that with the convex hull approach so you only need to provide the list of nodes that you want enveloped? –  Jake Sep 11 '12 at 7:45
1  
Thanks Jake, but the most of the credit should go to Andrew's great package :) Regarding the question: yes, it's really a good idea. I'll have a look as soon as possible! –  Claudio Fiandrino Sep 11 '12 at 7:47
    
Your method renders a much better looking output, but I really need the task to be automatized like @Gonzalo Medina did with \convexpath{a,g,b}{8pt}. I'll keep Gonzalo's answer as the accepted one. But I will really love to see a combination of both solutions like @Jake proposes. –  Felipe Aguirre Sep 11 '12 at 12:32
1  
I vote for opening a question! –  Felipe Aguirre Sep 13 '12 at 12:28
1  
@FelipeAguirre: new question opened Hobby path realization in convex hull approach. –  Claudio Fiandrino Sep 15 '12 at 9:51

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.