26

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

enter image description here

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}
21

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} {
  let
    \p1 = ($(hullnode\currentnode)!#2!-90:(hullnode\previousnode)$),
    \p2 = ($(hullnode\currentnode)!#2!90:(hullnode\nextnode)$),
    \p3 = ($(\p1) - (hullnode\currentnode)$),
    \n1 = {atan2(\y3,\x3)},
    \p4 = ($(\p2) - (hullnode\currentnode)$),
    \n2 = {atan2(\y4,\x4)},
    \n{delta} = {-Mod(\n1-\n2,360)}
  in 
    {-- (\p1) arc[start angle=\n1, delta angle=\n{delta}, radius=#2] -- (\p2)}
}
-- 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

| improve this answer | |
  • Muchas gracias!! – Felipe Aguirre Sep 10 '12 at 21:02
  • 3
    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
25

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}
| 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
  • 2
    @FelipeAguirre: new question opened Hobby path realization in convex hull approach. – Claudio Fiandrino Sep 15 '12 at 9:51

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.