share
TeX - LaTeXHow can we draw a Christmas tree with decorations, using TikZ?
[+210] [19] Stefan Kottwitz
[2011-12-22 22:04:22]
[ tikz-pgf trees fun ]
[ https://tex.stackexchange.com/questions/39149/how-can-we-draw-a-christmas-tree-with-decorations-using-tikz ]

I would like to use TikZ for drawing a christmas tree. Here's a start, I used the lindenmayersystems library for drawing a tree:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\begin{document}
\begin{tikzpicture}
\draw [color=green!50!black, l-system={rule set={S -> [+++G][---G]TS,
  G -> +H[-G]L, H -> -G[+H]L, T -> TL, L -> [-FFF][+FFF]F}, step=4pt, angle=18,
 axiom=+++++SLFFF, order=11}] lindenmayer system -- cycle;
\end{tikzpicture}
\end{document}

Fractal tree

I found the tree in "The Science of fractal images" by Peitgen and Saupe.

Who can help to decorate it? Or to draw another tree with Christmas decorations, such as tinsel garland (lametta), candles, baubles (Christmas balls), a tree topper? Perhaps add a shading to the green?

For celebrating Christmas, I would like to put the tree on our blog [1], and on the TikZ example gallery [2].

(1) I don't know if I'll get a chance to figure out the details of this so I'll record the idea as inspiration for domeone else to realise: for tinsel, try a curve with the snake decoration and rounded corners as in tex.stackexchange.com/q/38989/86 by adjusting the parameters then you get quite a variety of tinsel-like effects - Andrew Stacey
(Botheration. The iPad keyboard strikes again: "someone". And I haven't the accuracy to hit the "edit" link.) - Andrew Stacey
(5) I'm very happy Kjell accepts your offer to become the new maintainer of TeXample.net. It's a very good news ! Happy christmas Stephan !! - Alain Matthes
Right. Now for the next challenge draw Santa falling out of a chimney covered in soot... :) - McGafter
[+136] [2011-12-23 21:16:37] Alain Matthes [ACCEPTED]

Merry Christmas everyone!

Christmas tree with balls, candles and snowflakes

Now pic is very useful. An update was necessary

Instead of

\newsavebox{\mycandle}
\savebox{\mycandle}{ 
\begin{tikzpicture}[scale=.1]
\shade[top color=yellow,bottom color=red] (0,0) .. controls (1,.2) and (1,.5) .. (0,2) .. controls (-1,.5)  and  (-1,.2) .. (0,0);
\fill[yellow!90!black] (.8,0) rectangle (-.8,-5); 
\end{tikzpicture} }

\tikzset{ mycandle/.pic ...

The code

% !TEX TS-program = pdflatex
\documentclass[border=2mm]{standalone}
\usepackage[usenames,dvipsnames]{xcolor} 
\usepackage{tikz}

\usetikzlibrary{ shapes,decorations.shapes,decorations.fractals,decorations.markings,shadows}

\tikzset{ mycandle/.pic={
\shade[top color=yellow,bottom color=red] (0,0) .. controls (1,.2) and (1,.5) .. (0,2) .. controls (-1,.5)  and  (-1,.2) .. (0,0);
\fill[yellow!90!black] (.8,0) rectangle (-.8,-5); }}

\tikzset{
  paint/.style={draw=#1!50!black, fill=#1!50},
  my star/.style={decorate,decoration={shape backgrounds,shape=star},star points=#1}}

\begin{document}
  \begin{tikzpicture}[every pic/.style={scale=.1,transform shape}  ,
    ball red/.style={
    decorate, decoration={ markings,mark=between positions .2 and 1 step 3cm
      with
      { \pgfmathsetmacro{\sz}{2 + .5 * rand}
        \path[shading=ball,ball color=red] (0,0) circle[radius=\sz mm]; }}},
        ball blue/.style={decorate, decoration={ markings, mark=between positions 0.1 and .9 step 3cm
      with {\pgfmathsetmacro{\sz}{2 + .5 * rand}
        \path[shading=ball,ball color=blue] (0,0) circle[radius=\sz mm]; }}}]

\draw[fill=Maroon,ultra thick] 
      (.75,-1)  ..  controls (.5,.5)  and   (.5,3)    .. (0.5,4) 
   -- (-0.5,4)  ..  controls (-.5,3) and (-.5,.5)     .. (-.75,-1) ;
\draw[ultra thick,fill=green!50!black] 
      (0,10) .. controls  (0,8)     and   (1,7)    .. (1.5,7) 
             ..  controls (1,7)     and   (1,7)    .. (0.5,7.25) 
             ..  controls (1.5,5)   and   (2.5,4)  .. (3,4)
             ..  controls (2,4)     and   (1.25,4) .. (1,4.5)
             ..  controls (2,2)     and   (3.5,2)  .. (4,2)
             ..  controls (1,1)     and   (-1,1)   .. (-4,2) 
             ..  controls (-3.5,2)  and   (-2,2)   .. (-1,4.5)
             ..  controls (-1.25,4) and   (-2,4)   .. (-3,4) 
             ..  controls (-2.5,4)  and   (-1.5,5) .. (-0.5,7.25) 
             ..  controls  (-1,7)   and   (-1,7)   .. (-1.5,7)
             ..  controls  (-1,7)   and   (0,8)    .. (0,10)
              ;

\pic foreach \candle in {(2,5),(-2,5),(0.5,7.5),(-0.5,7.5),(-3,2.5), (3,2.5),
                    (1.5,1.75),(-1.5,1.75)} at \candle {mycandle} ; 

\node [star, star point height=.5cm, minimum size=.5cm,draw,fill=yellow,thick]
      at (0,10) {};
\begin{scope}[decoration={shape sep=.2cm, shape size=.25cm}] 
    \draw [my star=6, paint=red]  (-4,2)
             ..  controls (0,2)     and   (1,3.5)   .. (1,4.40); 
    \draw [my star=6, paint=red]  (-1.5,5.40)
             ..  controls (0,5.40)     and   (0.5,6.5)      .. (0.5,7);  
    \draw [my star=6, paint=blue]  (4,2)
             ..  controls  (0,2) and (-1,3.5)      .. (-1,4.40);             
    \draw [my star=6, paint=blue]  (1.5,5.40)
             ..  controls (0,5.40)     and   (-0.5,6.5)      .. (-0.5,7);     
\end{scope} 
% the balls
\path[ball red] 
      (0,10) .. controls  (0,8)     and   (1,7)    .. (1.5,7) 
             ..  controls (1,7)     and   (1,7)    .. (0.5,7.25) 
             ..  controls (1.5,5)   and   (2.5,4)  .. (3,4)
             ..  controls (2,4)     and   (1.25,4) .. (1,4.5)
             ..  controls (2,2)     and   (3.5,2)  .. (4,2)
             ..  controls (1,1)     and   (-1,1)   .. (-4,2) 
             ..  controls (-3.5,2)  and   (-2,2)   .. (-1,4.5)
             ..  controls (-1.25,4) and   (-2,4)   .. (-3,4) 
             ..  controls (-2.5,4)  and   (-1.5,5) .. (-0.5,7.25) 
             ..  controls  (-1,7)   and   (-1,7)   .. (-1.5,7)
             ..  controls  (-1,7)   and   (0,8)    .. (0,10)
              ; 
\path[ball blue] 
      (0,10) .. controls  (0,8)     and   (1,7)    .. (1.5,7) 
             ..  controls (1,7)     and   (1,7)    .. (0.5,7.25) 
             ..  controls (1.5,5)   and   (2.5,4)  .. (3,4)
             ..  controls (2,4)     and   (1.25,4) .. (1,4.5)
             ..  controls (2,2)     and   (3.5,2)  .. (4,2)
             ..  controls (1,1)     and   (-1,1)   .. (-4,2) 
             ..  controls (-3.5,2)  and   (-2,2)   .. (-1,4.5)
             ..  controls (-1.25,4) and   (-2,4)   .. (-3,4) 
             ..  controls (-2.5,4)  and   (-1.5,5) .. (-0.5,7.25) 
             ..  controls  (-1,7)   and   (-1,7)   .. (-1.5,7)
             ..  controls  (-1,7)   and   (0,8)    .. (0,10)
              ; 
 % the snow
\foreach \i in {0.5,0.6,...,1.6}
     \fill [white!80!blue,decoration=Koch snowflake,opacity=.9]
           [shift={(rand*5,rnd*8)},scale=\i]
           [double copy shadow={opacity=0.2,shadow xshift=0pt,
           shadow yshift=3*\i pt,fill=white,draw=none}]
        decorate {
          decorate {
            decorate {
              (0,0) -- ++(60:1) -- ++(-60:1) -- cycle
            }
          }
        };                  
\end{tikzpicture}
\end{document} 

enter image description here


(11) I love the elegance of this one. - Andrew Stacey
(2) Beautiful! I put this one to our blog right now. - Stefan Kottwitz
(4) I like the Koch snowflakes! Great idea. - Harold Cavendish
(4) The output is nice, but the input didn't look very christmasy so I optimised it a bit in an answer below. - David Carlisle
@AlainMatthes I want to support 'Tents and Trees' puzzle in my logicpuzzle package and need some kind of tree. I've modified your tree a bit. May I kindly ask you for a waiver (based on cc-wiki) to use your code in logicpuzzle.sty and license it under LPPL? - Josef
@Josef No problem for me, you can use it like you want - Alain Matthes
1
[+122] [2011-12-23 20:45:21] Andrew Stacey

Christmas Tree

Just in case the code isn't clear from behind the picture, here it is in full:

\documentclass{article}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{%
  lindenmayersystems,
  decorations.pathmorphing,
  decorations.markings,
  shapes.geometric,
  calc%
}
\tikzset{
  tinsel/.style={
    #1,
    rounded corners=10mm,
    ultra thin,
    decorate,
    decoration={
      snake,
      amplitude=.1mm,
      segment length=10,
    }
  },
  baubles/.style={
    decorate,
    decoration={
      markings,
      mark=between positions .3 and 1 step 2cm
      with
      {
        \pgfmathsetmacro{\brad}{2 + .5 * rand}
        \path[shading=ball,ball color=#1] (0,0) circle[radius=\brad mm];
      }
    }
  },
  lights/.style={
    decorate,
    decoration={
      markings,
      mark=between positions 0 and 1 step 1cm
      with
      {
        \pgfmathparse{rand > 0 ? "dart" : "kite"}
        \let\lshape\pgfmathresult
         \pgfmathsetmacro{\tint}{100*rnd}
        \node[rotate=90,\lshape,shading=ball,inner sep=1pt,ball color=red!\tint!yellow] {};
      }
    }
  }
}

\begin{document}
\begin{center}
\tikz[remember picture,overlay] \coordinate (star) at (0,-1);
\end{center}

\lstinputlisting[
  breaklines=true,
  language=TeX,
  basicstyle=\tiny,
  firstline=63,
  lastline=103]{\jobname.tex}

\begin{tikzpicture}[overlay,remember picture]
\path (star) +(-50:7) coordinate (rhs) +(-130:7) coordinate (lhs);
\draw[brown!50!black,line width=5mm,line cap=round] (star) ++(-90:6.8) -- ++(0,-1) coordinate (base);
\node[scale=-1,trapezium,fill=black,minimum size=1cm] at (base) {};
\foreach \height/\colour in {%
  .2/blue,
  .4/yellow,
  .6/red,
  .8/orange,
  1/pink%
} {
  \draw[tinsel=\colour] ($(star)!\height!(lhs)$) to[bend right] ($(star)!\height!(rhs)$);
}
\path (star);
\pgfgetlastxy{\starx}{\stary}
\begin{scope}[xshift=\starx,yshift=\stary,yshift=-7cm]
\draw[color=green!50!black, l-system={rule set={S -> [+++G][---G]TS,  G -> +H[-G]L, H -> -G[+H]L, T -> TL, L -> [-FFF][+FFF]F}, step=4pt, angle=18, axiom=+++++SLFFF, order=11}] lindenmayer system -- cycle;
\end{scope}
\foreach \height/\colour in {%
  .1/pink,
  .3/red,
  .5/yellow,
  .7/blue,
  .9/orange%
} {
  \draw[tinsel=\colour] ($(star)!\height!(lhs)$) to[bend right] ($(star)!\height!(rhs)$);
}
\foreach \height in {.15,.35,...,1} {
  \draw[lights]  ($(star)!\height!(lhs)$) to[bend right] ($(star)!\height!(rhs)$);
}
\foreach \angle/\colour in {
  -50/red,
  -70/yellow,
  -90/blue,
  -110/pink,
  -130/purple%
} {
  \draw[baubles=\colour] (star) -- ++(\angle:7);
}
\node[star,star point ratio=2.5,fill=yellow,minimum size=1cm] at (star) {};
\end{tikzpicture}
\end{document}

(1) Thanks Andrew, posted to texample.net/tikz/examples/christmas-tree-2 ! Kindly tell me if I should change something. - Stefan Kottwitz
@StefanKottwitz Looks great. The only change I'd make would be to put the (star) coordinate at (0,0) - it is at (0,-1) to put it at the right place with respect to the code listing. It just looks a little odd to put it at (0,-1) (but you should check that all the other pieces position correctly - I had quite a time with positioning the original tree). - Andrew Stacey
2
[+108] [2011-12-23 01:32:52] Jake

Another tree that can be decorated:

Merry Christmas, everybody!

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
%
\begin{tikzpicture}
\begin{axis}[
    hide axis, clip=false,
    y domain=0:2*pi,
    samples=30,axis equal, view={45}{20}]

\addplot3 [domain=0:4,surf,shader=flat,z buffer=sort,fill=green!50!brown, draw=green!50!black, line join=bevel] 
    ({(1.3*x-floor(x))*x^0.5*cos(deg(y))},
     {(1.3*x-floor(x))*x^0.5*sin(deg(y))},
     {-5*x});

\addplot3 [domain=0:4.5, samples=10, samples y=0, fill=yellow!85!red, draw=yellow!55!red] ({0},{sin(x/5*360) * (1 - x + floor(x)) },{cos(x/5*360) * (1 - x + floor(x) )  + 0.5}) -- cycle;
\end{axis}
\end{tikzpicture}%
%
\end{document}

3
[+97] [2011-12-24 12:55:36] morbusg

Here's mine:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{scopes,svg.path,shapes.geometric,shadows}
\begin{document}
\begin{tikzpicture}[
  mystar/.style={star, minimum size=2cm, star point ratio=2.5, shade, thick,
    line join=round, color=yellow!80!black, draw=red!20!black,
    top color=yellow!80!white, bottom color=yellow!60!black},
  mytree/.style={scale=0.5, rotate=180, draw=green!60!black, thick,
    line join=round, inner color=green!60!yellow, outer color=green!50!black},
  myball/.style={shade, ball color=#1, circular drop shadow={
    shadow xshift=0pt, shadow yshift=-.5ex, fill=green!40!black}}
  ]
  {[mytree]
  \shadedraw svg "M355,430
    q90,10 105,-85 30,0 50,-30 20,30 50,30 50,-20 100,0 10,88 105,85
    -45,90 -205,25 Q400,520 355,430";
  \shadedraw svg "M380,325
    q83,10 105,-80 25,0 35,-30 20,25 40,30 20,-10 35,-25 20,20 40,25
    25,90 105,82 -15,50 -120,15 -30,-2 -60,12 -30,0 -52,-28
    C490,370 380,360 380,325";
  \shadedraw svg "M435,225
    q65,-8 90,-70 35,40 70,0 25,60 90,70 -30,52 -90,5 -36,48 -73,-3
    C520,254 445,265 435,225";
  \shadedraw svg "M470,139
    q50,5 90,-80 50,90 90,80 -30,30 -50,20 -40,45 -78,0
    Q500,170 470,139";
  }
  %\shadedraw svg[scale=0.5,rotate=180]
  %"M460,532 q50,-8 q77,-45 v-20 a20,13 0 1 1 48,0 v20 q30,40 77,45";
  %pgf/tikz doesn't like the arc operation, as stated in manual

  \node[mystar] at (-9.85,-1) {$\lambda$};

  \shade[myball=blue]   (-9.7,-2.2)   circle (.2cm);
  \shade[myball=red]    (-9.2,-3.8)   circle (.2cm);
  \shade[myball=green]  (-10.3,-4)    circle (.4cm);
  \shade[myball=yellow] (-8.95,-5.4)  circle (.4cm);
  \shade[myball=red]    (-10.7,-6.1)  circle (.4cm);
  \shade[myball=blue]   (-10.8,-5)    circle (.2cm);
  \shade[myball=yellow] (-9.5,-6.7)   circle (.2cm);
  \shade[myball=green]  (-8.3,-7.6)   circle (.4cm);
  \shade[myball=yellow] (-11.7,-7.6)  circle (.4cm);
  \shade[myball=blue]   (-10.5,-7.8)  circle (.2cm);
\end{tikzpicture}
\end{document}

which looks like:

christmastree

Merry Christmas!


(6) So beautiful with only a few lines! - Stefan Kottwitz
I added your tree to the TikZ gallery, is it ok for you? texample.net/tikz/examples/christmas-tree-1 let me know if I should modify or add something. - Stefan Kottwitz
@Stefan: thanks :-)! Sure, gallery is ok. - morbusg
(1) I am curious—why did you put a lambda inside the star? - Harold Cavendish
this wins for quickest to compile :) - Suresh
(3) @Harrold: It was just a small easter egg (for lambda calculus). - morbusg
(7) Easter egg at Christmas. Ha ha ha. (Or "ho ho ho") - Andrew Stacey
It should be written in a plain TeX. - kiss my armpit
(2) @GarbageCollector: Heh, you are absolutely right. However, I get an error with plain which seems to relate to svgpath. - morbusg
4
[+78] [2013-11-17 20:49:25] Andrew Stacey

Having been having fun with straight-edge-and-compass constructions (thanks to What is the simplest way to draw this triangle exactly? [1]), I thought I'd try my hand at a Christmas tree constructed using straight-edge and compass.

Static image of Christmas tree

(The animated version is about 5Mb. I'll have to stick it somewhere other than imgur and link to it.)

\documentclass[
%  handout, % use this to see the final construction
  xcolor=svgnames
]{beamer}
%\url{https://tex.stackexchange.com/q/142210/86}
%\url{https://tex.stackexchange.com/q/39149/86}
\usepackage{tikz}

\usetikzlibrary{decorations.text}

\usepackage[
%  draft
]{rulercompass}

\setbeamertemplate{navigation symbols}{}
\setbeamercolor{background canvas}{bg=Beige}

\pgfdeclarelayer{picture}
\pgfdeclarelayer{points}
\pgfsetlayers{picture,main,points}

\begin{document}
\begin{frame}[plain]
\hfill%
\begin{tikzpicture}[
    stop jumping,
    max size={\textwidth}{\textheight},
    pot/.style={
      draw=brown,
      on layer=picture,
      ultra thick
    },
    trunk/.style={
      draw=brown!50!black,
      on layer=picture,
      ultra thick
    },
    tree/.style={
      draw=green!50!black,
      on layer=picture,
      ultra thick
    },
    bauble/.style={
      fill=yellow,
      ultra thick,
      on layer=picture,
    },
    star/.style={
      draw=yellow,
      fill=red!50!black,
      on layer=picture
    },
    ruler compass,
    draft label/.style={
      reset label anchor,
      above,
      font=\tiny
    },
    every segment/.style={
    },
    every compass/.style={
      overlay,
    },
    every point/.style={
      node on layer=points,
      minimum size=1mm,
    },
    every arc/.style={
      on layer=picture,
      ultra thick
    },
    construction in use/.style={
      draw=gray!50,
    },
    construction not in use/.style={
      draw=gray!50,
    },
  ]
\path (0,0) node[name=0,ruler compass/point=red];
\path (0,1) node[name=1,ruler compass/point=red];
\pause
\ruler<+->[ruler compass/ruler length=40]{0}{1}
\compass<+->{0}{1}
\point<.->{r-0-1}{c-0-1}{2}
\compass<+->{1}{a}
\point<.->{r-0-1}{c-1-a}{1}
\compass<+->{a}{1}
\point<.->{c-a-1}{c-1-a}{1}
\point<.->{c-a-1}{c-1-a}{2}
\compass<+->{b}{c}
\compass<+->{b}{a}
\point<.->{c-b-a}{r-0-1}{1}
\compass<+->{e}{b}
\point<.->{c-e-b}{c-b-a}{1}
\point<.->{c-e-b}{c-b-a}{2}
\point<.->{c-e-b}{r-0-1}{1}
\ruler<+->{c}{g}
\ruler<.->{d}{f}
\compass<+->{h}{g}
\compass<+->{a}{g}
\ruler<+->{c}{d}
\point<.->{r-c-d}{c-0-1}{1}
\point<.->{r-c-d}{c-0-1}{2}
\compass<+->{b}{1}
\point<.->{c-b-1}{r-0-1}{1}
\compass<+->{b}{0}
\point<.->{c-b-0}{r-0-1}{1}
\ruler<+->{f}{g}
\compass<+->{k}{l}
\point<.->{c-k-l}{r-f-g}{1}
\point<.->{c-k-l}{r-f-g}{2}
\ruler<+->{i}{m}
\ruler<+->{j}{n}
\point<.->{r-j-n}{c-h-g}{2}
\point<.->{r-i-m}{c-h-g}{2}
\point<.->{r-j-n}{c-a-g}{1}
\point<.->{r-i-m}{c-a-g}{1}
\compass<+->{q}{o}
\compass<.->{r}{p}
\point<.->{c-q-o}{r-j-n}{1}
\point<.->{c-r-p}{r-i-m}{1}
\draw<.->[pot] (g) arc[centred arc to={a}{q}]
 (f) arc[arc flip,centred arc to={a}{r}];
\draw<.->[trunk] (o) -- (s) (p) -- (t);
\draw<.->[pot] (d) arc[centred arc to={b}{c}] -- (g) arc[arc flip,centred arc to={h}{f}] -- cycle;
\point<.->{c-h-g}{r-0-1}{1}
\compass<+->{u}{s}
\point<.->{c-u-s}{r-0-1}{1}
\compass<+->{v}{s}
\compass<+->{v}{u}
\point<.->{c-v-u}{r-0-1}{1}
\compass<+->{u}{w}
\compass<+->{w}{u}
\point<.->{c-u-w}{c-w-u}{1}
\point<.->{c-u-w}{c-w-u}{2}
\compass<+->{x}{v}
\compass<+->{y}{v}
\point<.->{c-x-v}{c-v-s}{2}
\point<.->{c-y-v}{c-v-s}{2}
\draw<.->[tree]
  (v)
  arc[centred arc to={x}{z}]
  arc[arc flip,centred arc to={v}{aa}]
  arc[centred arc to={y}{v}]
;
\compass<+->{v}{h}
\point<.->{c-v-h}{c-y-v}{2}
\point<.->{c-v-u}{c-y-v}{2}
\point<.->{c-v-u}{c-x-v}{2}
\point<.->{c-v-h}{c-x-v}{2}
\ruler<+->{ab}{ad}
\compass<+->{ab}{ad}
\compass<+->{ad}{ab}
\point<.->{c-ab-ad}{c-ad-ab}{1}
\compass<+->{af}{ab}
\point<.->{c-v-h}{r-i-m}{2}
\compass<+->{h}{ag}
\point<.->{c-v-h}{c-h-ag}{2}
\compass<+->{ag}{h}
\point<.->{c-v-h}{c-ag-h}{1}
\compass<+->{ai}{ag}
\point<.->{c-v-h}{c-ai-ag}{1}
\foreach[remember=\tpt as \ppt (initially i)] \tpt in {j,...,o}
{
  \compass<+->{a\tpt}{a\ppt}
  \point<.->{c-v-h}{c-a\tpt-a\ppt}{1}
}
\compass<+->{ah}{h}
\point<.->{c-v-h}{c-ah-h}{2}
\compass<+->{aq}{ah}
\point<.->{c-v-h}{c-aq-ah}{1}
\foreach[remember=\tpt as \ppt (initially q)] \tpt in {r,...,w}
{
  \compass<+->{a\tpt}{a\ppt}
  \point<.->{c-v-h}{c-a\tpt-a\ppt}{1}
}
\point<.->{c-v-u}{r-i-m}{2}
\compass<+->{u}{ay}
\compass<.->{ay}{u}
\point<.->{c-v-u}{c-ay-u}{1}
\compass<+->{az}{ay}
\point<.->{c-v-u}{c-az-ay}{1}
\point<.->{c-v-u}{c-u-ay}{2}
\compass<+->{bb}{u}
\point<.->{c-v-u}{c-bb-u}{2}
\compass<+->{bc}{bb}
\point<.->{c-v-u}{c-bc-bb}{1}
\compass<+->{bd}{bc}
\point<.->{c-bd-bc}{c-af-ab}{2}
\foreach[remember=\tpt as \ppt (initially d)] \tpt in {e,...,n}
{
  \compass<+->{b\tpt}{b\ppt}
  \point<.->{c-af-ab}{c-b\tpt-b\ppt}{2}
}
\foreach \bctr/\brad in {
  h/ag,
  aj/ai,
  am/al,
  ap/ao,
  ar/aq,
  au/at,
  ax/aw,
  ba/az,
  u/ay,
  bd/bc,
  bg/bf,
  bj/bi,
  bm/bl%
}
{
  \path<.->[bauble] (\bctr) to[circle through] (\brad);
}
\point<.->{c-ad-ab}{r-0-1}{1}
\compass<+->{v}{bp}
\compass<+->{bp}{v}
\point<.->{c-v-bp}{r-0-1}{2}
\compass<+->{bq}{v}
\point<.->{c-v-bp}{c-bp-v}{1}
\point<.->{c-v-bp}{c-bp-v}{2}
\point<.->{c-v-bp}{c-bq-v}{1}
\point<.->{c-v-bp}{c-bq-v}{2}
\fill<.->[star] (bp) -- (bu) -- (bt) -- cycle (bs) -- (br) -- (bq) -- cycle;
\compass<+->{b}{y}
{\huge
\path<+->[decorate,decoration={text along path,text align=center,text={Have a Constructive Christmas}}] (y) arc[arc flip,centred arc to={b}{x}];
}
\end{tikzpicture}%
\hspace*{\fill}%
\end{frame}
\end{document}

You also need the style file (save as rulercompass.sty) which also incorporates quite a few things from other questions and answers on this site:

\ProvidesPackage{rulercompass}
\usepackage{alphalph}
\usetikzlibrary{intersections,calc}

\newif\ifrc@draft
\newif\ifrc@beamer
\newif\ifrc@fliparc

\@ifclassloaded{beamer}{%
  \rc@beamertrue
}{}

\DeclareOption{draft}{%
  \rc@drafttrue
}

\DeclareOption{beamer}{%
  \rc@beamertrue
}

\ProcessOptions

\newcounter{pointlabels}
\setcounter{pointlabels}{0}
\resetcounteronoverlays{pointlabels}

\ifrc@beamer
\tikzset{
  onslide/.code args={<#1>#2}{%
    \only<#1>{\pgfkeysalso{#2}}%
  },
  alt/.code args={<#1>#2#3}{%
    \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}}%
  },
  alt if exist/.code args={#1#2#3}{%
    \@ifundefined{path@#1}{%
      \pgfkeysalso{#2}%
    }{
      \alt<.-\csname path@#1\endcsname>{%
        \pgfkeysalso{#2}%
      }{
        \pgfkeysalso{#3}%
      }%
    }%
  },
  intersection/save/.code={%
    \begingroup
    \only<.>{%
    \tikz@intersect@path@names@parse#1\tikz@stop
    \protected@write\pgfutil@auxout{}{%
        \string\global\string\@namedef{path@\tikz@intersect@path@a}{\the\beamer@slideinframe}%
        \string\global\string\@namedef{path@\tikz@intersect@path@b}{\the\beamer@slideinframe}%
    }%
    }%
    \endgroup
  }
}

\newcommand<>\compass[3][]{%
  \draw#4[#1,ruler compass/compass={#2}{#3}];
}

\newcommand<>\ruler[3][]{%
  \draw#4[#1,ruler compass/ruler={#2}{#3}];
}

\newcommand<>\point[4][]{%
  \path#5 [name intersections={use=#2 and #3}] (intersection-#4) node[ruler compass/point,#1];
}

\else

\tikzset{
  alt if exist/.code args={#1#2#3}{%
    \pgfkeysalso{#2}%
  },
  onslide/.code args={<#1>#2}{%
    \pgfkeysalso{#2}%
  },
  intersection/save/.code={%
    \begingroup
    \tikz@intersect@path@names@parse#1\tikz@stop
    \protected@write\pgfutil@auxout{}{%
        \string\global\string\@namedef{path@\tikz@intersect@path@a}{\the\beamer@slideinframe}%
        \string\global\string\@namedef{path@\tikz@intersect@path@b}{\the\beamer@slideinframe}%
    }%
    \endgroup
  }
}

\newcommand\compass[2]{%
  \draw[ruler compass/compass={#1}{#2}];
}

\newcommand\ruler[2]{%
  \draw[ruler compass/ruler={#1}{#2}];
}

\newcommand\point[4][]{%
  \path [name intersections={use=#2 and #3}] (intersection-#4) node[ruler compass/point,#1];
}

\fi    

\tikzset{
  intersection/use/.style={%
    of=#1,
    save=#1,
  },
  circle through/.style={
    to path={
      \pgfextra{
        \tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax
        \pgf@xa=\pgf@x
        \pgf@ya=\pgf@y
        \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
        \pgfmathsetmacro\rc@radius{veclen(\pgf@x - \pgf@xa,\pgf@y - \pgf@ya)}%
      }
      circle[radius=\rc@radius pt] (\tikztotarget)
    }
  },
  arc flip/.is if=
rc@fliparc,
  centred arc to/.code 2 args={%
    \tikz@scan@one@point\pgfutil@firstofone(#1)\relax
    \pgfmathsetmacro\rc@radius{veclen(\tikz@lastx-\pgf@x,\tikz@lasty-\pgf@y)}%
    \pgfmathsetmacro\rc@sangle{atan2(\tikz@lasty - \pgf@y,\tikz@lastx - \pgf@x)}%
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone(#2)\relax
    \pgfmathsetmacro\rc@eangle{atan2(\pgf@y - \pgf@ya,\pgf@x - \pgf@xa)}%
    \pgfmathsetmacro\rc@eangle{\rc@eangle < \rc@sangle ? \rc@eangle +       360 : \rc@eangle}%
    \ifrc@fliparc
    \pgfmathsetmacro\rc@eangle{\rc@eangle - 360}%
    \fi
    \pgfkeysalso{start angle=\rc@sangle, end angle=\rc@eangle, radius=\rc@radius pt}
  },
  ruler compass/.is family,
  ruler compass/.cd,
  construction in use/.style={
    draw=blue
  },
  construction not in use/.style={
    draw=gray!75,
  },
  compass/.style 2 args={
    alt if exist={c-#1-#2}{
      ruler compass/construction in use/.try,
    }{
      ruler compass/construction not in use/.try
    },
    name path=c-#1-#2,
    ruler compass/every construction path/.try,
    ruler compass/every compass/.try,
    insert path={
      (#1) to[circle through] (#2)
      node[name=c-#1-#2-centre,ruler compass/aux point={#1}]
      node[name=c-#1-#2-rim,ruler compass/aux point={#2}]
    },
  },
  ruler/.style 2 args={
    overlay,
    alt if exist={r-#1-#2}{
      ruler compass/construction in use/.try
    }{
      ruler compass/construction not in use/.try
    },
    name path=r-#1-#2,
    ruler compass/every construction path/.try,
    ruler compass/every ruler/.try,
    insert path={
      ($(#1)!\pgfkeysvalueof{/tikz/ruler compass/ruler length}!(#2)$) -- ($(#2)!\pgfkeysvalueof{/tikz/ruler compass/ruler length}!(#1)$)
      node[name=r-#1-#2-start,ruler compass/aux point={#1}]
      node[name=r-#1-#2-end,ruler compass/aux point={#2}]
    },
  },
  ruler length/.initial=20,
  aux point/.style={
    circle,
    minimum width=4mm,
    onslide=<.|handout:0>{draw=red},
    node contents={},
    at={(#1)},
    ruler compass/every aux point/.try
  },
  point/.style={
    ruler compass/name it,
    coordinate,
    node contents={},
    ruler compass/every point/.try,
    insert path={
      node[
        fill=#1,
        circle,
        minimum width=1mm,
        inner sep=0mm,
        reset label anchor,
        anchor=center,
        node contents={}
        ]
    }
  },
  name it/.code={%
    \ifx\tikz@fig@name\pgfutil@empty
    \stepcounter{pointlabels}%
    \pgfkeysalso{name=\alphalph{\value{pointlabels}}}%
    \ifrc@draft
    \pgfkeysalso{label={[ruler compass/draft label/.try]\alphalph{\value{pointlabels}}}}%
    \fi
    \fi
  },
  point/.default=black,
}

\newcounter{jumping}
\resetcounteronoverlays{jumping}
\def\rc@scale{1}

\def\jump@setbb#1#2#3{%
  \@ifundefined{jump@#1@maxbb}{%
    \expandafter\gdef\csname jump@#1@maxbb\endcsname{#3}%
  }{%
    \csname jump@#1@maxbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #3
    \pgfmathsetlength\pgf@x{max(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{max(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@maxbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
  \@ifundefined{jump@#1@minbb}{%
    \expandafter\gdef\csname jump@#1@minbb\endcsname{#2}%
  }{%
    \csname jump@#1@minbb\endcsname
    \pgf@xa=\pgf@x
    \pgf@ya=\pgf@y
    #2
    \pgfmathsetlength\pgf@x{min(\pgf@x,\pgf@xa)}%
    \pgfmathsetlength\pgf@y{min(\pgf@y,\pgf@ya)}%
    \expandafter\xdef\csname jump@#1@minbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
  }
}

\tikzset{
  stop jumping/.style={
    execute at end picture={%
      \stepcounter{jumping}%
      \pgfmathsetlength\pgf@xa{\pgf@picminx/\rc@scale}%
      \pgfmathsetlength\pgf@ya{\pgf@picminy/\rc@scale}%
      \pgfmathsetlength\pgf@xb{\pgf@picmaxx/\rc@scale}%
      \pgfmathsetlength\pgf@yb{\pgf@picmaxy/\rc@scale}%
      \immediate\write\pgfutil@auxout{%
        \noexpand\jump@setbb{\the\value{jumping}}{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@yb}}
      },
      \csname jump@\the\value{jumping}@maxbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
      \csname jump@\the\value{jumping}@minbb\endcsname
      \path (\the\pgf@x,\the\pgf@y);
    },
  },
  max size/.code 2 args={%
    \addtocounter{jumping}{1}%
    \pgfutil@ifundefined{jump@\the\value{jumping}@maxbb}{}{%
      \csname jump@\the\value{jumping}@maxbb\endcsname
      \pgf@xa=\pgf@x
      \pgf@ya=\pgf@y
      \csname jump@\the\value{jumping}@minbb\endcsname
      \advance\pgf@xa by -\pgf@x
      \advance\pgf@ya by -\pgf@y
      \pgfmathsetmacro\rc@xratio{\pgf@xa > #1 ? \pgf@xa/#1 : 1}%
      \pgfmathsetmacro\rc@yratio{\pgf@ya > #2 ? \pgf@ya/#2 : 1}%
      \pgfmathsetmacro\rc@scale{1/max(\rc@xratio,\rc@yratio)}%
      \pgfkeysalso{scale=\rc@scale}%
    }
    \addtocounter{jumping}{-1}%
  }
}

\tikzset{
  on layer/.code={
    \pgfonlayer{#1}\begingroup
    \aftergroup\endpgfonlayer
    \aftergroup\endgroup
  },
  node on layer/.code={
    \gdef\node@@on@layer{%
      \setbox\tikz@tempbox=\hbox\bgroup\pgfonlayer{#1}\unhbox\tikz@tempbox\endpgfonlayer\egroup}
    \aftergroup\node@on@layer
  },
  reset label anchor/.code={%
    \let\tikz@auto@anchor=\pgfutil@empty
    \def\tikz@anchor{#1}
  },
  reset label anchor/.default=center
}

\def\node@on@layer{\aftergroup\node@@on@layer}

\endinput
[1] https://tex.stackexchange.com/q/142210/86

Very charming, but I'm getting an error: ./CompassRulerChristmasTree.tex:79: Package pgfkeys Error: I do not know the key '/tikz/node contents' and I am going to ignore it. Perhaps you misspelled it. I'm using MacTeX TeXLive 2013. - sgmoye
Sometimes, with gifsicle -O3 anim.gif > anim_opt.gif one may get the file size optimized by factors up to 1000 and beyond. - AlexG
@sgmoye I use the CVS version of PGF and the node contents is in there. The solution is a bit annoying, but doable: remove every node contents={} line and after every node[...] put an empty brace pair {}. - Andrew Stacey
@AlexG In the end, I made it into a proper video and uploaded it to YouTube: youtu.be/b83GoT62MHI - Andrew Stacey
5
[+68] [2013-12-11 19:45:39] Mark Wibrow

A bit late, but here's a simple Christmas tree for 2016:

\documentclass[border=5]{standalone}
\usepackage{tikz}
\newbox\stereogrambox
\pgfmathdeclarerandomlist{colors}{{red}{green!50!black}{green}{white}{blue}}
\begin{document}
\setbox\stereogrambox=\hbox{%
\begin{tikzpicture}[x=1/2pt,y=1/2pt]
\foreach \x in {0,...,95}
  \foreach \y in {0,...,119}{
    \pgfmathrandomitem\c{colors}
    \fill [fill=\c] (\x,\y) rectangle ++(1,1);
  }
\end{tikzpicture}}%
\begin{tikzpicture}[x=1pt,y=1pt,
stereogram node/.style={inner sep=0, outer sep=0,
  anchor=south, fill=white, execute at begin node=\copy\stereogrambox
}]
\foreach \x in {0,...,1}
  \node [stereogram node] at (\x*52, 0) {};
\clip [shift={(0, 4)}] 
 (0,0) -- (-4,0) -- (-4,4) -- (-18,4) -- (0,52) --
 (18,4) -- (4,4) -- (4,0) -- cycle;
\node [stereogram node] at (2, 0) {};
\end{tikzpicture}
\end{document}

enter image description here

And here's a Christmas tree for 2015:

\RequirePackage{luatex85}
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{backgrounds,arrows.meta}
\pgfdeclarelayer{foreground}
\pgfdeclarelayer{before-background}
\pgfsetlayers{background,before-background,main,foreground}
\usepackage{luacode}
\begin{luacode*}
floor = math.floor
ceil = math.ceil

Maze = {}
Maze.__index = Maze
Maze.NORTH = 90
Maze.SOUTH = 270
Maze.EAST = 0
Maze.WEST = 180

Maze.new = function(r, c)
  local i, j, row, cell
  local obj = {}
  setmetatable(obj, Maze)
  obj.rows = r
  obj.cols = c
  obj:reset()
  return obj
end

Maze.reset = function(self)
  local i, j, row, cell
  self.cells = {}
  for i = 1,self.rows do
    row = {}
    for j = 1,self.cols do
      cell = {visited=false, visitable=true,
        north=true,south=true,east=true, west=true,
        meta=''}
      table.insert(row, cell)
    end
    table.insert(self.cells, row)
  end
end

Maze.visitable = function(self, i, j)
   return self.cells[i] and self.cells[i][j] and 
     self.cells[i][j].visitable 
end

Maze.isVisitable = function(self, i, j)
   return self.cells[i] and self.cells[i][j] and 
     self.cells[i][j].visitable 
end




Maze.setVisitable = function(self, i, j, visitable)
  self.cells[i][j].visitable = visitable
  self.cells[i][j].north = visitable
  self.cells[i][j].south = visitable
  self.cells[i][j].east = visitable
  self.cells[i][j].west = visitable
end

Maze.getMeta = function(self, i, j)
  return self.cells[i][j].meta
end

Maze.setMeta = function(self, i, j, meta)
  self.cells[i][j].meta = meta
end

Maze.create = function(self, start)
  local n, N, x, y, a, b, k, stack
  N = self.rows * self.cols
  for i = 1,self.rows do
    for j = 1,self.cols do
      if not self.cells[i][j].visitable then
        N = N - 1
      end
    end
  end

  start = start or {x=1, y=1}
  x, y = start.x, start.y
  stack = {}
  table.insert(stack, {x=x, y=y})
  self.cells[y][x].visited = true
  visited = 1
  while visited < N do
    x = stack[#stack].x
    y = stack[#stack].y

    n = {}
    if self:isVisitable(y+1, x) and not self.cells[y+1][x].visited then
      table.insert(n, Maze.NORTH)
    end
    if self:isVisitable(y-1, x) and not self.cells[y-1][x].visited then
      table.insert(n, Maze.SOUTH)
    end
    if self:isVisitable(y, x+1) and not self.cells[y][x+1].visited then
      table.insert(n, Maze.EAST)
    end
    if self:isVisitable(y, x-1) and not self.cells[y][x-1].visited then
      table.insert(n, Maze.WEST)
    end

    if #n == 0 then
      table.remove(stack)
    else
      k = n[math.random(#n)]
      if k == Maze.NORTH then
        a, b = x, y+1
        self.cells[y][x].north = false
        self.cells[b][a].south = false
      elseif k == Maze.SOUTH then
        a, b = x, y-1
        self.cells[y][x].south = false
        self.cells[b][a].north = false
      elseif k == Maze.EAST then
        a, b = x+1, y
        self.cells[y][x].east = false
        self.cells[b][a].west = false
      elseif k == Maze.WEST then
        a, b = x-1, y
        self.cells[y][x].west = false
        self.cells[b][a].east = false
      end
      table.insert(stack, {x=a, y=b})
      self.cells[b][a].visited = true
      visited = visited + 1
    end
  end
end

m = Maze.new(70,55)
for i = 1,m.rows do
  for j = 1,m.cols do
    m:setVisitable(i, j, false)
  end
end

-- tree
tree_data = {1,1,1,3,3,3,5,5,7,7,9,11,11,13,15,17,19,23,27,21,
  13,15,17,17,19,21,23,27,29,33,25,
  19,21,21,23,25,27,29,33,35,39,31,25,
  23,25,27,29,31,33,35,37,41,45,37,31,21}
for i, x in ipairs(tree_data) do
  for j = 1, x do
    m:setVisitable(m.rows-i-5, floor((m.cols - x) / 2) + j, true)
    m:setMeta(m.rows-i-5, floor((m.cols - x) / 2) + j, 'green')
  end
end

-- decorations
c = floor(m.cols/2)
colors = {'red', 'orange', 'purple'}
ncolors = 3
for q = 0,3 do
  for j = c-15, c+15 do
    if j < c then
      k  = 3
    else
      k = 1.625
    end
    for r = -1,1 do
      m:setMeta(floor((j - c) / k) + 15 + q * 10 + r, j, 
       colors[math.random(ncolors)])
    end
  end
end

-- star
star_data = {1,1,1,3,3,5,9,15,9,5,3,3,1,1,1}
for i, x in ipairs(star_data) do
  for j = 1, x do
    m:setVisitable(m.rows-i+1, floor((m.cols - x) / 2) + j, true)
    m:setMeta(m.rows-i+1, floor((m.cols - x) / 2) + j, 'yellow')
  end
end


-- trunk
trunk_data = {7,7,9,11}
for i, x in ipairs(trunk_data) do
  for j = 1, x do
    m:setVisitable(m.rows-i-61, floor((m.cols - x) / 2) + j, true)
    m:setMeta(m.rows-i-61, floor((m.cols - x) / 2) + j, 'brown')
  end
end

-- snow
for i = 1,5 do
  for j = 1, m.cols do
   m:setVisitable(i,j, true)
    m:setMeta(i,j, 'white')
  end
end

m:create({x=1, y=1})
m.cells[1][1].west = false
m.cells[m.rows][ceil(m.cols/2)].north = false

\end{luacode*}
\tikzset{
  crayon/.style={line width=0.1cm, line cap=round, draw=#1},
  crayon/.default=none,
  sketch/.style={bend right, out=rand*10, in=180-rand*10}
}

\def\luaprint#1{\directlua{tex.print(#1)}}
\def\ifluacondition#1#2#3{%
  \def\nexta{#2}\def\nextb{#3}%
  \csname if\directlua{tex.print(tostring(#1))}\endcsname%
    \let\next=\nexta%
  \else%
    \let\next=\nextb%
  \fi%
  \next%
}
\begin{document}
\begin{tikzpicture}[show background rectangle,
background rectangle/.style={fill=black!85}, >=stealth]
\foreach \i in {1,...,\luaprint{m.rows}}{
  \foreach \j in {1,...,\luaprint{m.cols}}{
%
\tikzset{shift={(\j,\i)}}
\edef\currentcolor{\luaprint{m:getMeta(\i,\j)}}
\ifluacondition{m:isVisitable(\i,\j)}{
  \begin{pgfonlayer}{before-background}
    \filldraw [\currentcolor!5!black] (0,0) rectangle (1,1);
  \end{pgfonlayer}
}{
  \pgfmathparse{int(random(1,10))}
  \ifnum\pgfmathresult=1
    \shade [top color=white, bottom color=gray]
      (0.5+rand/4,0.5+rand/4) circle [radius=.125];
  \fi
}
\ifluacondition{m.cells[\i][\j].north and not m:isVisitable(\i+1,\j)}{
  \begin{pgfonlayer}{foreground}
    \shade [top color=white, bottom color=gray] 
     (0,0.9) to [sketch] ++(1,0)
     arc (-90:90:.15) to [sketch] ++(-1,0) arc (90:270:.15);
  \end{pgfonlayer}
}{}
\ifluacondition{m.cells[\i][\j].south}
  {\draw [crayon=\currentcolor] (0,0) to [sketch] (1,0);}{}
\ifluacondition{m.cells[\i][\j].west and not m:isVisitable(\i,\j-1)}
  {\draw [crayon=\currentcolor] (0,0) to [sketch] (0,1);}{}
\ifluacondition{m.cells[\i][\j].east}%
  {\draw [crayon=\currentcolor] (1,0) to [sketch] (1,1);}{}
}}
\draw [crayon=red, line width=0.25cm, ->] (0,1.5) -- ++(1.5,0);
\draw [crayon=red, line width=0.25cm, ->] 
  (\luaprint{ceil(m.cols/2)}+.5,\luaprint{m.rows}+.5) -- ++(0,1.5);
\end{tikzpicture}
\end{document}

enter image description here

And here's an invisible tree from a couple of years ago.

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\pagecolor{black}
\usetikzlibrary{shapes.geometric,decorations}
\pgfmathdeclarerandomlist{colors}{{red}{yellow}{pink}{green}{orange}{purple}{blue}{white}}

\newcommand\drawstar[1][]{%
  \pgfmathsetmacro\s{rnd*2+2}
    \pgfmathsetmacro\t{rnd*.5cm+0.5cm}
    \pgfmathsetmacro\y{rand*0.125cm}
    \pgfmathsetmacro\r{rand*180}
    \pgfmathrandomitem{\c}{colors}
    \node [star, fill=\c, star point ratio=\s, rotate=\r, minimum size=\t, inner sep=0pt, every star/.try, #1] at (0cm,\y pt) {};
}
\pgfdeclaredecoration{stars}{start}{
  \state{start}[width=rnd*.5cm+.25cm]{\drawstar}
  \state{final}{\drawstar}
}

\begin{document}

\begin{tikzpicture}[line cap=round, x=1cm,y=1cm,]

\draw [every star/.style={opacity=0.125}, decoration=stars, decorate] 
  \foreach \i in {0,...,5}{ 
 plot [domain=\i*360:\i*360+180, samples=100] (\x/300*cos \x, -\x/150+\x/900*sin \x) };


\draw [every star/.style={opacity=0.5}, decoration=stars, decorate] 
\foreach \i in {0,...,5}{ 
  plot [domain=\i*360+180:\i*360+360, samples=100] (\x/300*cos \x, -\x/150+\x/900*sin \x) };

\drawstar[fill=yellow, minimum size=1.5cm]

\end{tikzpicture}

\end{document}

enter image description here

And another:

\documentclass[tikz, border=0.25cm]{standalone}
\usepackage{tikz}
\pagecolor{black}
\usetikzlibrary{decorations.pathreplacing}
\makeatletter
\newcount\tikzjointhedotsnumber


\pgfdeclaredecoration{join the dots}{initial}{%
  \state{initial}[width=0pt, next state=do dots, persistent precomputation={\global\tikzjointhedotsnumber=1}]{}
  %
  \state{do dots}[width=\pgfdecoratedinputsegmentlength, persistent postcomputation={\global\advance\tikzjointhedotsnumber by1}]{%
    \pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
  }
  %
  \state{final}{%
    % Is the last point the same as the first?
      \pgfpointdiff{\pgfpointdecoratedpathlast}{\pgfpointdecoratedpathfirst}%
      \pgfmathveclen{\the\pgf@x}{\the\pgf@y}%
      \ifdim\pgfmathresult pt=0pt\relax%
        \global\advance\tikzjointhedotsnumber by-1\relax
      \else
        \pgftransformshift{\pgfpointdecoratedpathlast}%
        \pgfcoordinate{@dot-\the\tikzjointhedotsnumber}{\pgfpointorigin}%
      \fi
      % Ok, now we do everything. Draw the dots and place the numbers.
      %
      \c@pgf@counta=\tikzjointhedotsnumber%
      \c@pgf@countb=2\relax%
      \edef\lastdot{\the\tikzjointhedotsnumber}%
      \def\nextdot{2}%
      \pgftransformreset%
      \pgfmathloop%
      \ifnum\pgfmathcounter>\tikzjointhedotsnumber
      \else%
        % Draw the dot.
        \edef\tmp{\the\tikzjointhedotsnumber}%
                \tikzjointhedotsnumber=\pgfmathcounter\relax%
        \path [shift={(@dot-\pgfmathcounter)}, every dot/.try, dot \pgfmathcounter/.try]; 
         \tikzjointhedotsnumber=\tmp% 
        %
        % Calculate the dot number node anchor
        \pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@counta}{center}}%
        \pgf@xc=\pgfmathresult pt\relax%
        \ifdim0pt>\pgf@xc%
          \advance\pgf@xc by360pt\relax%
        \fi%
        \pgfmathanglebetweenpoints{\pgfpointanchor{@dot-\pgfmathcounter}{center}}{\pgfpointanchor{@dot-\the\c@pgf@countb}{center}}%
        \pgf@yc=\pgfmathresult pt\relax%
        \ifdim0pt>\pgf@yc%
          \advance\pgf@yc by360pt\relax%
        \fi%
        \ifdim\pgf@xc>\pgf@yc%
          \pgf@x=360pt\relax%
        \else%
          \pgf@x=0pt\relax%
        \fi%
        \advance\pgf@x by-\pgf@xc%
        \advance\pgf@x by\pgf@yc%
        \divide\pgf@x by2\relax%
        \advance\pgf@x by\pgf@xc%
        \advance\pgf@x by180pt\relax%
        \edef\dotnumberanchor{\the\pgf@x}%
        \node [anchor=\dotnumberanchor, every dot number/.try, dot number \pgfmathcounter/.try] 
          at (@dot-\pgfmathcounter)
          {\tikzjointhedotsnumber=\pgfmathcounter\relax\tikzjointhedotstypesetnumber{\tikzjointhedotsnumber}};
        \c@pgf@counta=\pgfmathcounter\relax%
            \advance\c@pgf@countb by1\relax%
            \ifnum\c@pgf@countb>\tikzjointhedotsnumber%
              \c@pgf@countb=1\relax%
            \fi%
        \repeatpgfmathloop%
  }
}

% Command for typesetting dot number
% #1 - a count register holding the current dot number
%
\def\tikzjointhedotstypesetnumber#1{\the#1}
\makeatletter
% Keys for setting dot number styles
\tikzset{%
  syle dot number range/.code args={#1 to #2 with #3}{%
    \c@pgf@counta=#1
    \pgfmathloop
    \ifnum\c@pgf@counta>#2\relax%
    \else%
      \tikzset{dot number \the\c@pgf@counta/.style={#3}}%
      \advance\c@pgf@counta by1
    \repeatpgfmathloop%
  },
    style dot number list/.code args={#1 with #2}{%
      \pgfutil@for\tmp:=#1\do{%
        \tikzset{dot number \tmp/.style={#2}}%
      }%
    }
}
\makeatother

\tikzset{%
  % Executed for every dot
  every dot/.style={fill=white,
    insert path={  circle [radius=1mm] coordinate [alias=dot-last] (dot-\the\tikzjointhedotsnumber)  }
  },
  % Executed for every dot number
  every dot number/.style={
   shape=circle,
   font=\sf,
   scale=2,
   text=white
  },
  join the dots/.style={
    decoration=join the dots, decorate
  },
  lines/.style={
    ultra thick,
    line join=round,
    line cap=round
  },
  crayon/.style={
    draw=#1,
    line join=round,
    line cap=round,
    line width=1mm
  },
  sketch/.style={
    bend right, out=rand*10, in=180-rand*10
  }
}

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

\foreach \n in {1,...,40}{
\begin{tikzpicture}[line cap=round]



\draw [decoration=join the dots, decorate,x=10cm,y=10cm,
  dot number 16/.style={anchor=south},
  dot number 25/.style={anchor=south},
  dot 1/.style={fill=black}, dot number 1/.append style={text=black, anchor=south east},
  dot 40/.style={fill=black}, dot number 40/.append style={text=black, anchor=south west}] 
 (0,0) \foreach \i in {1,...,3} { -- ++(-1/8,-1/3) -- ++(-1/4,-1/3) -- ++(-3/8,-1/3) -- ++(\i/6,0) -- ++(\i/6,1/16) }
 -- ++(1/8,0)
 -- ++(0,-1/4)  -- ++(-1/2,0) -- ++(1/4,-1/2)  -- ++(6/8,0) -- ++(1/4, 1/2) -- ++(-1/2,0) -- ++(0,1/4)
 -- ++(1/8,0)
 \foreach \i in {3,...,1} { -- ++(\i/6,-1/16) -- ++(\i/6,0) -- ++(-3/8,1/3) -- ++(-1/4,1/3) -- ++(-1/8,1/3) };

\begin{pgfonlayer}{background}

\foreach \d in {4,9,14,27,32,37}{% 
  \tikzset{shift=(dot-\d), yshift=1pt}%
  \pgfmathsetseed{99+\d*50}%
  % Candle
  \fill [lines, fill=purple!80, rounded corners=0.125cm]
    (-1/3,0) to [sketch] (-1/3,2) -- (1/3,2)  to [sketch] (1/3,0);
  % Wick
  \draw [lines] (0,2) -- ++(0,1/4);
    \pgfmathsetseed{99+\n*50+\d*25}%
  \tikzset{shift={(0,2+1/8)}, xscale=round(rnd)*2-1,yscale=1+rand/8}
  \foreach \s/\c in {1/yellow,.5/red}
    \path [lines, fill=\c!50!orange, scale=\s]  
      (0,0) 
      arc (270:180:3/8) 
      .. controls ++(0,1/4) and ++(0,-1/4) .. (0,3/2)
      arc (90:0:3/8 and 1) arc (360:270:3/8 and 1/2);
} 

\path [fill=yellow!75!white, shift=(dot-1), rotate=22.5] (0:1.25)
  \foreach \i [evaluate={\j=mod(\i,2); \k=mod(\i+1,4)==0; \r=\j+1.25+\k+(\i==11);}] in {0,...,15}{
    -- (\i*22.5:\r)
  } -- cycle;
\end{pgfonlayer}

\pgfmathsetseed{99}
\draw [crayon=green!50!black, line width=1cm/8, sketch]
  (dot-1) \foreach \m in {1,...,\n}{ to [sketch] (dot-\m) };

\end{tikzpicture}
}
\end{document}

enter image description here


I get ! Package tikz Error: Giving up on this path. Did you forget a semicolon?. on line 26 of the first code? - fuenfundachtzig
I don't know why that would be. It works for me although I am using the latest CVS version. - Mark Wibrow
I could make it work with a few changes. In any case +1 and Merry Xmas :) - fuenfundachtzig
I wish I could upvote this again! - cfr
(1) That's for sure a Merry TikZmas! - Holene
I am completely delighted with the maze tree -- really wonderful, and an instructive use of lua besides. Could the background of the tree be made some lighter color so that some youngsters of my acquaintance can try solving it with pencils? I played around with the code, but not entirely successfully. - sgmoye
@sgmoye two things need to be changed, firstly, in the lua code in the section preceded by the -- snow comment change m:setMeta(i,j, 'white') to m:setMeta(i,j, 'black') (this is the color for the walls in the snow section). Then look for the line \filldraw [\currentcolor!5!black] (0,0) rectangle (1,1); and replace \currentcolor!5!black with white. You might need to fool around with colors for the other walls to make them more visible when printed (they are all strings in the lua code and set using the setMeta method). - Mark Wibrow
@MarkWilbrow Thanks. Just the pointers I need. - sgmoye
I am now having some trouble getting this to run. It fails with Undefined control sequence. \pdfpagewidth. If I supply \newlength{\pdfpagewidth} then it fails again an undefined control sequence \pdfpageheight. If I supply that as well, the file runs but only the very top lefthand corner shows. I'm using MacTeX2017, updated a few days ago. - sgmoye
@sgmoye since this answer has been posted some incompatibilities have arisen between the standalone package and lualatex. It is now necessary to put \RequirePackage{luatex85} at the top of the file. I have updated the answer accordingly. - Mark Wibrow
6
[+67] [2012-12-22 02:34:04] SztupY

Previous solutions don't really use the fact that the tree can be completely generated procedurally (I think this is what the OP originally intended):

And the picture will change every year! :)

Tree for 2012:

Fractal Christmas Tree 2012

Tree for 2013:

Fractal Christmas Tree 2013

Tree for 2014:

Fractal Christmas Tree 2014

Tree for 2015:

Fractal Christmas Tree 2015

Tree for 2016:

Fractal Christmas Tree 2016

Tree for 2017:

Fractal Christmas Tree 2017

Tree for 2018:

Fractal Christmas Tree 2018

Tree for 2019:

Fractal Christmas Tree 2019

Tree for 2020:

Cancelled due to Social Distancing

Tree for 2021:

Fractal Christmas Tree 2021

The solution added a new rule to the L-system, that collected some "good" points where decorations might be added. (good points are found on the main branches). From this list values are selected randomly, and baubles or lights are added to these points.

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc, lindenmayersystems,shapes,decorations,decorations.shapes}
\begin{document}

\def\pointlistleft{}
\def\pointlistright{}
\pgfmathsetseed{\year * 6}
\makeatletter
\pgfdeclarelindenmayersystem{Christmas tree}{
    \symbol{C}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistleft\expandafter{\expandafter{\t}}}
    \symbol{c}{\pgfgettransform{\t} \expandafter\g@addto@macro\expandafter\pointlistright\expandafter{\expandafter{\t}}}
    \rule{S -> [+++G][---g]TS}
    \rule{G -> +H[-G]CL}
    \rule{H -> -G[+H]CL}
    \rule{g -> +h[-g]cL}
    \rule{h -> -g[+h]cL}
    \rule{T -> TL}
    \rule{L -> [-FFF][+FFF]F}
}
\makeatother

\begin{tikzpicture}[rotate=90]
\draw [color=brown!50!black,line width=2.5pt] (0,0) -- (170pt,0);
\draw [color=green!50!black,l-system={Christmas tree,step=4pt,angle=16,axiom=LLLLLLSLFFF,order=10,randomize angle percent=20}] lindenmayer system -- cycle;

\pgfmathdeclarerandomlist{pointsleft}{\pointlistleft}
\pgfmathdeclarerandomlist{pointsright}{\pointlistright}
\pgfmathdeclarerandomlist{colors}{{red}{blue}{yellow}}

\foreach \i in {0,1,...,5}
{
    \pgfmathrandomitem{\c}{pointsleft}
    \pgfsettransform{\c}
    \pgfgettransformentries{\a}{\b}{\c}{\d}{\xx}{\yy}
    \pgfmathrandomitem{\c}{pointsright}
    \pgfsettransform{\c}
    \pgfgettransformentries{\a}{\b}{\c}{\d}{\XX}{\YY}
    \pgftransformreset

    \pgfmathsetmacro\calcy{min(\yy,\YY)-max((abs(\yy-\YY))/3,25pt)}

    \draw[draw=orange!50!black, fill=orange!50, decorate, decoration={shape backgrounds, shape=star, shape sep=3pt, shape size=4pt}, star points=5] (\xx,\yy) .. controls (\xx,\calcy pt) and (\XX,\calcy pt) .. (\XX,\YY);
}

\foreach \i in {0,1,...,15}
{
    \pgfmathrandomitem{\c}{pointsleft}
    \pgfsettransform{\c}
    \pgftransformresetnontranslations
    \draw[color=black] (0,0) -- (0,-4pt);
    \pgfmathrandomitem{\c}{colors}
    \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt];
}

\foreach \i in {0,1,...,15}
{
    \pgfmathrandomitem{\c}{pointsright}
    \pgfsettransform{\c}
    \pgftransformresetnontranslations
    \draw[color=black] (0,0) -- (0,-4pt);
    \pgfmathrandomitem{\c}{colors}
    \shadedraw[ball color=\c] (0,-8pt) circle [radius=4pt];
}

\end{tikzpicture}
\end{document}

Where's the tree for 2015? Last year you updated the 19th ;-) - Tom Bombadil
@TomBombadil had some issues with MacTex recently, but they were solved :) - SztupY
Are the balls the same of the previous years? :-):-) My sincere congratulations. - Sebastiano
7
[+55] [2012-10-26 09:14:53] David Carlisle
{\let~\catcode~`A0 AgdefAs.#1.{Acsname#1Aendcsname}AdefAq#1#2#3#4#5#6#7#8#9{%#######################
AdefAy##1###1##3##4##5###3###2##8##9{AdefAw####1#####1####3####4####5#####3#####2####8####9{%#######
AdefAz########1#########1########3########4########5#########3#########2########8########9{Aegroup%#
As.d####9cum##5ntc#6##9ss.[11pt]{scr####4tc#6}%#####################################################
As.##3p##9c#4##9g##5.[dv##1psn##9m##5s#8svgn##9m##5s]{xc####9#6####9r}%#############################
As.##3p##9c#4##9g##5.{t##8z}As.##3t##8z#6ibr##9r#9.{%###############################################
sh##9p##5s#8########4##1####9ns.sh##9p##5s#8########4##1####9ns.#5r##9ct##9#6s#8%###################
########4##1####9ns.m####4#4##1ngs#8#########3####9ws}%#############################################
As.n##5ws##9v##5b####9x.{Amycd}%####################################################################
As.s##9v##5b####9x.{Amycd}{#####2###1{####1}[sc##9#6##5=.1]%########################################
Ashade[t####9p#####2c####9#6####9r=#9##5#6#6####9w#8b####9tt####9m#####2c####9#6####9r=r##5d]%######
#####2(####8#8####8###2#########1########1#####3#8.########8#####2########5#####2%##################
#####3#8####3###2#########1#####2(####8#8########8#########1########1#########21#8####3###2%########
#####2########5#####2#########21#8.########8#########1#####2(####8#8####8###2;%#####################
#7[#9##5#6#6####9w!9####8!b#6##9c#4]#####2(.8#8####8###2#####2r##5ct##9ng#6##5#####2%###############
#########2.8#8-5###2;%##############################################################################
###3{####1}#####2}As.t##8zs##5t.{p####5nt/.st#9#6##5={dr##9w=################1!5####8!b#6##9c#4%####
#8#####2#5##1#6#6=################1!5####8}#8%######################################################
m#9#####2st####4/.st#9#6##5={########4##5#8########4##1####9n={sh##9p##5#####2b##9c#4gr####9unds#8%#
sh##9p##5=st####4}#8st####4#####2p####9##1nts=################1}}%##################################
###1{d####9cum##5nt}%###############################################################################
###1{####1}[#####2b##9#6#6#####2r##5d/.st#9#6##5={%#################################################
########4##5#8#####2########4##1####9n={m####4#4##1ngs#8m####4#4=b##5tw##5##5n#####2%###############
p####9s##1t##1####9ns#####2.#1#####2########5#####21#####2st##5p#####23cm%##########################
w##1th#####2{As.pg##4hs##5tm##9cr####9.{Asz}{#1#####2+#####2####3#####2*#####2r########5}%##########
#####1[#########3##1ng=b##9#6#6#8b##9#6#6#####2c####9#6####9r=r##5d]#####2(####8#8####8###2#####2%##
c##1rc#6##5[r##9d##1us=Asz#####2mm];%###############################################################
}}}#####2#8b##9#6#6#####2b#6u##5/.st#9#6##5={########4##5#8########4##1####9n=%#####################
{m####4#4##1ngs#8m####4#4=b##5tw##5##5n#####2p####9s##1t##1####9ns#####2####8.1#####2########5%#####
#####2.9#####2st##5p#####23cm%######################################################################
w##1th#####2{As.pg##4hs##5tm##9cr####9.{Asz}{#1#####2+#####2####3#####2*#####2r########5}%##########
#####1[#########3##1ng=b##9#6#6#8b##9#6#6#####2c####9#6####9r=b#6u##5]#####2%#######################
(####8#8####8###2#####2c##1rc#6##5[r##9d##1us=Asz#####2mm];%########################################
}}}]Adraw[#5##1#6#6=M####4####9####9n#8u#6tr##9#####2th##1c#4]%#####################################
(.#25#8-1###2#####2########3#####2########1(####3#8####3###2#####2########5#####2(%#################
####3#83###2#####2########3#####2(####8####3#84###2%################################################
--#####2#########2####8####3#84###2#####2########3#####2########1#########2####3#83###2#####2%######
########5#####2#########2####3#8####3###2#####2########3#####2#########2.#25#8-1###2#####2;%########
Ashade[u#6tr##9#####2th##1c#4#8#####2t####9p#####2c####9#6####9r=gr##5##5n!9####8!b#6##9c#4#8%######
b####9tt####9m#####2c####9#6####9r=gr##5##5n!1####8!b#6##9c#4]%#####################################
(####8#81####8###2#####2########3########1#####2(####8#88###2#####2########5#####2#####3########9%##
#####2########3#####2#####3####3########9%##########################################################
########3#####2########1#####3########9#####2########5#####2#####3########9#####2########3#####2(%##
####8####3#8#2.#15###2%#############################################################################
########3#####2########1#####3####3#85###2#####2########5#####2(#1####3#84###2#####2########3#####2%
(3#84###2%##########################################################################################
########3#####2########1(#1#84###2#####2########5#####2#####3.#15#84###2#####2########3#####2%######
#####3#84####3###2%#################################################################################
########3#####2########1(#1#8########8#####2########5#####2(3####3#8########8#####2########3#####2(%
4#8########8%#######################################################################################
########3#####2########1#####3#81###2#####2########5#####2#########21#81###2#####2########3#####2%##
#########24#8########8%#############################################################################
########3#####2########1#########23####3#8########8#####2########5#####2#########2#1#8########8%####
#####2########3#####2#########21#84####3###2%#######################################################
########3#####2########1#########21.#15#84###2#####2########5#####2#########2#1#84###2#####2%#######
########3#####2#########23#84###2%##################################################################
########3#####2########1#########2#1####3#84###2#####2########5#####2#########21####3#85###2#####2%#
########3#####2#########2####8####3#8#2.#15###2%####################################################
########3#####2########1#####2#########21########9#####2########5#####2#########21########9#####2%##
########3#####2#########21####3########9%###########################################################
########3#####2########1#####2#########21########9#####2########5#####2(####8#88###2#####2########3%
#####2(####8#81####8###2;%##########################################################################
As.#5####9r##5##9ch.#####2Acd#####2##1n#####2{(#1#85###2#8#########2#1#85###2#8(####8####3#8#2####3%
###2#8#########2####8####3#8#2####3###2#8#########23#8#1####3###2#8#####2(3#8#1####3###2#8%#########
#####3####3#81.#25###2#8#########21####3#81.#25###2}%###############################################
Anode#####2##9t#####2Acd#####2{As.##3b####9x.{Amycd}}#####2;%#######################################
Anode#####2[st####4#8#####2st####4#####2p####9##1nt#####2h##5##1ght=####3cm#8#####2m##1n##1mum%#####
#####2s##1z##5=####3cm#8dr##9w#8#5##1#6#6=#9##5#6#6####9w#8th##1c#4]%###############################
##9t#####2(####8#81####8###2#####2{};###1{sc####9p##5}[########4##1####9n={sh##9p##5#####2s##5p=.#1%
cm#8#####2sh##9p##5#####2s##1z##5=.#15cm}]%#########################################################
Adraw#####2[m#9#####2st####4=#3#8#####2p####5nt=r##5d]#####2#########24#8########8%#################
########3#####2########1(####8#8########8#####2########5#####2#####3#83####3###2#####2########3%####
#####2#####3#84.4####8###2;%########################################################################
Adraw#####2[m#9#####2st####4=#3#8#####2p####5nt=r##5d]#####2#########21####3#85.4####8###2%#########
########3#####2########1(####8#85.4####8###2#####2########5#####2(####8####3#8#3####3###2#####2%####
########3#####2(####8####3########9;%###############################################################
Adraw#####2[m#9#####2st####4=#3#8#####2p####5nt=b#6u##5]#####2(4#8########8%########################
########3#####2########1#####2(####8#8########8#####2########5#####2#########21#83####3###2#####2%##
########3#####2#########21#84.4####8###2;%##########################################################
Adraw#####2[m#9#####2st####4=#3#8#####2p####5nt=b#6u##5]#####2#####3####3#85.4####8###2%############
########3#####2########1(####8#85.4####8###2#####2########5#####2#########2####8####3#8#3####3###2%#
#####2########3#####2#########2####8####3########9;%################################################
###3{sc####9p##5}#####1[b##9#6#6#####2r##5d](####8#81####8###2#####2########3########1#####2(####8%#
#88###2#####2########5#####2#####3########9#####2########3#####2#####3####3########9%###############
########3#####2########1#####3########9#####2########5#####2#####3########9#####2########3#####2(%##
####8####3#8#2.#15###2%#############################################################################
########3#####2########1#####3####3#85###2#####2########5#####2(#1####3#84###2#####2########3#####2%
(3#84###2%##########################################################################################
########3#####2########1(#1#84###2#####2########5#####2#####3.#15#84###2#####2########3#####2#####3%
#84####3###2%#######################################################################################
########3#####2########1(#1#8########8#####2########5#####2(3####3#8########8#####2########3#####2(%
4#8########8%#######################################################################################
########3#####2########1#####3#81###2#####2########5#####2#########21#81###2#####2########3#####2%##
#########24#8########8%#############################################################################
########3#####2########1#########23####3#8########8#####2########5#####2#########2#1#8########8%####
#####2########3#####2#########21#84####3###2%#######################################################
########3#####2########1#########21.#15#84###2#####2########5#####2#########2#1#84###2#####2%#######
########3#####2#########23#84###2%##################################################################
########3#####2########1#########2#1####3#84###2#####2########5#####2#########21####3#85###2#####2%#
########3#####2#########2####8####3#8#2.#15###2%####################################################
########3#####2########1#####2#########21########9#####2########5#####2#########21########9#####2%##
########3#####2#########21####3########9%###########################################################
########3#####2########1#####2#########21########9#####2########5#####2(####8#88###2#####2########3%
#####2(####8#81####8###2;%##########################################################################
#####1[b##9#6#6#####2b#6u##5](####8#81####8###2#####2########3########1#####2(####8#88###2#####2%###
########5#####2#####3########9#####2########3#####2#####3####3########9%############################
########3#####2########1#####3########9#####2########5#####2#####3########9#####2########3#####2(%##
####8####3#8#2.#15###2%#############################################################################
########3#####2########1#####3####3#85###2#####2########5#####2(#1####3#84###2#####2########3#####2%
(3#84###2%##########################################################################################
########3#####2########1(#1#84###2#####2########5#####2#####3.#15#84###2#####2########3#####2#####3%
#84####3###2%#######################################################################################
########3#####2########1(#1#8########8#####2########5#####2(3####3#8########8#####2########3#####2(%
4#8########8%#######################################################################################
########3#####2########1#####3#81###2#####2########5#####2#########21#81###2#####2########3#####2%##
#########24#8########8%#############################################################################
########3#####2########1#########23####3#8########8#####2########5#####2#########2#1#8########8%####
#####2########3#####2#########21#84####3###2%#######################################################
########3#####2########1#########21.#15#84###2#####2########5#####2#########2#1#84###2#####2%#######
########3#####2#########23#84###2%##################################################################
########3#####2########1#########2#1####3#84###2#####2########5#####2#########21####3#85###2#####2%#
########3#####2#########2####8####3#8#2.#15###2%####################################################
########3#####2########1#####2#########21########9#####2########5#####2#########21########9#####2%##
########3#####2#########21####3########9%###########################################################
########3#####2########1#####2#########21########9#####2########5#####2(####8#88###2#####2########3%
#####2(####8#81####8###2;%##########################################################################
As.#5####9r##5##9ch.#####2Ai#####2##1n#####2{####8####3#8####8.#3#8########3.#81.#3}%###############
#7#####2[wh##1t##5!8####8!b#6u##5#8########4##1####9n=K####9ch#####2sn####9w#5#6##9#4##5#8####9p%###
##9c##1t#9=.9]%#####################################################################################
[sh##1#5t={(r########5*5#8rnd*8###2}#8sc##9#6##5=Ai]%###############################################
[d####9ub#6##5#####2c####9p#9#####2#########3####9w={####9p##9c##1t#9=####8.#1#8#########3####9w%###
#####2xsh##1#5t=####8pt#8%##########################################################################
#########3####9w#####2#9sh##1#5t=3*Ai#####2pt#8#5##1#6#6=wh##1t##5#8dr##9w=n####9n##5}]%############
########4##5#####2{########4##5#####2{########4##5#####2{(####8#8####8###2#####2--#####2++(#3####8:%
1###2#####2--#####2++#########2#3####8:1###2#####2--#####2c#9c#6##5%################################
}}};###3{####1}###3{d####9cum##5nt}}Az{#####2c####9ntr####9#6s#####2}{#####2..}{..}{d##5c####9r##9t%
}{##9nd}{sh##9d}{(-}{#1###2}{#8#2###2}}Aw{t##8zp##1ctur##5}Apath{.5}{##9r}{##9##1}{(1}{ }0o}%#######
Ay iAbegin{use}{#5mat}eAend){i#4}a}Aq276kflAfill,y%#################################################

(28) Looks like a duplicate :) - topskip
-1: Could at least post a screenshot of the result. (Only joking on the -1) - Andrew Stacey
well the screenshot is the same as Alain's code above as topskip noted. - David Carlisle
(23) Awesome!!I plan to use this as a showcase as to how easy TeX is to use... - Peter Grill
(20) If you look at this code without blinking for 5 minutes, you start to see a christmas tree. :) - Paulo Cereda
Hey, just remembered that code only answers are frowned up, so this could use some documentation to explain how this works, and how we could change some of the paramaters. :-) - Peter Grill
(13) Some code is just so transparently obvious that additional documentation is clearly unnecessary. - David Carlisle
(1) Forgive me my ignorance of TeX, but how do I compile this? :-) - hpesoj626
(6) save it as tree.tex and pdflatex tree - David Carlisle
Cannot imagine you obfuscated @Alain 's code by hand. Could you please make the script or whatever you used public? - AlexG
(2) @AlexG imagine again:-) - David Carlisle
So it took 10 months to do it manually? - AlexG
(3) No, just a few minutes (if I had taken longer I would have done a better job of getting even line length without using %. I didn't type it in of course it was just derived from Alain's code by applying a few regular-expression replace from his posted code, but they were just interactively applied not any saved script - David Carlisle
Odd, I can't get it to compile with either TeX or pdflatex. - Canageek
(3) @Canageek should work with pdflatex, it's just Alain's answer, with the source code um, pretty printed a bit. - David Carlisle
(3) I worry about you sometimes... :) - Sean Allred
(3) @SeanAllred I appreciate your concern - David Carlisle
(6) I say this is false advertising: when I compiled it, I didn't get a cat at all... - cfr
8
[+48] [2014-12-27 03:51:39] cfr

We are still within the 12 days of Christmas and the wise men have not yet arrived bearing gifts, so I trust that I do not arrive too late.

I wondered...

If we have trees, why not a forest?

There is, of course, no reason whatsoever to draw a Christmas tree using forest....

Nadolig Llawen!

Note that the current code has been updated to work with Forest 2.1, as the previous version would no longer compile. If you want to compile with older Forest, please use the code from the previous version of my answer.

\documentclass[tikz, border=5pt, rgb, x11names, svgnames, dvipsnames]{standalone}
\usepackage{forest}
\usetikzlibrary{shapes.geometric,backgrounds,shadows,fit,fadings,calc}
\pgfdeclarelayer{foreground}
\pgfdeclarelayer{boncyff}
\pgfdeclarelayer{canghennau}
\pgfdeclarelayer{goleuni}
\pgfsetlayers{background,canghennau,boncyff,goleuni,main,foreground}
\makeatletter
% adapted (simplified version) from tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
\tikzset{%
  on foreground layer/.style={%
    execute at begin scope={%
      \pgfonlayer{foreground}%
      \let\tikz@options=\pgfutil@empty%
      \tikzset{every on foreground layer/.try,#1}%
      \tikz@options%
    },
    execute at end scope={\endpgfonlayer}
  },
  on canghennau layer/.style={
    execute at begin scope={%
      \pgfonlayer{canghennau}%
      \let\tikz@options=\pgfutil@empty%
      \tikzset{every on canghennau layer/.try,#1}%
      \tikz@options%
    },
    execute at end scope={\endpgfonlayer}
  },
  on boncyff layer/.style={
    execute at begin scope={%
      \pgfonlayer{boncyff}%
      \let\tikz@options=\pgfutil@empty%
      \tikzset{every on boncyff layer/.try,#1}%
      \tikz@options%
    },
    execute at end scope={\endpgfonlayer}
  },
  on goleuni layer/.style={
    execute at begin scope={%
      \pgfonlayer{goleuni}%
      \let\tikz@options=\pgfutil@empty%
      \tikzset{every on goleuni layer/.try,#1}%
      \tikz@options%
    },
    execute at end scope={\endpgfonlayer}
  },
  aa/.store in=\cfr@aa,
  aa=0,
  pics/anrheg/.style n args={2}{
    code={
      \node (-bocs) [anchor=north, rounded corners=2pt, outer sep=0pt, minimum width=5mm, minimum height=5mm, fill=#1, rotate=\cfr@aa] {};
      \path [fill=#2, draw=#2, rotate=\cfr@aa]
      ([xshift=-.5mm]-bocs.south)
      [out=80, in=-105] to ([xshift=.5mm]-bocs.north)
      [out=175, in=5] to ([xshift=-.5mm]-bocs.north)
      [out=-85, in=100] to ([xshift=.5mm]-bocs.south)
      [out=-175, in=-5] to cycle;
      \path [fill=#2, draw=#2, rotate=\cfr@aa]
      ([yshift=.5mm]-bocs.west)
      [out=-10, in=-175] to ([yshift=-.5mm]-bocs.east)
      [out=85, in=-85] to ([yshift=.5mm]-bocs.east)
      [out=-175, in=-10] to ([yshift=-.5mm]-bocs.west)
      [out=95, in=-95] to cycle;
    },
  },
}
\makeatother
\tikzfading[
  name=disglair,
  inner color=transparent!0,
  outer color=transparent!100]
\colorlet{lliw1}{Crimson}
\colorlet{lliw2}{DeepPink}
\colorlet{lliw3}{Violet}
\colorlet{lliw4}{Purple3}
\colorlet{lliw5}{Cyan}
\colorlet{lliw6}{Green1}
\colorlet{lliw7}{Gold}
\colorlet{lliw8}{Aquamarine1}
\colorlet{lliw0}{OrangeRed1}
\colorlet{lliwanrheg1a}{WildStrawberry}
\colorlet{lliwanrheg1b}{Ivory}
\colorlet{lliwanrheg2a}{Red1}
\colorlet{lliwanrheg2b}{Yellow1}
\colorlet{lliwanrheg3a}{Turquoise2}
\colorlet{lliwanrheg3b}{WildStrawberry}
\colorlet{lliwanrheg4a}{Yellow1}
\colorlet{lliwanrheg4b}{DodgerBlue3}
\colorlet{lliwanrheg5a}{Ivory}
\colorlet{lliwanrheg5b}{Turquoise2}
\colorlet{lliwanrheg0a}{DodgerBlue3}
\colorlet{lliwanrheg0b}{Red1}
\begin{document}
\forestset{
  declare count register=nodes y goeden,
  nodes y goeden'=0,
  declare count register=tier count,
  tier count'=1,
  % canghennau
  cangen chwith/.style={
    edge path={
      \noexpand\scoped[on canghennau layer]{
        \noexpand\path [draw=ForestGreen, thick, \forestoption{edge}]
          (!u.parent anchor) +(0,20pt) [out=-90, in=150] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,15pt) [out=-90, in=150] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,10pt) [out=-90, in=150] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,5pt) [out=-90, in=150] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) [out=-90, in=150] to (.child anchor)\forestoption{edge label};
      }
    },
  },
  cangen dde/.style={
    edge path={
      \noexpand\scoped[on canghennau layer]{
        \noexpand\path [draw=ForestGreen, thick, \forestoption{edge}]
          (!u.parent anchor) +(0,20pt) [out=-90, in=30] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,15pt) [out=-90, in=30] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,10pt) [out=-90, in=30] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) +(0,5pt) [out=-90, in=30] to (.child anchor)\forestoption{edge label}
          (!u.parent anchor) [out=-90, in=30] to (.child anchor)\forestoption{edge label};
      }
    },
  },
  plant/.style={
    before typesetting nodes={
      repeat=#1{
        prepend={[, bud, cangen chwith]},
        append={[, bud, cangen dde]},
      },
    },
  },
  boncyff/.style={
    edge path={
      \noexpand\scoped[on boncyff layer]{
        \noexpand\path [line cap=round, line width=2.5pt, draw=Chocolate4, \forestoption{edge}] (!u.parent anchor) -- (.child anchor)\forestoption{edge label};
      }
    },
  },
  seren/.style={
    star, minimum size=25pt, star points=7, star point ratio=3, parent anchor=south, outer sep=2pt, inner color=white, outer color=Gold1, draw=Goldenrod1, inner color=white, outer color=Silver, draw=Snow3, tikz={\scoped[on goleuni layer]\node (sglein) [minimum width=50pt, circle, inner color=white, outer color=Silver, path fading=disglair] {};}
  },
  enw/.style={
    nodes y goeden'+=1,
    name/.process={Rw}{nodes y goeden}{n##1},
  },
  anrheg/.style={
    no edge, enw, anchor=north
  },
  bud/.style={
    inner sep=0pt,
    outer sep=0pt,
    parent anchor=center,
    child anchor=center,
    enw,
  },
  gwag/.style={
    inner sep=0pt,
    outer sep=0pt,
    parent anchor=center,
    child anchor=center,
    no edge,
  },
}
\begin{forest}
  for tree={
    if level=0{}{
      bud,
    },
    boncyff,
    if n=1{
      tier count'+=1,
    }{},
    s sep+=7.5,
    before computing xy={
      l/.process={Rw+n+d}{tier count}{4*#1 pt}
    },
    before typesetting nodes={
      if n children=0{
        append={
          [, bud, boncyff
            [, bud, l'=2pt, boncyff
              [, anrheg, alias=troed, before computing xy={l'=0pt}
              ]
            ]
          ]
        },
        delay={
          for children={
            if={
              >OOw+n={n}{!u.n children}{(#1+1)/2}
            }{}{
              append={
                [, gwag, l'=2pt
                  [, anrheg, before computing xy={l'=7.5pt}
                  ]
                ]
              },
            },
          },
        },
      }{},
    },
  },
  [, seren, plant=1
    [, plant=2
      [, plant=3
        [, plant=4
          [, plant=5
            [, plant=6
            ]
          ]
        ]
      ]
    ]
  ]
  \foreach \i  in {1,...,50}
    {
      \ifnum\i=29\relax\else\ifnum\i=28\relax\else
        \pgfmathsetmacro{\result}{int(mod(\i,9))}
        \node [circle, ball color=lliw\result] at (n\i) {};
        \scoped[on goleuni layer] \node [circle, minimum width=20pt, inner color=lliw\result!50!white, outer color=lliw\result!50!Silver, path fading=disglair] at (n\i) {};
      \fi\fi
    }
  \foreach \i in {51,...,62}
    {
      \tikzset{aa=0}
      \pgfmathsetmacro{\result}{int(mod(\i,6))}
      \pgfmathsetmacro{\casgliad}{int(mod(4+\i,6))}
      \pgfmathsetmacro{\nesaf}{int(1+\i)}
      \ifnum\i>56
        \pic at (n\i) {anrheg={lliwanrheg\result a}{lliwanrheg\result b}};
      \else
        \pic at (n\i) {anrheg={lliwanrheg\result b}{lliwanrheg\result a}};
      \fi
      \tikzset{aa=45}
      \ifnum\i<56
          \pic at ([yshift=3.85mm,xshift=.25pt]$(n\i)!1/4!(n\nesaf)$) {anrheg={lliwanrheg\casgliad a}{lliwanrheg\casgliad b}};
      \fi
      \tikzset{aa=-45}
      \ifnum\i>56
        \ifnum\i<62
          \pic at ([yshift=3.85mm,xshift=-.25pt]$(n\i)!3/4!(n\nesaf)$) {anrheg={lliwanrheg\casgliad b}{lliwanrheg\casgliad a}};
        \fi
      \fi
    }
  \path
    (n29) ++(0,-1.5mm) coordinate (c0)
    (c0) arc (-90:0:5mm and 2.5mm) coordinate (c1)
    (c0) arc (-90:-180:5mm and 2.5mm) coordinate (c2)
    (c0) +(2.5mm,-4.5mm) coordinate (c3)
    (c0) +(-2.5mm,-4.5mm) coordinate (c4)
    (c1) +(0,-2mm) coordinate (c5)
    (c2) +(0,-2mm) coordinate (c6)
    ;
  \path [fill=Sienna1] (c2) arc (-180:0:5mm and 2.5mm) -- (c5) -- (c3) arc (0:-180:2.5mm and 1.25mm) -- (c6) -- cycle;
  \begin{scope}
    \clip (c2) arc (-180:0:5mm and 2.5mm) -- (c5) -- (c3) arc (0:-180:2.5mm and 1.25mm) coordinate [midway] (c7) -- (c6) -- cycle;
    \path [draw=Sienna3] (c6) arc (-180:0:5mm and 2.5mm);
    \path [draw=Sienna3] (c2) arc (-180:0:5mm and 2.5mm);
  \end{scope}
  \begin{scope}[on canghennau layer]
    \path [fill=Sienna1, draw=Sienna3] (c2) arc (-180:180:5mm and 2.5mm);
    \path [fill=Brown!50!black] (n29 |- c2) circle (4mm and 2mm);
  \end{scope}
  \begin{scope}[on background layer]
      \node [fill=MidnightBlue, inner sep=15pt, fit=(sglein) (troed) (n21) (n35) (c7) (n51) (n62) (n34)] {};
  \end{scope}
%   \foreach \i in {1,...,62} \node (anrheg \i) [red] at (n\i) {\i};
\end{forest}
\end{document}

coeden nadolig

Forgot the cat...

My cat has decided that under the Christmas tree is the place to be now most of the presents have been distributed. I thought my forest tree needed a cat but there is no room under the tree here, so this cat has decided to keep guard from above...

The cat is just a TiKZ pic compiled with standalone as a separate image (see below). Here the cat is simply included as an external image and scaled for the sake of simplicity:

\node (cath) [scale=.15, anchor=south, yshift=4.5mm, xshift=5mm] at (n34.north) {\includegraphics{cath-gorwedd}};

coeden nadolig gyda chath

Appendix: Cat Code

[If anybody spots what is messing up the bounding box, please let me know!]

\pdfminorversion=7
\RequirePackage[rgb,pdftex,dvipsnames,x11names]{xcolor}
\documentclass[tikz,border=5pt]{standalone}
\usetikzlibrary{calc,intersections,backgrounds}
\pgfdeclarelayer{foreground}
\pgfdeclarelayer{pen}
\pgfdeclarelayer{corff}
\pgfsetlayers{background,corff,main,pen,foreground}
\makeatletter
% adapted (simplified version) from tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
  \tikzset{%
    on foreground layer/.style={%
          execute at begin scope={%
            \pgfonlayer{foreground}%
            \let\tikz@options=\pgfutil@empty%
            \tikzset{every on foreground layer/.try,#1}%
            \tikz@options%
          },
          execute at end scope={\endpgfonlayer}
    },
    on pen layer/.style={
          execute at begin scope={%
            \pgfonlayer{pen}%
            \let\tikz@options=\pgfutil@empty%
            \tikzset{every on pen layer/.try,#1}%
            \tikz@options%
          },
          execute at end scope={\endpgfonlayer}
    },
    on corff layer/.style={
          execute at begin scope={%
            \pgfonlayer{corff}%
            \let\tikz@options=\pgfutil@empty%
            \tikzset{every on corff layer/.try,#1}%
            \tikz@options%
          },
          execute at end scope={\endpgfonlayer}
    },
    stripiau cwt/.style={draw=#1, very thin, shorten >=-5mm, shorten <=-5mm, double=#1, double distance=3.5mm},
    stripiau corff/.style={very thin, draw=#1, fill=#1},
    trwyn/.style={circle, yshift=1.25mm, minimum width=2.5mm, inner sep=0pt},
    llenwi cath/.style={fill=#1},
    llygaid/.style n args=2{inner color=#1, outer color=#2, ultra thick, draw},
    pics/cath b/.style n args=5{
      code={
        [ultra thick]
        \begin{pgfonlayer}{pen}% ref. workaround from http://tex.stackexchange.com/a/218166/ (Mark Wibrow)
          \begin{scope}[very thin]% [on pen layer={very thin}]
          \path [clip]
            (0,10mm) coordinate (pen1) arc (90:65:19mm and 20mm) coordinate [pos=.75] (pp1) coordinate (pen2)
              arc (65:45:19mm and 20mm)  coordinate (pen3)
              arc (45:-60:19mm and 20mm) coordinate [pos=.05] (pp4) coordinate [pos=.4] (pp5) coordinate [pos=.45] (pp8) coordinate [pos=.75] (pp9)  coordinate (pen8)
              arc (-60:-90:19mm and 20mm) coordinate (pen10)
              arc (-90:-120:19mm and 20mm) coordinate (pen9)
              arc (-120:-225:19mm and 20mm) coordinate [pos=.25] (pp10) coordinate [pos=.55] (pp11) coordinate [pos=.6] (pp6) coordinate [pos=.95] (pp7) coordinate (pen4)
              arc (-225:-245:19mm and 20mm) coordinate (pen5)
              arc (-245:-270:19mm and 20mm) coordinate [pos=.25] (pp2)
              ;
          \path [stripiau corff=#1]
            (pp2) [out=-45, in=95] to ($(pen1) - (0,10mm)$) coordinate (pp3) [out=85, in=-135] to (pp1) |- +(5mm,5mm) -| cycle
            (pp4) [out=-135, in=25] to +(-7.5mm,-4mm) [out=-25, in=115] to (pp5) -| +(5mm,5mm) |- cycle
            (pp7) [out=-45, in=155] to +(7.5mm,-4mm) [out=-155, in=65] to (pp6) -| +(-5mm,5mm) |- cycle
            (pp8) [out=-135, in=-25] to +(-17.5mm,0mm) [out=-45, in=115] to (pp9) -| +(5mm,5mm) |- cycle
            (pp11) [out=-45, in=-155] to +(17.5mm,0mm) [out=-135, in=65] to (pp10) -| +(-5mm,5mm) |- cycle
            ;
          \end{scope}
        \end{pgfonlayer}
        \path
          (pen2) ++(4mm,7.5mm) coordinate (pen6)
          (pen5) ++(-4mm,7.5mm) coordinate (pen7);
        \path [rounded corners=1pt, llenwi cath=#2]
          (pen1) arc (90:65:19mm and 20mm)
            [out=80, in=-110] to (pen6) [out=-80, in=85] to
          (pen3) arc (45:-225:19mm and 20mm)
            [out=95, in=-100] to (pen7) [out=-70, in=100] to
          (pen5) arc (-245:-270:19mm and 20mm);
        \begin{scope}[on foreground layer={ultra thick}]
          \draw [rounded corners=1pt, ultra thick]
            (pen1) arc (90:65:19mm and 20mm)
              [out=80, in=-110] to (pen6) [out=-80, in=85] to
            (pen3) arc (45:-225:19mm and 20mm)
              [out=95, in=-100] to (pen7) [out=-70, in=100] to
            (pen5) arc (-245:-270:19mm and 20mm);
        \end{scope}
      \path [llenwi cath=#2]% corff
          (pp8) [out=35, in=100] to coordinate [pos=.075] (corff7) coordinate [pos=.1] (corff8) coordinate [pos=.2] (corff9) coordinate [pos=.225] (corff10) coordinate [pos=.325] (corff11) coordinate [pos=.35] (corff12) coordinate [pos=.45] (corff13) coordinate [pos=.475] (corff14) coordinate [pos=.575] (corff15) coordinate [pos=.6] (corff16) coordinate [pos=.7] (corff17) coordinate [pos=.725] (corff18) coordinate [pos=.825] (corff19) coordinate [pos=.86] (corff20) coordinate [pos=.96] (corff21) ++(75mm,-15mm) coordinate (corff5)
            [out=-80, in=-85] to coordinate [pos=.6] (corff6) coordinate [pos=.7] (corff22) coordinate [pos=.775] (corff23) coordinate [pos=.825] (corff24) coordinate [pos=.875] (corff27) coordinate [pos=.9] (corff25) coordinate [pos=.985] (corff26) (pen9);
         \begin{scope}[ultra thick]% stripiau'r corff
            \clip
              (pp8) [out=35, in=100] to (corff5)
                [out=-80, in=-85] to (pen9) |- cycle;
            \path [stripiau corff=#1]
              (pp8) [out=-95, in=65] to ++(7.5mm,-15mm) [out=45, in=-175] to (corff7)
              (corff8) [out=-85, in=50] to ++(7.5mm,-17.5mm) [out=45, in=-135] to (corff9)
              (corff10) [out=-90, in=60] to ++(5mm,-20mm) [out=50, in=-140] to (corff11)
              (corff12) [out=-100, in=55] to ++(2.5mm,-20mm) [out=50, in=-145] to (corff13)
              (corff14) [out=-110, in=50] to ++(0,-20mm) [out=40, in=-155] to (corff15)
              (corff16) [out=-115, in=40] to ++(-3.5mm,-18.5mm) [out=30, in=-170] to (corff17)
              (corff18) [out=-135, in=20] to ++(-7.5mm,-16.5mm) [out=10, in=-180] to (corff19)
              (corff20) [out=-170, in=-5] to ++(-10mm,-12.5mm) [out=-15, in=140] to (corff21)
              (corff26) [out=-45, in=-135] to ++(20mm,-1.5mm) [out=-115, in=45] to (corff25) -- +(-5mm,0) |- cycle
              (corff27) [out=40, in=-115] to ++(20mm,7.5mm) [out=-105, in=65] to (corff24) -- +(-5mm,0) |- cycle;
         \end{scope}
        \draw [ultra thick, name path=corff]
          (pp8) [out=35, in=100] to ++(75mm,-15mm)
            [out=-80, in=-85] to coordinate [pos=.6] (corff6) (pen9);
        \draw [ultra thick, llenwi cath=#2]% coesau
          (corff22) ++(17.5mm,12.5mm) coordinate (coes1)
          (corff23) ++(12.5mm,15mm) coordinate (coes2)
          (coes1) [out=-120, in=35] to (corff22) [out=-145, in=5] to ++(-20mm,-7.5mm) [out=-175, in=0] to ++(-5mm,0) arc (-90:90:-5mm and 3mm) coordinate (coes9) [out=0, in=-175] to ++(5mm,0) coordinate (coes11) [out=5, in=-145] to (corff23) [out=35, in=-100] to (coes2);
        \begin{pgfonlayer}{background}% ref. workaround from http://tex.stackexchange.com/a/218166/ (Mark Wibrow)
          \begin{scope}
            \draw [ultra thick, llenwi cath=#2]% coesau
              (corff23) [out=-145, in=5] to (coes11) [out=-175, in=0] to (coes9) arc (-90:90:-4mm and 2.5mm) [out=0, in=-145] to (corff24)
              ;
          \end{scope}
        \end{pgfonlayer}
        \path [llenwi cath=#2]% llenwi'r cwt
          (corff5) [out=-80, in=-15] to ($(corff6) + (0,-2.5mm)$) coordinate (cwt5)
            [out=165, in=-90] to ++(-5mm,5mm) coordinate (cwt6)
            [out=90, in=170] to ++(7.5mm,5mm) coordinate (cwt7)
            [out=-10, in=-95] to ($(corff5) + (-15mm,-2.5mm)$) coordinate (cwt8)
          ;
        \begin{scope}[ultra thick]% stripiau'r cwt
          \clip (corff5) [out=-80, in=-15] to
              coordinate [pos=.1] (cwt9)
              coordinate [pos=.15] (cwt10a)
              coordinate [pos=.25] (cwt11a)
              coordinate [pos=.345] (cwt12a)
              coordinate [pos=.44] (cwt13a)
              coordinate [pos=.53] (cwt14a)
              coordinate [pos=.62] (cwt15a)
              coordinate [pos=.71] (cwt16a)
              coordinate [pos=.805] (cwt17a)
              coordinate [pos=.9] (cwt18a)
              coordinate [pos=1] (cwt19a)
              (cwt5)
            [out=165, in=-90] to
              coordinate [pos=.45] (cwt20a)
              (cwt6)
            [out=90, in=170] to
              coordinate [pos=.65] (cwt20b)
              (cwt7)
            [out=-10, in=-95] to
              coordinate [pos=.025] (cwt19b)
              coordinate [pos=.125] (cwt18b)
              coordinate [pos=.225] (cwt17b)
              coordinate [pos=.325] (cwt16b)
              coordinate [pos=.425] (cwt15b)
              coordinate [pos=.525] (cwt14b)
              coordinate [pos=.625] (cwt13b)
              coordinate [pos=.725] (cwt12b)
              coordinate [pos=.825] (cwt11b)
              coordinate [pos=.925] (cwt10b)
              (cwt8)
            |- (corff21) -- cycle;
          \path [stripiau corff=#1]
            (corff5) [out=110, in=10] to ++(-7.5mm,-3.5mm) [out=0, in=120] to (cwt9);
          \path [llenwi cath=#1]
            (cwt20a) [out=80, in=-80] to (cwt20b) [out=170, in=90] to (cwt6) [out=-90, in=165] to cycle
            ;
          \foreach \i in {10,...,19}
            \draw [stripiau cwt=#1] (cwt\i a) [out=90, in=-60] to (cwt\i b);
        \end{scope}
        \draw [ultra thick, name path=cwt]
          (corff5) [out=-80, in=-15] to (cwt5)
            [out=165, in=-90] to (cwt6)
            [out=90, in=170] to (cwt7)
            [out=-10, in=-95] to (cwt8)
          ;
         \begin{scope}[on foreground layer={ultra thick}]
          \draw
            (pen10) -- ++(0,7.5mm) coordinate (ceg1)
              [out=-45, in=180] to +(5mm,-2.5mm) coordinate (ceg2)
              [out=0, in=-100] to +(2.5mm,3.5mm) coordinate (ceg3)
             ;
          \draw
            (ceg1)
              [out=-135, in=0] to +(-5mm,-2.5mm) coordinate (ceg4)
              [out=180, in=-80] to +(-2.5mm,3.5mm) coordinate (ceg5)
            ;
          \path (ceg1)
            node (trwyn1) [trwyn, anchor=west] {}
            node (trwyn2) [trwyn, anchor=east] {};
          \draw
            ($(trwyn1)!1/2!(trwyn2)$) coordinate (trwyn) [out=10,in=140] to +(25mm,7.5mm)
            (trwyn) [out=-10, in=120] to +(.5mm,-5mm)
            (trwyn) [out=-40, in=130] to +(-1.5mm,-5mm)
            ;
          \draw
            (trwyn) [out=170,in=40] to +(-25mm,7.5mm)
            (trwyn) [out=-170, in=60] to +(-.5mm,-5mm)
            (trwyn) [out=-140, in=50] to +(1.5mm,-5mm)
            ;
          \path (ceg1)
            node (trwyn1) [trwyn, draw, ball color=#5, anchor=west] {}
            node (trwyn2) [trwyn, draw, ball color=#5, anchor=east] {};
         \end{scope}
          \draw [llygaid={#3}{#4}]
          ({$(pen1)!2/5!(pen10)$} -| {$(pen8)!3/4!(pen4)$}) coordinate (llygad chwith)
            ++(-5mm,0) coordinate (llygad chwith 1) [out=20, in=180] to ++(6mm,2.5mm) coordinate (llygad chwith 2) [out=0, in=120] to ++(4mm,-2.5mm)
            [out=-120, in=0] to ++(-4mm,-2.5mm) [out=180, in=-20] to ++(-6mm,2.5mm)
          ;
          \draw [llygaid={#3}{#4}]
            ({$(pen1)!2/5!(pen10)$} -| {$(pen9)!3/4!(pen3)$}) coordinate (llygad de)
              ++(5mm,0) coordinate (llygad de 1) [out=160, in=0] to ++(-6mm,2.5mm) coordinate (llygad de 2) [out=180, in=40] to ++(-4mm,-2.5mm)
              [out=-40, in=180] to ++(4mm,-2.5mm) [out=0, in=-160] to ++(6mm,2.5mm)
          ;
          \fill [ball color=black] (llygad chwith 1 -| llygad chwith 2) circle (2.5mm);
          \fill [ball color=black] (llygad de 1 -| llygad de 2) circle (2.5mm);
          \begin{scope}[on foreground layer={ultra thick}]
            \draw [shorten >=1pt]
              ($(pen2)!7/10!(pen3)$) coordinate (clust1) [out=125, in=-80] to (pen6);
            \draw [shorten >=1pt]
              ($(pen5)!7/10!(pen4)$) coordinate (clust2) [out=55, in=-100] to (pen7);
          \end{scope}
          \begin{scope}% llenwi clust de
            \clip (clust1) [out=125, in=-80] to (pen6) [out=-110, in=80] to (pen2) |- cycle;
            \path [stripiau corff=#1, rounded corners=1pt]
              (clust1) [out=125, in=-80] to (pen6) [out=-110, in=80] to (pen2) arc (65:45:19mm and 20mm)
              ;
          \end{scope}
          \begin{scope}% llenwi clust chwith
            \clip (clust2) [out=55, in=-100] to (pen7) [out=-70, in=100] to (pen5) |- cycle;
            \path [stripiau corff=#1, rounded corners=1pt]
              (clust2) [out=55, in=-100] to (pen7) [out=-70, in=100] to (pen5) arc (-245:-225:19mm and 20mm)
              ;
          \end{scope}
          % dim yn ddefnyddiol ar hyn o bryd ond gobeithio bynnan nhw ar ôl iddyn nhw fix the bug!
          \coordinate (-pen) at (pen1);
          \coordinate (-clust chwith) at (pen7);
          \coordinate (-clust de) at (pen6);
        }
    },
}
\makeatother
\begin{document}
  \colorlet{lliw llygaid3}{Chartreuse1}
  \colorlet{lliw llygaid4}{Green4}
  \colorlet{lliw trwyn1}{LightPink2}
  \colorlet{cath5}{LavenderBlush3}
  \colorlet{cath6}{LavenderBlush4}
  \begin{tikzpicture}
    \pic {cath b={cath6}{cath5}{lliw llygaid3}{lliw llygaid4}{lliw trwyn1}};
  \end{tikzpicture}
\end{document}

(6) +1 for "cat code" - musarithmia
(2) On my own machine, I now have a TikZ library of cat codes ;). - cfr
(2) compat=1.0-all on v2.x compiles the old code. Unbelievable! ;-) - Sašo Živanović
I have this error. ("C:\Users\uy\AppData\Local\Programs\MiKTeX 2.9\tex/latex/epstopdf-pkg\epstopdf -base.sty") ! Missing number, treated as zero. <to be read again> \forest@id@of@cath - shj37
@shj37 Did you try with the compat thing? Sašo said it worked, but that was 4 years ago .... - cfr
(1) @shj37 It should work now - thanks. The code posted assumed a cat, even when there wasn't one. Not a bad policy for life, but disastrous for code. - cfr
@cfr It's working now. Thank you. - shj37
9
[+40] [2011-12-24 18:45:48] Harold Cavendish

I have learned a couple of new things in TikZ and created an own minimalistic version loosely based on Altermundus' first creation (and a beautiful one it is). Hopefully he does not mind. Merry Christmas to all of you!

\documentclass[border=2mm]{standalone}
\usepackage[dvipsnames]{xcolor}  
\usepackage{tikz}
\usetikzlibrary{shapes,decorations.shapes}
\newsavebox{\ball}
\savebox{\ball}{ 
\begin{tikzpicture}[scale=.1]
\draw (0,0) -- (0, 5);
\shadedraw[ball color=red] (0,0) circle (60pt);
\end{tikzpicture}
} 
\begin{document}
\begin{tikzpicture} 
   \draw[fill=RawSienna] 
   (-.5,-1)  -- (.5,-1) -- (.5,4) -- (-.5,4) -- (-.5,-1) ;
\draw[fill=green!50!black] 
(-3.5,2) -- (3.5, 2) -- (1.5,4) -- (3, 4) -- (1, 6) -- (2, 6) -- (0,9) -- (-2,6) -- (-1,6) -- (-3,4) -- (-1.5,4) -- (-3.5,2);
\foreach\deco in {(1.5,5.65),(-1.5,5.65),(0.75,7.5),(-0.75,7.5),(-2,3.65), (2,3.65), (2.6,1.65),(-2.6,1.65)}
\node at \deco {\usebox{\ball}} ; 
 \node [star, star point height=.3cm, minimum size=1.2cm, draw,fill=yellow] at (0,9.1) {};
\end{tikzpicture}
\end{document}

Christmas tree.


10
[+35] [2011-12-24 18:31:02] cmhughes

Merry Christmast everyone!

animation

\documentclass{beamer}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\usepackage{animate}
\usepackage{hyperref}
\hypersetup{pdfpagemode=FullScreen}
\usepackage{ifthen}
\newcounter{mycount}
\setcounter{mycount}{0}

\begin{document}

\begin{frame}[fragile]{}
\begin{center}
\resizebox{5cm}{!}{%
    \begin{animateinline}[loop, poster = first,controls]{10}
    \whiledo{\themycount<10}{
        \begin{tikzpicture}[ballstyle/.style={circle,draw=blue!50,fill=\c,thick, minimum size=6mm}]
             \pgfmathdeclarerandomlist{color}{{red}{blue}{yellow}{white}{purple}}
             \pgfmathrandomitem{\c}{color}
             \foreach\ycoord in {-3,0,3}{
                \draw[fill=green,draw=green] (-3,\ycoord)--(3,\ycoord)--(0,\ycoord+3)--cycle;
                \node at (3,\ycoord) [ballstyle] {};
                \node at (-3,\ycoord) [ballstyle] {};}
             \node at (0,6) [star,fill =yellow,minimum size=2cm] {};
             \draw[fill=brown,draw=black] (-1,-3)--(1,-3)--(1,-5)--(-1,-5)--cycle;
        \end{tikzpicture}
        \stepcounter{mycount}
        \ifthenelse{\themycount<10}{
                \newframe
        }{
                \end{animateinline}
        }
        }
    }
\end{center}
\end{frame}

\end{document}

(2) For slightly more realistic trees you could use the one here: tex.stackexchange.com/a/34676/2693 - Alan Munn
@AlanMunn Thanks, I was looking for that post! I was mainly concentrating on the animation. - cmhughes
11
[+21] [2012-02-09 01:31:55] hpekristiansen

Just a tree

tree

with extremely ugly code(I do not know how to do it corectly?! -ovelay and center):

\documentclass{article}
\usepackage{overpic}
\usepackage{graphicx} 
\begin{document}
\begin{overpic}[unit=1cm, width=8cm, height=12cm]{ttt}
\put(14.5,0){\includegraphics[width=4cm,height=12cm]{ttt}}
\put(23,0){\includegraphics[width=1.5cm,height=12cm]{ttt}}
\end{overpic}
\end{document}

ttt.pdf is the compiled tree from the question.


(1) I don't see how this answers the original question. - Werner
(10) @werner: It doesn't, and I would never expect it to be accepted as an answer. I consider it to be a contribution never the less. - hpekristiansen
12
[+16] [2014-06-04 19:03:15] Steven B. Segletes

I'm starting my Christmas decorating early, very early.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{lindenmayersystems}
\usepackage{stackengine}
\usepackage{simpsons}
\newcommand\ball[4][]{\stackinset{c}{}{c}{#1}{#4}{\textcolor{#2}{\scalebox{#3}{$\bullet$}}}}
\newlength\tmplen
\newcommand\rb[2]{\tmplen=#1\baselineskip\relax\tmplen=.07\tmplen\relax%
  \raisebox{\tmplen}{#2}}
\begin{document}
\setbox0=\hbox{
\begin{tikzpicture}
\draw [color=green!50!black, l-system={rule set={S -> [+++G][---G]TS,
  G -> +H[-G]L, H -> -G[+H]L, T -> TL, L -> [-FFF][+FFF]F}, step=4pt, angle=18,
 axiom=+++++SLFFF, order=11}] lindenmayer system -- cycle;
\end{tikzpicture}
}
\centering
\stackinset{c}{.6in}{b}{.8in}  {\ball[1pt] {green!15}{3}  {\P}}{%
\stackinset{c}{-1.2in}{b}{1in}  {\ball[.6pt]{red}     {4}  {\textcolor{white}{\S}}}{%
\stackinset{c}{0in}{b}{2.5in}   {\ball      {red!30}  {5}  {\tiny\LaTeX{}}}{%
\stackinset{c}{.2in}{b}{2in}    {\ball[1pt] {green!60}{3}  {@}}{%
\stackinset{c}{-.6in}{b}{1.3in} {\ball[.5pt]{yellow}  {2.5}{\footnotesize A}}{%
\stackinset{c}{1.4in}{b}{.8in}  {\ball[.5pt]{yellow}  {2.5}{\footnotesize $\Omega$}}{%
\stackinset{c}{.7in}{b}{1.1in}  {\ball[1pt] {blue!50} {4.3}{\scalebox{.42}{\Bart}}}{%
\stackinset{c}{-.24in}{b}{.8in} {\ball[1pt] {cyan!20} {4.3}{\scalebox{.42}{\Homer}}}{%
\stackinset{c}{-.3in}{b}{1.75in}{\ball[1pt] {cyan!40} {4.3}{\scalebox{.33}{\Marge}}}{%
\stackinset{c}{-0.7in}{b}{.75in}{\ball[1pt] {green!40}{4.3}{\scalebox{.42}{\Lisa}}}{%
\stackinset{c}{0.2in}{b}{1.4in} {\ball[1pt] {blue!10} {4.3}{\scalebox{.42}{\Maggie}}}{%
\hspace{5.8ex}\box0
}}}}}}}}}}}\par
\vspace{-.7in}\bfseries\noindent\hspace{5.8ex}%
\rb{12}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{M}}}\kern-2pt}%
\rb{7}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{e}}}\kern-2pt}%
\rb{3}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{r}}}\kern-2pt}%
\rb{1}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{r}}}\kern-2pt}%
\rb{0}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{y}}}\kern-2pt}%
\rb{1}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{ }}}\kern-2pt}%
\rb{4}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{C}}}\kern-2pt}%
\rb{9}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{h}}}\kern-2pt}%
\rb{9}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{r}}}\kern-2pt}%
\rb{4}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{i}}}\kern-2pt}%
\rb{1}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{s}}}\kern-2pt}%
\rb{0}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{t}}}\kern-2pt}%
\rb{0}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{m}}}\kern-2pt}%
\rb{1}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{a}}}\kern-2pt}%
\rb{4}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{s}}}\kern-2pt}%
\rb{9}{\ball[-2pt]{red}{3.4}{\smash{\textcolor{white}{!}}}\kern-2pt}%
\end{document}

enter image description here


13
[+15] [2015-12-24 14:17:21] Tobi

This is the one I made for the 24. “door” of my TikZ Advent Calendar in my Blog [1] (in German):

christmas tree

Merry Christmas to all fellow TeX.SX users!


\documentclass[border=5mm,tikz]{standalone}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{chancery}

\usepackage{tikz}
\usetikzlibrary{
   arrows.meta,
   backgrounds,
   calc,
   decorations.pathmorphing,
   decorations.text,
   shapes.geometric,
}

\begin{document}
\begin{tikzpicture}[
   bauble/.pic = {
      \shade [ball color = yellow!60!brown]
         (0,-0.9) circle [radius = 0.3];
      \draw [
         ultra thick,
         red,
         -{>[scale=0.6]<[scale=0.9]},
      ] (0,-0.6) -- (0,0);
      \shade [
         left color = yellow!40!brown,
         right color = yellow!30!black,
      ]
         (-0.1,-0.62) to[bend right, looseness = 0.6]
         (0.1,-0.62) -- ++(0,0.1) -| cycle;
   },
]
   % Star
   \node (Stern) [
      star,
      star point height = 6mm,
      minimum size = 20mm,
      thick,
      draw = yellow!60!brown,
      inner color = yellow!40!brown,
      outer color = yellow!80!brown,
      rotate = 50,
   ] at (3,14) {};
   \begin{scope}[on background layer]
      \shade [
         left color = yellow!60!brown,
         right color = white,
      ]
         ($(Stern.center)-(0,0.1)$) -- ($(Stern.center)+(0,0.1)$)
         to[bend left] ++(4,1) -- ++(0.5,-1.5)
         to[bend right] cycle;
   \end{scope}
   % Trunk
   \begin{scope}
      \filldraw [
         fill = brown!55!black,
         draw = brown!35!black,
         thick,
      ] (-1,0) rectangle (1,2);
      \clip (-1,0) rectangle (1,2);
      \foreach \x in {-1,-0.9,...,1}
         \draw [
            brown!35!black,
            ultra thick,
            decoration = {
               random steps,
               segment length = 1mm,
               amplitude = 0.25mm
            }, decorate
         ] (\x,0) -- ++(0,2);
   \end{scope}
   % Branches
   \foreach \b/\y [count = \n]
   in {6/2, 5.5/3.5, 5/5, 4.5/6.5, 3.5/8, 2.5/9.5}
      \shadedraw [
         outer color = green!35!black,
         inner color = green!60!black,
         draw = green!35!black,
         looseness = 0.6,
      ]
         (-\b,\y-0.5) coordinate (L-\n)
         to [bend right] coordinate [midway] (LM-\n)
         (0,\y) coordinate (M-\n)
         to [bend right] coordinate [midway] (RM-\n)
         (\b,\y-0.6) coordinate (R-\n)
         to [bend left] coordinate [pos = 0.2 + 0.05*rand] (RS-\n)
         (0,\y+4) coordinate (S-\n)
         to [bend left] coordinate [pos = 0.8 + 0.05*rand] (LS-\n)
         cycle;
   % Top
   \shadedraw [
      left color = yellow!20!brown,
      right color = yellow!80!brown,
      draw = yellow!40!brown,
      looseness = 0.4,
   ] ($(S-6)-(0.45,1.5)$)
      to [bend right] ++(0.9,0) 
      to [bend left] ($(S-6)+(0,0.25)$)
      to [bend left] cycle;
   \draw [
      draw = yellow!40!brown,
      ultra thick,
      >>-{Rays[n = 6, width = 4mm, length = 4mm]},
      line cap = round,
   ] ($(S-6)+(0,-0.4)$) -- ++(0,0.8);
   % Decoration
   \begin{scope}[
      ultra thick,
      decoration = {
         coil,
         aspect = 0.4,
         amplitude = 2mm,
         segment length = 1.5mm,
      },
   ]
      \draw [red, decorate, bend right]
         (LS-6) to (RS-5)
         (LS-4) to (RS-3)
         (LS-2) to (RS-1);
      \draw [red!75!black, decorate, bend left]
         (RS-6) to (LS-5)
         (RS-4) to (LS-3)
         (RS-2) to (LS-1);
   \end{scope}
   % Baubles
   \path
      ($(S-6)-(0.3,2.75)$) pic {bauble}
      ($(S-4)-(1.1,3.15)$) pic {bauble}
      ($(S-4)+(1.2,-3.4)$) pic {bauble}
      ($(S-2)-(1.9,3.8)$)  pic {bauble}
      ($(S-2)+(0.2,-3.3)$) pic {bauble}
      ($(S-2)+(1.8,-3.6)$) pic {bauble};
   % Texts
   \path [
      decoration = {
         text along path,
         text = {|\Huge|Merry Christmas!},
         text align = left,
      }, decorate,
   ] (-5,13.5) to[bend left] ++(7,2);
   \node [
      font = \Huge,
   ] at (4.5,-1.5) {… and a happy New Year!};
   % Show tree coordinates
%   \foreach \n in {1,...,6}
%      \filldraw [
%         draw = white,
%         thick,
%         every node/.style = {
%            above = 1pt,
%            font = \sffamily\scriptsize,
%            fill = white,
%            inner sep = 1pt,
%         },
%         every circle/.style = {
%            radius = 0.6mm
%         },
%      ]
%         (L-\n)  circle node {L-\n}
%         (LM-\n) circle node {LM-\n}
%         (M-\n)  circle node {M-\n}
%         (RM-\n) circle node {RM-\n}
%         (R-\n)  circle node {R-\n}
%         (RS-\n) circle node {RS-\n}
%         (S-\n)  circle node {S-\n}
%         (LS-\n) circle node {LS-\n};
\end{tikzpicture}
\end{document}
[1] http://tobiw.de/tbdm/tikz-adventskalender

14
[+15] [2020-12-24 11:19:35] Rmano

Well, for 2020 (we really deserve something for 2020), with circuitikz:

enter image description here

Plain bog simple LaTeX code (I would never try to compete with David Carlisle's one [1])...

\documentclass[border=10pt]{standalone}
\usepackage[siunitx, RPvoltages]{circuitikz}
\ctikzsetstyle{romano}
\pgfmathdeclarerandomlist{MyRandomColors}{%
    {red}%
    {blue}%
    {cyan}%
    {orange}%
    {yellow}%
}%

\begin{document}
\begin{circuitikz}[y=-1cm, thick]
    \draw [color=orange!50!black] (0,6) to[generic, fill=orange!50!black] (0,8) node[ground]{};
    \foreach \y in {2,4,6} {
        \foreach \x in {-\y,0,\y} {
            \draw [color=green!50!black] (0.5*\x,\y) to [R] ({0.5*\x-sign(\x)},\y-2);
        }
        \draw[color=green!50!black] (-0.5*\y, \y) to[R] (0,\y) to[R] (0.5*\y,\y);
    }
    \foreach \y in {2,4,6} {
        \foreach \x in {-\y,0,\y} {
            \pgfmathrandomitem{\RandomColor}{MyRandomColors}
            \node [circ, color=\RandomColor] at(0.5*\x,\y) {};
        }
    }
    \node [circ, color=red] at(0,0) {};
\end{circuitikz}
\end{document}
[1] https://tex.stackexchange.com/a/79151/38080

(1) That is one resistant tree! :D - morbusg
@morbusg clearly, it is! ;-) - Rmano
15
[+13] [2015-12-25 11:58:53] Henri Menke

This is not done with decorations, but with Lua. I hope you enjoy this fractal christmas tree. Play around with the values in \maketree to vary the number of points to be computed.

\documentclass{article}
\pagestyle{empty}
\usepackage{luacode,pgfplots}
\begin{luacode*}
rects = {
   -- lower branches
   {{0.6,0.2}, {0.6,0.5}, {0.0,0.0}},
   {{0.4,0.2}, {0.4,0.5}, {1.0,0.0}},
   -- lower middle branches
   {{0.6,0.35}, {0.6,0.65}, {0.15,0.13}},
   {{0.4,0.35}, {0.4,0.65}, {0.85,0.13}},
   -- upper middle branches
   {{0.6,0.45}, {0.6,0.75}, {0.2,0.25}},
   {{0.4,0.45}, {0.4,0.75}, {0.8,0.25}},
   -- top
   {{0.4,0.5}, {0.6,0.5}, {0.4,1}}
}

function calculate_transform(a,b,c)
   -- Calculate the transformation matrix and return it as a
   -- table with matrix and offset vector
   A_temp = { {0,0}, {0,0} }
   A_temp[1][1] = b[1] - a[1]
   A_temp[2][1] = b[2] - a[2]
   A_temp[1][2] = c[1] - a[1]
   A_temp[2][2] = c[2] - a[2]
   return { A_temp, a }
end

function apply_transform(T, p)
   -- Apply the transformation on the point p
   -- and return the new point
   A_temp = T[1]
   a_temp = T[2]
   p_new = { 0,0 }
   for i=1,#A_temp do
      for j=1,#A_temp[i] do
         p_new[i] = p_new[i] + A_temp[i][j]*p[j]
      end
   end
   for i=1,#p_new do
      p_new[i] = p_new[i] + a_temp[i]
   end
   return p_new
end

function make_trafos()
   -- Create a table of all transformations
   T = {}
   for i=1,#rects do
      T[i] = calculate_transform(rects[i][1], rects[i][2], rects[i][3])
   end
   return T
end

function calculate_attractor(trafos, N)
   -- Create a table of points which make up the
   -- fractal tree
   p_0 = { 0,0 }
   pos_list = {}

   -- Discard the first 100 points (warm up)
   for i=0,100 do
      p_0 = apply_transform(trafos[math.random(1, #trafos)], p_0)
   end

   -- Create the table of points
   for i=1,N do
      -- Apply a random transformation to the current p_0
      p_0 = apply_transform(trafos[math.random(1, #trafos)], p_0)
      pos_list[i] = p_0
   end

   return pos_list
end

function make_tree(Max_Points)
   -- Get the list of transformations
   trafos = make_trafos()

   -- Calculate the tree for Max_Points
   data = calculate_attractor(trafos, Max_Points)

   -- Output for pgfplots
   for i=1,#data do
      tex.sprint("(" .. data[i][1] .. "," .. data[i][2] .. ")")
   end
end
\end{luacode*}

\newcommand\maketree[1]{
  \directlua{make_tree(#1)}
}

\begin{document}
\begin{tikzpicture}
  \begin{axis}[balls/.style 2 args = {
      only marks,mark size=#2,
      every mark/.append style={draw=#1,fill=#1}
    },
    balls/.default={green!50!black}{.5pt}]
    \addplot[balls] coordinates {\maketree{10000}};
    \addplot[balls={green}{2pt}] coordinates {\maketree{10}};
    \addplot[balls={red}{2pt}] coordinates {\maketree{10}};
    \addplot[balls={blue}{2pt}] coordinates {\maketree{10}};
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here


16
[+12] [2015-12-20 18:44:55] Tom Bombadil

This answer is a by-product of my answer to " December challenge: Create an Advent Calendar [1]". You can choose the amount of "snow" on the branches, and the size of the picture. However, the picture can't be too small [2], it fails for factors below 3.6.

Code

\documentclass[tikz, border=2mm]{standalone}
\usetikzlibrary{decorations.markings}

\newcommand{\NordmannFir}[3]%
% shift, scale, day
{ \begin{scope}[shift={(#1)}, scale=#2]
        \pgfmathsetmacro{\C}{2+#3*4}
        \colorlet{LightFir}{green!50!gray!75!black}
        \colorlet{DarkFir}{green!35!black}
        \colorlet{Snow}{cyan!80!blue!15}
        \colorlet{Trunk}{brown!50!gray!70!black}

        \fill[left color=Trunk!80, right color=Trunk!80, middle color=Trunk] (0,0) arc (270:180:0.05 and 0.01) -- (0,1) -- (0.05,0.01) arc (360:270:0.05 and 0.01) -- cycle;

        \foreach \y in {0,...,11}
        {   \fill[bottom color=DarkFir, top color=Snow!\C!LightFir, middle color=Snow!\C!LightFir] (-0.35+0.025*\y,0.07*\y+0.06) to[out=0,in=200,looseness=0.5] (0,\y*0.07+0.09) to[out=-20, in=180, looseness=0.5] ++ (0.35-\y*0.025,-0.03) to[out=170,in=-30] ++ (-0.35+\y*0.025,0.155-\y*0.005) to[out=210,in=10] ++ (-0.35+\y*0.025,-0.155+\y*0.005) -- cycle;
        }
    \end{scope}
}

\newcommand{\RegStar}[5]%
% inner radius, outer radius, tips, rot angle, options
{   \pgfmathsetmacro{\starangle}{360/#3}
    \draw[#5] (#4:#1)
    \foreach \x in {1,...,#3}
    { -- (#4+\x*\starangle-\starangle/2:#2) -- (#4+\x*\starangle:#1)
    }
    -- cycle;
}

\newcommand{\NGram}[4]%
% outer radius, tips, rot angle, options
{   \pgfmathsetmacro{\starangle}{360/#2}
    \pgfmathsetmacro{\innerradius}{#1*sin(90-\starangle)/sin(90+\starangle/2)}
    \RegStar{\innerradius}{#1}{#2}{#3}{#4}
}

\newcommand{\DecoratedTree}[2]% scale (>=3.6 !!!!), Snowiness (0...24)
{   \begin{scope}[scale=#1]
    \fill[inner color=blue!40!black, outer color=blue!10!black] (0.02,0.02) rectangle (0.98,0.98);
    \NordmannFir{0.5,0.1}{0.8}{#2}
    \NGram{0.03}{7}{-90}{shift={(0.5,0.9)},inner color=red, outer color=yellow, draw=orange}

    \foreach \LR in {1,-1}
    {   \foreach \y in {0,...,11}
        {   \pgfmathtruncatemacro{\C}{mod(\LR*\y+13,3)}
            \draw[white, line width=#1/100*28.452756*0.2] ({0.5+(-\LR*0.34+\LR*0.025*\y)*0.8},{0.1+(0.07*\y+0.04)*0.8}) -- ++ (0,0.018);
            \fill[ball color=\ifcase\C cyan\or magenta\or yellow\fi] ({0.5+(-\LR*0.34+\LR*0.025*\y)*0.8},{0.1+(0.07*\y+0.04)*0.8}) circle (0.012);
        }
    }
    \fill[ball color=green!50!gray!75] (0.5,0.8) circle(0.016);

    \xdef\CuCo{0}

    \draw
    [   yellow,
        bend left=10,
        decoration=
        {   markings,
            mark=between positions 0.01 and 1 step 0.02 with
            {   
                \pgfmathtruncatemacro{\C}{mod(\CuCo,3)}
                \fill[inner color=\ifcase\C red\or blue\or yellow\fi, outer color=transparent, opacity=0.07] (0,0) circle (0.03*#1);
                \fill[inner color=\ifcase\C red\or blue\or yellow\fi, outer color=\ifcase\C red!50\or blue!50\or yellow!50\fi] (0,0) circle (0.005*#1);
                \pgfmathparse{\CuCo+1}
                \xdef\CuCo{\pgfmathresult}
            }
        },
        postaction={decorate}] (0.61,0.21) to (0.40,0.265) (0.585,0.325) to (0.43,0.38) (0.56,0.44) to (0.45,0.50) (0.55,0.55) to (0.46,0.61) (0.53,0.665) to (0.475,0.72);
    \end{scope}
}

\begin{document}

\foreach \S in {0,...,24}
{   \begin{tikzpicture}
        \DecoratedTree{10}{\S}
    \end{tikzpicture}
}

\foreach \S in {23,...,1}
{   \begin{tikzpicture}
        \DecoratedTree{10}{\S}
    \end{tikzpicture}
}

\end{document}

Output (1st page)

enter image description here

Animation (increasing & decreasing snow)

produced with ImageMagick [3] via

convert -loop 0 -delay 15 -dispose previous -density 95 xmas.pdf xmas.gif

Click here. Warning: ~ 2MB [4]

[1] https://tex.stackexchange.com/questions/280771/december-challenge-create-an-advent-calendar/280799#280799
[2] https://tex.stackexchange.com/questions/284008/problem-with-decorations-in-a-small-tikz-picture
[3] http://www.imagemagick.org/script/index.php
[4] https://i.stack.imgur.com/kThKU.gif

17
[+11] [2018-12-15 15:14:58] Ulysses

Here is my own little Christmas tree for this collection. I have decorated it with baubles, tinsel, flashing fairy lights, and a star tree-topper, and placed presents beneath the tree.

Ulysses's Christmas Tree

Code:

\documentclass[a4paper,landscape]{article}
%\documentclass[export]{standalone}
% All design and code created by Ulysses. Please credit me if you use a significant portion of this anywhere.

\usepackage[margin=0.5cm]{geometry}
\usepackage{animate}
\usepackage{tikz}
\usetikzlibrary{snakes,shapes,fadings}
\usepackage{times}

\tikzfading[name=littleglow,inner color=transparent!0,outer color=transparent!100]
\tikzfading[name=bigglow,inner color=transparent!30,outer color=transparent!100]
\newcommand{\light}[1]{
    \fill[fill=white,path fading=littleglow] (#1) circle (0.07cm);
    \fill[fill=white,path fading=bigglow] (#1) circle (0.15cm);
}

\newcommand{\present}[4]{
    \begin{scope}[xshift=#3,yshift=#4]
    \filldraw[fill=#1,draw=black,thick] (0,0) rectangle ++(2,2);
    \draw[draw=black,thick,double distance=3mm, double=#2,cap=rect] (0.15,1) -- ++(1.7,0);
    \draw[draw=black,thick,double distance=3mm, double=#2,cap=rect] (1,0.15) -- ++(0,1.7);
    \filldraw[fill=#2,draw=black,thick] (1,2.05) -- ++(-85:0.8cm) -- ++(55:0.2cm) -- ++(-35:0.2cm) -- ++(105:0.8cm);
    \filldraw[fill=#2,draw=black,thick] (1,2.05) -- ++(-95:0.8cm) -- ++(125:0.2cm) -- ++(205:0.2cm) -- ++(75:0.8cm);
    \filldraw[fill=#2,draw=black,thick] (1.1,2.15) .. controls ++(0.25,0.2) .. ++(0.5,0.3) .. controls ++(0.1,-0.1) and ++(0.1,0.1) .. ++(0,-0.8) .. controls ++(-0.25,0.1) .. ++(-0.5,0.3);
    \filldraw[fill=#2,draw=black,thick] (0.9,2.15) .. controls ++(-0.25,0.2) .. ++(-0.5,0.3) .. controls ++(-0.1,-0.1) and ++(-0.1,0.1) .. ++(0,-0.8) .. controls ++(0.25,0.1) .. ++(0.5,0.3);
    \filldraw[fill=#2,draw=black,thick] (0.9,1.95) rectangle ++(0.2,0.2);
    \end{scope}
}

\newcommand{\base}[2]{
\begin{tikzpicture}
    % Guide lines
    %\draw[step=1cm,lightgray,very thin] (-20,-14) grid (20,14);
    %\draw[step=0.2cm,lightgray,very thin] (-7,-7) grid (0,2);
    %\draw[step=1cm,cyan,very thin] (-7,-7) grid (0,2);

    % Jumper
    %\filldraw[fill=cyan!20!white!,draw=black, line width=3pt] (-5,13) arc (180:360:5cm and 3cm) -- ++(5,0) -- ++(10,-17) -- ++(-4,-2) -- ++(-6,10.2) -- ++(0,-17.2) -- ++(-20,0) -- ++(0,17.2) -- ++(-6,-10.2) -- ++(-4,2) -- ++(10,17) -- ++(5,0);
    %\filldraw[fill=cyan!40!white!,draw=black, line width=3pt] (-5,13) arc (180:360:5cm and 3cm) -- ++(1,0) arc (180:360:-6cm and 4cm) -- ++(1,0);
    %\filldraw[fill=cyan!40!white!,draw=black, line width=3pt] (20,-4) -- ++(-4,-2) -- ++(-0.5068,0.862) -- ++(4,2) -- ++(0.5068,-0.862);
    %\filldraw[fill=cyan!40!white!,draw=black, line width=3pt] (-20,-4) -- ++(4,-2) -- ++(0.5068,0.862) -- ++(-4,2) -- ++(-0.5068,-0.862);
    \filldraw[fill=cyan!20!white!,draw=black, line width=3pt] (-8,-8) rectangle ++(16,16);
    \draw (0,-7.7) node {\large Design and code created by Ulysses.};

    % Tree
    \filldraw[fill=green!40!black!,draw=black,thick] (0,6) .. controls ++(0,-0.5) and ++(-0.5,0) .. ++(2,-2) -- ++(-1,0) .. controls ++(0,-0.5) and ++(-0.5,0) .. ++(2,-2) -- ++(-1,0) .. controls ++(0,-0.5) and ++(-0.5,0) .. ++(2,-2) -- ++(-1,0) .. controls ++(0,-0.5) and ++(-0.5,0) .. ++(2,-2) -- ++(-10,0) .. controls ++(0.5,0) and ++(0,-0.5) .. ++(2,2) -- ++(-1,0) .. controls ++(0.5,0) and ++(0,-0.5) .. ++(2,2) -- ++(-1,0) .. controls ++(0.5,0) and ++(0,-0.5) .. ++(2,2) -- ++(-1,0) .. controls ++(0.5,0) and ++(0,-0.5) .. ++(2,2);
    \filldraw[fill=brown!50!black!,draw=black,thick] (-0.3,-2) rectangle (0.3,-3);
    \filldraw[fill=red!70!black!,draw=black,thick] (-1,-3) -- (1,-3) -- (0.7,-4.5) -- (-0.7,-4.5) -- (-1,-3);

    % Tinsel
    \draw[draw=black,thick,double distance=1mm, double=yellow!80!black!,cap=round,dotted] (1,4.65) .. controls ++(0,-0.5) and ++(1,-0.2) .. (-1.5,3.2);
    \draw[draw=black,thick,double distance=1mm, double=yellow!80!black!,cap=round,dotted] (1.85,2.8) .. controls ++(0,-0.5) and ++(1.5,-0.5) .. (-2.7,1);
    \draw[draw=black,thick,double distance=1mm, double=yellow!80!black!,cap=round,dotted] (2.7,0.95) .. controls ++(0,-0.5) and ++(2.5,-0.5) .. (-3.68,-1);

    % Baubles
    \shadedraw[ball color=red,draw=black,thick] (-0.5,4.5) circle (0.2cm);
    \shadedraw[ball color=blue,draw=black,thick] (1,3) circle (0.2cm);
    \shadedraw[ball color=yellow,draw=black,thick] (-0.3,2.7) circle (0.2cm);
    \shadedraw[ball color=green,draw=black,thick] (-1.5,1.5) circle (0.2cm);
    \shadedraw[ball color=green,draw=black,thick] (1.7,1.2) circle (0.2cm);
    \shadedraw[ball color=blue,draw=black,thick] (-0.1,0.8) circle (0.2cm);
    %\shadedraw[ball color=blue,draw=black,thick] (-0.9,0.5) circle (0.2cm);
    \shadedraw[ball color=yellow,draw=black,thick] (-2.2,-0.3) circle (0.2cm);
    \shadedraw[ball color=yellow,draw=black,thick] (2.3,-0.7) circle (0.2cm);
    \shadedraw[ball color=red,draw=black,thick] (0.4,-1.3) circle (0.2cm);
    \shadedraw[ball color=blue,draw=black,thick] (-3.4,-1.6) circle (0.2cm);

    % Star
    \filldraw (0,6) node[fill=yellow!90!black!,draw=black,thick,star,star points=4,star point ratio=4] {};
    \filldraw (0,6) node[fill=yellow!90!black!,draw=black,thick,star,star points=4,star point ratio=4,rotate=45] {};

    % Lights set 1
    \begin{scope}[opacity=#1]
    \light{0,3} \light{-1,3.5} \light{-0.2,4} \light{0.3,5} \light{1.2,4.3} \light{-1.2,4.2} \light{1.4,3} \light{0.6,2.2} \light{-0.9,1.8} \light{-1.7,2.5} \light{2.2,2.2} \light{1,1.4} \light{0.6,0.2} \light{-0.8,0.6} \light{-1.4,-0.4} \light{-2.6,0.4} \light{2.8,0.2} \light{-2.8,-0.7} \light{3.4,-1.6} \light{1.1,-0.6} \light{2,-1.4} \light{-0.6,-1.4} \light{-2,-1.8} \light{-4,-1.7}
    \end{scope}

    % Lights set 2
    \begin{scope}[opacity=#2]
    \light{0.4,3.3} \light{-0.7,3.8} \light{0.2,4.5} \light{-0.3,5.1} \light{1.4,4.15} \light{-0.9,4.4} \light{1.5,2.7} \light{0.1,2.5} \light{-0.6,1.6} \light{-1.2,2.7} \light{1.7,2.0} \light{1.4,0.8} \light{-0.2,0.1} \light{-1.8,0.5} \light{-1,-0.5} \light{-2.1,1.2} \light{2.6,-0.2} \light{-2.7,-0.2} \light{4,-1.7} \light{0.6,-0.7} \light{1.1,-1.6} \light{-1.3,-1.4} \light{-2.7,-1.5} \light{2.4,-1.3}
    \end{scope}

    % Presents
    \present{red}{yellow}{2cm}{-5.5cm}
    \present{green!60!black}{red}{-3.5cm}{-5cm}
    \present{blue!60!white}{cyan}{-2cm}{-6.25cm}
    \present{blue}{green}{1cm}{-6.75cm}

    \draw (0.62,-2.15) node {\tiny Ulysses};

\end{tikzpicture}
}

\begin{document}

\begin{figure}[p]
\centering
\begin{animateinline}[autoplay,loop,scale=1]{2}
\base{1}{0}
\newframe
\base{0}{1}
\end{animateinline}
\end{figure}
\end{document}

18
[+4] [2022-12-09 18:39:56] Thruston

Not enough Metapost [1] answers yet. Here is a pinwheel tiling [2] decorated with Christmas trees, arranged so it can be printed as a greetings card.

enter image description here

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
input colorbrewer-cmyk
vardef pinwheel(expr level, a, b, c, s) = 
    if level = 0:
        path t; t = a--b--9/10[b,c]--cycle;
        fill t withcolor Greens[9][s];
        draw t withpen pencircle scaled 1/8 withcolor Greens 9 1;
        fill unitsquare shifted 1/2 left shifted 1/8 down 
                        scaled 1.2 scaled if turningnumber t > 0: - fi 1
                        rotated angle (point 3 of t - point 2 of t)
                        shifted point 5/2 of t 
                        withcolor (s/8)[(0, 0, 0, 0), YlOrBr 5 5];
    else:
        save d, e, f, g;
        pair d, e, f, g; 
        d = 2/5[b, c]; e = 4/5[b,c]; f = 1/2[e, a]; g = 1/2[a, b];
        pinwheel(level - 1, e, a, c, 4);
        pinwheel(level - 1, f, g, a, 3);
        pinwheel(level - 1, f, g, e, 2);
        pinwheel(level - 1, d, e, g, 5);
        pinwheel(level - 1, d, b, g, 6);
    fi
enddef;
beginfig(1);
    numeric a, b; b = 210mm; 2a = b; 
    pinwheel(4, (0, 0), (b, 0), (0, a), ""); 
    pinwheel(4, (b, a), (0, a), (b, 0), "");
    clip currentpicture to unitsquare xscaled 148mm yscaled 105mm;
    currentpicture := currentpicture rotated 90;
    bboxmargin := 0;
    draw bbox currentpicture shifted 297.6 left withcolor (0, 0, 0, 0); 
endfig;
\end{mplibcode}
\end{document}

You need to compile this one with lualatex.

[1] https://tug.org/metapost.html
[2] https://en.wikipedia.org/wiki/Pinwheel_tiling

I used the CMYK colours were because the printers wanted them in that gamut. Note that (0, 0, 0, 0) is white in CMYK. - Thruston
19