42

While thinking about creating an own Advent Calendar for the beloved people around me – instead of buying a boring one with chocolate in it – a thought came to my mind: "How would I draw this in TikZ?" And since I will go a different way this year and don't have time to realize a LaTeX version, I thought I could make it a challenge for the community.

So, here are the specifications the implementation should provide:

  • On a rectangular field, create 24 randomly distributed "windows" (represented by simple rectangles) that are labelled from 1 through 24.
  • The windows with number 1 through 23 shall be equal in size and aspect ratio, window number 24 can have a different aspect ratio but should cover about twice the area of the other ones.
  • It has to be made sure that no two windows are touching or even overlapping.
  • The placement of the windows shall be computed at runtime via random number generation (not from values somehow hard coded into the document), i.e. every LaTeX run should generate a new arrangement.

The challenge is not restricted to TikZ, every LaTeX package that can be used to accomplish this (pstricks, etc.) is allowed. If you need an idea, how the whole thing could look like, compare the following image. Note that this example differs in two points from the specified criteria: Not all windows are rectangular and not all of them have the same size.

Advent Calendar

So, let the challenge begin and bring the community into X-mas mood...

  • 3
    Jake did it for circles which you can tightly pack rectangles in them. See /tikz-distribute-evenly-and-randomly-circles and you can still put chocolate in it. – percusse Nov 30 '15 at 12:39
  • You could add a couple of images showing better what's the idea. – egreg Nov 30 '15 at 12:57
  • I've taken the liberty of adding the 'fun' tag. If you're not OK with this change, feel free to revert. – Mico Nov 30 '15 at 18:27
  • 1
    Does it have to be random? Pseudo-random? Or is it enough to get a different result on each compilation? Randomness is important for cryptography, for example, but seems like overkill here. Pseudo-randomness is faster but still strikes me as overkill just to get a different result. – cfr Dec 1 '15 at 1:18
  • Also, the image you've posted does not meet the criteria stated as desiderata. – cfr Dec 1 '15 at 1:19
18

I'll never be as festive and cheerful as Tom Bombadil so I won't even try. I just want to tackle the minimal problem using only LaTeX.

The following code distributes an arbitrary number of nonintersecting rectangles (with independent sizes) inside a rectangular field. The algorithm is just brute force with a threshold limiting the maximum number of attempts to place a rectangle; if exceeded, an error is thrown.

It's quite gross, but it works relatively well as long as there are just a few windows and these are much smaller than the field. Also, it's just eighty lines.

\documentclass[tikz,border=9]{standalone}

% initialize windows coordinates and sizes
\begingroup\globaldefs=1
  \foreach \n in {1,...,24}{
    \pgfqkeys{/advent/windows/\n}{
      x/.initial=0, w/.initial=1.62cm,
      y/.initial=0, h/.initial=1cm,}}
\endgroup

% double the area of the last one
\pgfqkeys{/advent/windows/24}{
  w=2.29cm, h=1.41cm,}

% define field size
\pgfqkeys{/advent/field}{
  w/.store in=\fW, w=16.2cm,
  h/.store in=\fH, h=10cm,}

% macro to randomly displace a window inside the field
\def\PlaceWindow#1{
  \pgfqkeys{/advent/windows/#1}{
    w/.get=\wW,
    h/.get=\wH,}
  \pgfmathsetmacro{\wX}{random()*(\fW-\wW)+.5*\wW}
  \pgfmathsetmacro{\wY}{random()*(\fH-\wH)+.5*\wH}
  \begingroup\globaldefs=1
    \pgfqkeys{/advent/windows/#1}{
      x/.expand once=\wX,
      y/.expand once=\wY,}
  \endgroup}

% macro to check for collisions and put the result in \CollisionStatus
\def\CheckCollision#1#2{
  \pgfqkeys{/advent/windows/#1}{
    x/.get=\aX, w/.get=\aW,
    y/.get=\aY, h/.get=\aH,}
  \pgfqkeys{/advent/windows/#2}{
    x/.get=\bX, w/.get=\bW,
    y/.get=\bY, h/.get=\bH,}
  \begingroup\globaldefs=1
    \pgfmathsetmacro{\CollisionStatus}%
      {(abs(\aX-\bX)<.5*(\aW+\bW))&&(abs(\aY-\bY)<.5*(\aH+\bH))}
  \endgroup}

% style to draw any window
\pgfkeys{/advent/windows/draw/.style={
  draw, rectangle, line width=2pt, node contents=#1, inner sep=0sp, font=\bf,
  xshift=\pgfkeysvalueof{/advent/windows/#1/x},
  yshift=\pgfkeysvalueof{/advent/windows/#1/y},
  minimum width=\pgfkeysvalueof{/advent/windows/#1/w}-\pgflinewidth,
  minimum height=\pgfkeysvalueof{/advent/windows/#1/h}-\pgflinewidth,},}

% style to draw the field
\pgfkeys{/advent/field/draw/.style={
  draw, rectangle, line width=4pt, node contents={},
  xshift=0.5*\fW, minimum width=\fW+\pgflinewidth,
  yshift=0.5*\fH, minimum height=\fH+\pgflinewidth,},}

% initialize pseudorandom number generator using custom seed if provided
\ifdefined\seed\pgfmathsetseed{\seed}\fi
% distibute windows on the field
\PlaceWindow1
\foreach \n in {2,...,24}{                 % try to place each window
  \foreach \t in {1,...,100}{              % up to a hundred times (THRESHOLD)
    \PlaceWindow\n
    \foreach \k [evaluate=\k using int(\k)] in {2-1,...-1,\n-1}{
      \CheckCollision\n\k                  % until it does not collide
      \if1\CollisionStatus\breakforeach\fi % with the preceeding ones
    }
    \if0\CollisionStatus\breakforeach\fi
  }
  \if1\CollisionStatus\errmessage{Sorry, 100 attempts were not enough.}\fi
}

%draw the thing
\begin{document}\begin{tikzpicture}
  \node[/advent/field/draw];
  \node [font=\Huge\bf] at (.5*\fW,2em+\fH) {Merry whatever.};
  \foreach \n in {1,...,24} \node[/advent/windows/draw=\n];
\end{tikzpicture}\end{document}

Each run gives a different result, as long as you wait a minute: TiKz default seed for pseudorandom numbers is \time*\year. If you want it to change every time just compile using the unix timestamp as a seed:

pdflatex \\def\seed{`date +%s`}\\input main.tex

This also allows for reproducibility. The seed 123 has a runtime of a couple of seconds and outputs

Merry whatever.

Not pretty, but I think the criteria are all satisfied.


UPDATED: aesthetics

I managed to throw some eye candy together while still keeping the code under 150 lines. Since the ordinary Christmas theme is already being adequately developed, I considered the alternative viewpoint.

Here is the code:

\RequirePackage[dvipsnames]{xcolor}
\documentclass[tikz]{standalone}

% initialize windows coordinates and sizes
\begingroup\globaldefs=1
  \foreach \n in {1,...,24}{
    \pgfqkeys{/advent/windows/\n}{
      x/.initial=0, w/.initial=1.62cm,
      y/.initial=0, h/.initial=1cm,}}
\endgroup

% double the area of the last one
\pgfqkeys{/advent/windows/24}{
  w=2.29cm, h=1.41cm,}

% define field size
\pgfqkeys{/advent/field}{
  w/.store in=\fW, w=16.2cm,
  h/.store in=\fH, h=10cm,}

% macro to randomly displace a window inside the field
\def\PlaceWindow#1{
  \pgfqkeys{/advent/windows/#1}{
    w/.get=\wW,
    h/.get=\wH,}
  \pgfmathsetmacro{\wX}{random()*(\fW-\wW)+.5*\wW}
  \pgfmathsetmacro{\wY}{random()*(\fH-\wH)+.5*\wH}
  \begingroup\globaldefs=1
    \pgfqkeys{/advent/windows/#1}{
      x/.expand once=\wX,
      y/.expand once=\wY,}
  \endgroup}

% macro to check for collisions and put the result in \CollisionStatus
\def\CheckCollision#1#2{
  \pgfqkeys{/advent/windows/#1}{
    x/.get=\aX, w/.get=\aW,
    y/.get=\aY, h/.get=\aH,}
  \pgfqkeys{/advent/windows/#2}{
    x/.get=\bX, w/.get=\bW,
    y/.get=\bY, h/.get=\bH,}
  \begingroup\globaldefs=1
    \pgfmathsetmacro{\CollisionStatus}%
      {(abs(\aX-\bX)<.5*(\aW+\bW))&&(abs(\aY-\bY)<.5*(\aH+\bH))}
  \endgroup}

% style to draw any window
\usepackage{contour} \contourlength{.6pt} \contournumber{200}
\pgfkeys{/advent/windows/draw/.style={
  Goldenrod, draw, rectangle, line width=.4pt,
  double=black, double distance=.4pt,
  node contents=\contour{Goldenrod}{\color{black}#1},
  inner sep=0sp, font=\bf\Huge,
  xshift=\pgfkeysvalueof{/advent/windows/#1/x}-.5*\fW,
  yshift=\pgfkeysvalueof{/advent/windows/#1/y}-.5*\fH,
  minimum width=\pgfkeysvalueof{/advent/windows/#1/w}-.6pt,
  minimum height=\pgfkeysvalueof{/advent/windows/#1/h}-.6pt,},}

% initialize pseudorandom number generator using custom seed if provided
\ifdefined\seed\pgfmathsetseed{\seed}\fi
% distibute windows on the field
\PlaceWindow1
\foreach \n in {2,...,24}{                 % try to place each window
  \foreach \t in {1,...,200}{              % up to a hundred times (THRESHOLD)
    \PlaceWindow\n
    \foreach \k [evaluate=\k using int(\k)] in {2-1,...-1,\n-1}{
      \CheckCollision\n\k                  % until it does not collide
      \if1\CollisionStatus\breakforeach\fi % with the preceeding ones
    }
    \if0\CollisionStatus\breakforeach\fi
  }
  \if1\CollisionStatus\errmessage{Sorry, 200 attempts were not enough.}\fi
}

% some tricks
\tikzset{
  moon shading/.code args={fill #1 to #2 then fade to #3}{
    \pgfdeclareradialshading{ring}{\pgfpoint{0cm}{0cm}}%
      {color(0)=(#1);color(25bp*#2)=(#1);color(25bp)=(#3)}
    \pgfkeysalso{/tikz/shading=ring}},
  fuzzy hills action/.style={
    line width=\pgflinewidth+2pt,draw opacity=.1,draw=#1,},
  fuzzy hills recursion/.code 2 args={%
    \pgfmathtruncatemacro{\level}{#1-1}%
    \if0\level\tikzset{preaction={fuzzy hills action=#2}}%
    \else\tikzset{preaction={fuzzy hills action=#2,
                             fuzzy hills recursion={\level}{#2}}}\fi},
  fuzzy hills/.style={
    preaction={fuzzy hills recursion={5}{#1}},draw opacity=1,draw=#1},
}

% draw the thing
\begin{document}\begin{tikzpicture}
  \coordinate [ rectangle, bottom color=violet, top color=black,
     minimum width=\fW+4pt, minimum height=\fH+4pt,];
  \coordinate [ circle, anchor=north, yshift=.5*\fH-8pt, minimum size=0.55*\fH,
    moon shading={fill Goldenrod to 0.8 then fade to BurntOrange},];
  \begin{scope}
    \clip [ rectangle, minimum width=\fW+8pt, minimum height=\fH+8pt];
    \fill [ fuzzy hills=Goldenrod!50!white, fill=purple!10!black]
      (-6cm,-7cm) ellipse (8cm and 6cm);
    \path [ scale=1/12.5, xscale=16.2+.5, yscale=10+.5,
            yshift=-6cm, xshift=-6.4cm,
            fuzzy hills=Goldenrod!50!white, fill=purple!10!black ]
      ( 7.33,8.60) .. controls ( 7.01,8.56) and ( 6.80,8.55) .. 
      ( 6.65,8.56) .. controls ( 6.44,8.41) and ( 6.29,8.35) .. 
      ( 6.16,8.33) .. controls ( 6.01,8.16) and ( 5.86,7.99) .. 
      ( 5.80,7.96) .. controls ( 5.60,7.60) and ( 5.52,7.39) .. 
      ( 5.44,7.17) .. controls ( 5.40,6.96) and ( 5.36,6.75) .. 
      ( 5.34,6.49) .. controls ( 5.35,6.36) and ( 5.36,6.26) .. 
      ( 5.41,5.98) .. controls ( 5.53,5.69) and ( 5.59,5.61) .. 
      ( 5.66,5.50) .. controls ( 5.83,5.49) and ( 5.87,5.39) .. 
      ( 6.18,5.56) .. controls ( 6.36,5.88) and ( 6.35,6.01) .. 
      ( 6.40,6.15) .. controls ( 6.38,6.32) and ( 6.36,6.49) .. 
      ( 6.30,6.69) .. controls ( 6.12,6.91) and ( 6.14,6.90) .. 
      ( 5.90,6.84) .. controls ( 5.74,6.59) and ( 5.72,6.46) .. 
      ( 5.76,6.14) .. controls ( 5.83,6.00) and ( 5.96,5.92) .. 
      ( 6.07,6.07) .. controls ( 6.14,6.30) and ( 6.15,6.26) .. 
      ( 6.05,6.50) --                           ( 5.95,6.33) --
      ( 6.02,6.31) .. controls ( 5.97,6.08) and ( 5.93,6.18) .. 
      ( 5.89,6.29) .. controls ( 5.90,6.39) and ( 5.87,6.45) .. 
      ( 6.00,6.68) .. controls ( 6.09,6.61) and ( 6.22,6.56) .. 
      ( 6.20,6.17) .. controls ( 6.16,6.11) and ( 6.19,5.94) .. 
      ( 5.91,5.84) .. controls ( 5.76,5.94) and ( 5.70,5.98) .. 
      ( 5.61,6.46) .. controls ( 5.65,6.75) and ( 5.74,7.00) .. 
      ( 5.85,7.14) .. controls ( 5.98,7.34) and ( 6.15,7.50) .. 
      ( 6.34,7.44) .. controls ( 6.62,7.36) and ( 6.87,7.03) .. 
      ( 7.05,6.71) .. controls ( 7.18,6.38) and ( 7.22,6.20) .. 
      ( 7.25,6.01) .. controls ( 7.27,5.68) and ( 7.26,5.44) .. 
      ( 7.23,5.26) .. controls ( 7.09,4.77) and ( 6.95,4.31) .. 
      ( 6.78,3.95) .. controls ( 6.59,3.52) and ( 6.39,3.14) .. 
      ( 6.20,2.90) .. controls ( 6.01,2.45) and ( 4.04,0.00) .. 
      ( 3.00,-1.00) --                          (12.49,0.00) --
      (12.48,5.75) .. controls (11.81,5.90) and (11.44,6.16) ..
      (10.71,6.44) .. controls (10.34,6.62) and (10.00,6.76) ..
      ( 9.44,7.10) .. controls ( 9.01,7.40) and ( 8.62,7.78) ..
      ( 8.21,8.23) .. controls ( 7.91,8.33) and ( 7.61,8.43) .. cycle;
  \end{scope}
  \coordinate [ rectangle, draw, line width=8pt,
     minimum width=\fW+\pgflinewidth,
     minimum height=\fH+\pgflinewidth];
  \foreach \n in {1,...,24} \node [ /advent/windows/draw=\n ];
\end{tikzpicture}\end{document}

Here is the output with seed=24122015:

merry nightmares!

What's this? What's this? There's color everywhere! What's this? There's white things in the air! What's this? I can't believe my eyes, I must be dreaming; wake up, Jack, this isn't fair! What's this?

I admit the picture suffers from a distinct lack of spiders, snakes and shrunken heads. Maybe next year I'll get around to drawing some delightful surprises to hide behind the windows.

  • 1
    While I like @TomBombadil's answer for its creativity and attention to detail, this is the answer I was actually trying to trigger. So thanks for giving it a try against that really mighty opponent. – Benedikt Bauer Dec 9 '15 at 9:36
  • @BenediktBauer that's nice to hear. Btw, I tried my hand with the Burtonesque take on Christmas. That's by no means finished, but maybe next year... – Paolo Brasolin Dec 9 '15 at 16:42
  • 4
    Boys and girls of every age, wouldn't you like to see something strange? Yay I got the reference! :) – Paulo Cereda Dec 9 '15 at 17:05
40
+100

You can get the latest PDF containing all pages here (about 4.5 MB).

some stats so far:

                Python   Latex 
lines of code      150    7300
compile time     0.22s   1350s

Here's a first very, very basic version. It places rectangles randomly on a rectangular grid, with the 24 being twice as big it makes a nice 5x5 grid. Furthermore, the font size increases with each day.

Generating Python Code

from random import randint, shuffle
from os import system
from sys import argv

__author__ = 'Tom Bombadil'

dates = [x for x in range(24, 0, -1)]
positions = [x for x in range(24, -1, -1)]
shuffle(positions)

if len(argv) >=2:
    cell_size = float(argv[1])
else:
    cell_size = 3

if len(argv) >=3:
    border_size = float(argv[2])
else:
    border_size = 0.2

with open("Christmas.tex", "w") as LaTeX:
    LaTeX.write('\\documentclass[tikz, border=2mm]{standalone}\n')
    LaTeX.write('\\usepackage{kerkis}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{document}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{tikzpicture}\n')
    # LaTeX.write('\n')
    LaTeX.write('\t\\draw (0,0) rectangle (' + str(5*cell_size) + ', ' + str(5*cell_size) + ');\n')
    for date in dates:
        position = positions[randint(0, len(positions)-1)]
        width = cell_size - 2*border_size
        height = cell_size - 2*border_size
        # print(date, position)
        if date == 24:
            if position % 5 == 4:
                position -= 1
            width = 2*cell_size - 2*border_size
            positions.remove(position+1)
        positions.remove(position)
        x = (position % 5)*cell_size+border_size
        y = (position // 5)*cell_size+border_size
        LaTeX.write('\t\\fontsize{' + str(date+13) + '}{' + str(int((date+13)*6/5)) + '}\selectfont\n')
        LaTeX.write('\t\\draw (' + str(x) + ', ' + str(y) + ') rectangle node {' + str(date) + '} ++ (' + str(width)
                    + ', ' + str(height) + ');\n')
    # LaTeX.write('\n')
    LaTeX.write('\\end{tikzpicture}\n')
    LaTeX.write('\n')
    LaTeX.write('\\end{document}')

system('pdflatex Christmas.tex')
system('Christmas.pdf')

Example resulting LaTeX code

\documentclass[tikz, border=2mm]{standalone}
\usepackage{kerkis}

\begin{document}

\begin{tikzpicture}
    \draw (0,0) rectangle (15, 15);
    \fontsize{37}{44}\selectfont
    <22 more days>
    \fontsize{14}{16}\selectfont
    \draw (12.2, 6.2) rectangle node {1} ++ (2.6, 2.6);
\end{tikzpicture}

\end{document}

Example output

enter image description here


Edit 1: Now with a little randomness in the box placement, a few colors, and "snow":

Generating Python Code

from random import randint, shuffle
from os import system
from sys import argv

__author__ = 'Tom Bombadil'

dates = [x for x in range(24, 0, -1)]
positions = [x for x in range(24, -1, -1)]
shuffle(positions)

if len(argv) >= 2:
    cell_size = float(argv[1])
else:
    cell_size = 5

if len(argv) >= 3:
    border_size = float(argv[2])
else:
    border_size = 0.2

with open("Christmas.tex", "w") as LaTeX:
    LaTeX.write('\\documentclass[tikz, border=2mm]{standalone}\n')
    LaTeX.write('\\usepackage{kerkis}\n')
    LaTeX.write('\\usetikzlibrary{shapes.geometric,decorations,decorations.pathmorphing}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{document}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{tikzpicture}[font=\\bf\\sf]\n')
    LaTeX.write('\t\\fill[inner color=blue!40!black, outer color=blue!10!black, clip] (0,0) rectangle (' +
                str(5*cell_size) + ', ' + str(5*cell_size) + ');\n')
    LaTeX.write('\t\\fill[decorate,decoration={random steps,segment length=0.5cm,amplitude=0.3cm}, '
                'bottom color=blue!50!black, top color=cyan!50!blue!50!black] (-1,-1) rectangle (' +
                str(5*cell_size+1) + ', ' + str(2.5*cell_size) + '12);\n')
    for flake in range(300):
        snow_x = round(randint(0, 1000)/1000*5*cell_size, 4)
        snow_y = round(randint(0, 1000)/1000*5*cell_size, 4)
        snow_r = round((randint(0, 18)/20+0.02)*0.1, 4)
        LaTeX.write('\t\\fill[blue!20] (' + str(snow_x) + ', ' + str(snow_y) + ') circle (' + str(snow_r) + ');\n')
    for date in dates:
        position = positions[randint(0, len(positions)-1)]
        width = round((cell_size - 2*border_size)/2, 4)
        height = round((cell_size - 2*border_size)/2, 4)
        # print(date, position)
        if date == 24:
            if position % 5 == 4:
                position -= 1
            width = cell_size - border_size
            positions.remove(position+1)
        positions.remove(position)
        x = round((position % 5)*cell_size+border_size + (randint(0, 100)+25)/300*cell_size, 4)
        y = round((position // 5)*cell_size+border_size + (randint(0, 100)+25)/300*cell_size, 4)
        LaTeX.write('\t\\fontsize{' + str(date+13) + '}{' + str(int((date+13)*6/5)) + '}\selectfont\n')
        LaTeX.write('\t\\fill[white, draw=white, fill opacity=0.18, text opacity=1, dotted] (' + str(x) + ', ' +
                    str(y) + ') rectangle node[circle, fill=white, text=black, fill opacity=0.3, inner sep=3pt] {' +
                    str(date) + '} ++ (' + str(width) + ', ' + str(height) + ');\n')
    LaTeX.write('\\end{tikzpicture}\n')
    LaTeX.write('\n')
    LaTeX.write('\\end{document}')

system('pdflatex Christmas.tex')
system('Christmas.pdf')

Example resulting LaTeX code

\documentclass[tikz, border=2mm]{standalone}
\usepackage{kerkis}
\usetikzlibrary{shapes.geometric,decorations,decorations.pathmorphing}

\begin{document}

\begin{tikzpicture}[font=\bf\sf]
    \fill[inner color=blue!40!black, outer color=blue!10!black, clip] (0,0) rectangle (25, 25);
    \fill[decorate,decoration={random steps,segment length=0.5cm,amplitude=0.3cm}, bottom color=blue!50!black, top color=cyan!50!blue!50!black] (-1,-1) rectangle (26, 12.512);
    \fill[blue!20] (5.6, 10.175) circle (0.032);
    ... <298 more snowflakes>
    \fill[blue!20] (22.775, 4.375) circle (0.092);
    \fontsize{37}{44}\selectfont
    \fill[white, draw=white, fill opacity=0.18, text opacity=1, dotted] (0.9, 20.8333) rectangle node[circle, fill=white, text=black, fill opacity=0.3, inner sep=3pt] {24} ++ (4.8, 2.3);
    ... <22 more calendar days>
    \fontsize{14}{16}\selectfont
    \fill[white, draw=white, fill opacity=0.18, text opacity=1, dotted] (11.0167, 11.05) rectangle node[circle, fill=white, text=black, fill opacity=0.3, inner sep=3pt] {1} ++ (2.3, 2.3);
\end{tikzpicture}

\end{document}

Example output

enter image description here


Update 1st December: There snow flakes now, and behind the first door was a shiny red ball!

Generating Python Code

from random import randint, shuffle
from os import system
from sys import argv

__author__ = 'Tom Bombadil'

dates = [x for x in range(24, 0, -1)]
positions = [x for x in range(24, -1, -1)]
shuffle(positions)

if len(argv) >= 2:
    cell_size = float(argv[1])
else:
    cell_size = 5

if len(argv) >= 3:
    border_size = float(argv[2])
else:
    border_size = 0.2

with open("Christmas.tex", "w") as LaTeX:
    LaTeX.write('\\documentclass[tikz, border=2mm]{standalone}\n')
    LaTeX.write('\\usepackage{kerkis}\n')
    LaTeX.write('\\usetikzlibrary{shapes.geometric,decorations,decorations.pathmorphing, spy}\n')
    # LaTeX.write('\\usepackage{bbding}\n')
    LaTeX.write('\n')
    LaTeX.write('\\newcommand{\\SnowFlake}[4]%\n')
    LaTeX.write('{\t\\draw[rotate=#4, flake, shift={(#1,#2)}]\n')
    LaTeX.write('\t\t(0:#3) -- (180:#3)\n')
    LaTeX.write('\t\t(60:#3) -- (240:#3)\n')
    LaTeX.write('\t\t(120:#3) -- (300:#3)\n')
    LaTeX.write('\t\t\\foreach \\Ray in {0,60,...,300}\n')
    LaTeX.write('\t\t{\t(\\Ray:#3/2) -- ++ (\\Ray+60:#3/3) (\\Ray:#3/2) -- ++ (\\Ray-60:#3/3)')
    LaTeX.write('\t\t};')
    # LaTeX.write('\t\t(0:#3/2) -- ++ (60:#3/3) (0:#3/2) -- ++ (300:#3/3)\n')
    LaTeX.write('}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{document}\n')
    LaTeX.write('\n')
    LaTeX.write('\\begin{tikzpicture}\n')
    LaTeX.write('\t[\tfont=\\bfseries\\sffamily,\n')
    LaTeX.write('\t\tflake/.style={blue!20, ultra thin},\n')
    LaTeX.write('\t\tdaybox/.style={white, draw=white, fill opacity=0.15, text opacity=1, dotted},\n')
    LaTeX.write('\t\tdaynode/.style={circle, fill=white, text=black, fill opacity=0.25, inner sep=3pt},\n')
    LaTeX.write('\t\tspy using outlines={circle, size=10cm, connect spies, magnification=5}')
    LaTeX.write('\t]\n')
    LaTeX.write('\t\\fill[inner color=blue!40!black, outer color=blue!10!black, clip] (0,0) rectangle (' +
                str(5*cell_size) + ', ' + str(5*cell_size) + ');\n')
    LaTeX.write('\t\\fill[decorate, decoration={random steps, segment length=0.5cm, amplitude=0.3cm}, '
                'bottom color=blue!50!black, top color=cyan!50!blue!50!black] (-1,-1) rectangle (' +
                str(5*cell_size+1) + ', ' + str(2.5*cell_size) + '12);\n')
    for flake in range(500):
        snow_x = round(randint(0, 1000)/1000*5*cell_size, 4)
        snow_y = round(randint(0, 1000)/1000*5*cell_size, 4)
        snow_r = round((randint(0, 35)/20+0.05)*0.1, 4)
        # snow_r = 4 + randint(0, 8)
        snow_a = randint(0, 14)
        # LaTeX.write('\t\\fill[flake] (' + str(snow_x) + ', ' + str(snow_y) + ') circle (' + str(snow_r) + ');\n')
        LaTeX.write('\t\\SnowFlake{' + str(snow_x) + '}{' + str(snow_y) + '}{' + str(snow_r) + '}{' + str(snow_a) + '}\n')
    for date in dates:
        position = positions[randint(0, len(positions)-1)]
        width = round((cell_size - 2*border_size)/2, 4)
        height = round((cell_size - 2*border_size)/2, 4)
        # print(date, position)
        if date == 24:
            if position % 5 == 4:
                position -= 1
            width = cell_size - border_size
            positions.remove(position+1)
        positions.remove(position)
        x = round((position % 5)*cell_size+border_size + (randint(0, 100)+25)/300*cell_size, 4)
        y = round((position // 5)*cell_size+border_size + (randint(0, 100)+25)/300*cell_size, 4)
        # LaTeX.write('\t\\fontsize{' + str(date+13) + '}{' + str(int((date+13)*6/5)) + '}\selectfont\n')
        if date > 1:
            LaTeX.write('\t\\fill[daybox] (' + str(x) + ', ' +
                        str(y) + ') rectangle node[daynode] {\\fontsize{' + str(date+13) + '}{' + str(int((date+13)*6/5)) + '}\\selectfont' +
                        str(date) + '} ++ (' + str(width) + ', ' + str(height) + ');\n')
        else:
            LaTeX.write('\t\\fill[gray!25] ('+ str(x) + ', ' + str(y) + ') -- ++ (' + str(width) + ', 0) -- ++ (60:' +
                        str(width/2) + ') -- ++ (0, ' + str(width) + ') -- ++ (240:' + str(width/2) + ') -- ++ (' +
                        str(-width) + ', 0) -- cycle;\n')
            LaTeX.write('\t\\draw[gray!50!black] (' + str(x+width) + ', ' + str(y) + ') -- ++ (0, ' + str(height) + ');\n')
            LaTeX.write('\\path[shading=ball, ball color=red] (' + str(x+width/2) + ', ' + str(y+height/2) +
                        ') circle (' + str(width*0.4) + ');\n')
    # LaTeX.write('\\spy[yellow] on (' + str(cell_size) + ', ' + str(cell_size) + ') in node at (' + str(2*cell_size) + ', ' + str(2*cell_size) + ');\n')
    LaTeX.write('\\end{tikzpicture}\n')
    LaTeX.write('\n')
    LaTeX.write('\\end{document}')

system('pdflatex Christmas.tex')
system('Christmas.pdf')

Example resulting LaTeX code

\documentclass[tikz, border=2mm]{standalone}
\usepackage{kerkis}
\usetikzlibrary{shapes.geometric,decorations,decorations.pathmorphing, spy}

\newcommand{\SnowFlake}[4]%
{   \draw[rotate=#4, flake, shift={(#1,#2)}]
        (0:#3) -- (180:#3)
        (60:#3) -- (240:#3)
        (120:#3) -- (300:#3)
        \foreach \Ray in {0,60,...,300}
        {   (\Ray:#3/2) -- ++ (\Ray+60:#3/3) (\Ray:#3/2) -- ++ (\Ray-60:#3/3)       };}

\begin{document}

\begin{tikzpicture}
    [   font=\bfseries\sffamily,
        flake/.style={blue!20, ultra thin},
        daybox/.style={white, draw=white, fill opacity=0.15, text opacity=1, dotted},
        daynode/.style={circle, fill=white, text=black, fill opacity=0.25, inner sep=3pt},
        spy using outlines={circle, size=10cm, connect spies, magnification=5}  ]
    \fill[inner color=blue!40!black, outer color=blue!10!black, clip] (0,0) rectangle (25, 25);
    \fill[decorate, decoration={random steps, segment length=0.5cm, amplitude=0.3cm}, bottom color=blue!50!black, top color=cyan!50!blue!50!black] (-1,-1) rectangle (26, 12.512);
    \SnowFlake{4.55}{22.15}{0.035}{3}
    ... <498 more snow flakes>
    \SnowFlake{3.9}{9.725}{0.115}{8}
    \fill[daybox] (11.7, 6.9) rectangle node[daynode] {\fontsize{37}{44}\selectfont24} ++ (4.8, 2.3);
    ... <22 more calendar days>
    \fill[daybox] (6.6833, 7.1) rectangle node[daynode] {\fontsize{15}{18}\selectfont2} ++ (2.3, 2.3);
    \fill[gray!25] (12.0833, 20.9667) -- ++ (2.3, 0) -- ++ (60:1.15) -- ++ (0, 2.3) -- ++ (240:1.15) -- ++ (-2.3, 0) -- cycle;
    \draw[gray!50!black] (14.383299999999998, 20.9667) -- ++ (0, 2.3);
\path[shading=ball, ball color=red] (13.2333, 22.1167) circle (0.92);
\end{tikzpicture}

\end{document}

Output 1st December

enter image description here


Update 2nd December: There are stars now, the red ball from yesterday has been magically transformed to a proper bauble, and there's a wrapped gift behind the second door! As this answer will get too long if I post the code every day, I will post only snippets leding up to the 24th and then the whole code. The small pictures drawing mechanism is inspired by "Drawing on an image with TikZ"

enter image description here


Update 3rd December: Today it's a snowman!

enter image description here


Update 4th December: It's a minty candy cane!

enter image description here


Update 5th December: My God, it's full of stars! Also, a farm house has appeared, and a mysterious object in the sky...

enter image description here


Update 6th December: Today it's an advent wreath with, surprise, two burning candles on it.

enter image description here


Update 7th December: Today, it's a gigerbread person!

enter image description here


Update 8th December: Today, it's a mistletoe!

enter image description here


Update 9th December: Have some milk and cookies (with colorful crumbs). Disclaimer: Cookies are virtual. For enjoying real cookies, bake some. Share them. Spread the joy!

enter image description here


Update 10th December: Do you know a famous character from Svalbard?

enter image description here


Update 11th December: Jingle bells, jingle bells, jingle all the way... with a little help from Jake.

enter image description here


Update 12th December: Today it's a nutcracker, mideled after a genuine one from Erzgebirge, Germany.

enter image description here


Update 13th December: Holy cow, is it the 3rd advent sunday already?

enter image description here


Update 14th December: Don't forget your mittens when you go outside! Provided it's cold out, of cause. Otherwise, don't forget your sun screen!

enter image description here


Update 15th December: If you haven't alrady, it's time to finish your wishlist!

enter image description here


Update 16th December: Today in out winter collection: a nice warm red hat!

enter image description here


Update 17th December: Last chance to catch the Geminids today!

enter image description here


Update 18th December: Today it's a Poinsettia. Also, a lot of trees have appeared (although a few issues with those need fixing). Hint: look at the PDF. The snow on the trees increases over time ;-)

enter image description here


Update 19th & 20th December : A festive tree and an advent wreath with 4 candles. Also simpler and beeter looking trees.

enter image description here

  • 3
    What's behind each of the flaps? :-) – Thruston Nov 30 '15 at 19:00
  • 3
    @Thruston; That's a secret until at least tomorrow ;-) – Tom Bombadil Nov 30 '15 at 19:04
  • 2
    @Thruston: Specially for you :-D – Tom Bombadil Dec 1 '15 at 0:03
  • 3
    I like the output of your solution, but python is a little bit of cheating, isn't it? – Benedikt Bauer Dec 1 '15 at 7:21
  • 5
    @BenediktBauer: Depends on your view ;-) While I think that all of it could be done without Python, things like handling lists and conditionals are a pain with LaTeX. So think of this approach as PythonLaTeX, no more cheating than LuaLaTex (probably). – Tom Bombadil Dec 1 '15 at 7:40
15

Here's my response to the challenge. Unfortunately it has a single flaw, which is the lack of collision detection for the nodes, since I have no idea how to do it and the lack of documentation on this topic didn't help (if someone could direct me to that, I'd appreciate it).

However it was quite a lot of work (350 lines of code!), so I'd like to post it anyways, even if just for that reason.

The placement of the days should be random for each compile.

Output

example image

Code

\documentclass{standalone}
\usepackage{tikz}
\usepackage{bbding} 
\usepackage[weather]{ifsym}
\usepackage{pgf}

\author{Alenanno}

\usetikzlibrary{calc,fit,decorations.pathmorphing,shapes,shadings,shapes.geometric}

\definecolor{darkgreen}{RGB}{0,86,23}   
\definecolor{lightbrown}{RGB}{201,154,66}
\definecolor{lightbrownb}{RGB}{201,134,66}
\definecolor{darkbrown}{RGB}{101,67,33}
\definecolor{darkbrownb}{RGB}{43,29,14}
\definecolor{bblue}{RGB}{0,108,217}
\definecolor{dyellow}{RGB}{164,153,149}
\definecolor{lyellow}{RGB}{243,221,197}
\definecolor{dblue}{RGB}{10,11,131}
\definecolor{lblue}{RGB}{10,130,180}

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

\newcommand{\treex}[2][.2]{
\begin{scope}[shift={(#2)},scale=#1]
\filldraw[draw=none,left color=lightbrown, right color=darkbrownb] (1,-12) -- (1,-14.5)
    to[out=-65,in=150] (4.4,-17.2) 
    to[out=175,in=-45] (2,-16.5)
    to[out=-70,in=130] (3,-18)
    to[out=160,in=-35] (.8,-17)
    to[out=210,in=90] (.2,-18)
    to[out=145,in=-90] (-.4,-16.7)
    to[out=200,in=10] (-3,-17.5)
    to[out=20,in=245] (-.7,-15)
    -- (-.7,-12) -- cycle;
\filldraw[darkbrown, opacity=.5] (4.4,-17.2) 
    to[out=175,in=-45] (2,-16.5)
    -- (1,-15.5)
    to[out=-45,in=170] cycle;
\filldraw[darkbrown, opacity=.5] (3,-18)
    to[out=160,in=-35] (.8,-17)
    to[out=210,in=90] (.2,-18)
    to[out=90,in=210] (.6,-16.1) 
    to[out=-30,in=165] cycle;
\filldraw[darkbrown, opacity=.5] (-.4,-16.7)
    to[out=200,in=10] (-3,-17.5)
    to[out=10,in=250] (-.4,-15.5)
    to[out=95,in=90] cycle;
\filldraw[darkgreen] (0,10) 
    to[out=-65,in=145] (6,3)
    to[out=200,in=10] (3.5,2.5)
    to[out=-65,in=145] (9.5,-5)
    to[out=200,in=10] (5,-6)
    to[out=-65,in=145] (11,-11.5)
    to[out=200,in=340] (-11,-11.5)
    to[out=35,in=245] (-5,-6)
    to[out=340,in=170] (-9.5,-5)
    to[out=35,in=245] (-3.5,2.5)
    to[out=340,in=170] (-6,3)
    to[out=35,in=245] cycle;    
\end{scope}
}

\newcommand{\snowflake}[2]{
    \node[font=\fontsize{#2}{70}, text=gray!20] at (#1) {\Snow};%flakeChevron};
}

\newcommand{\nive}[4][1.2]{
    \node[scale=#1*2, text=gray!20] (a) at (#2,#3) {\Snow};
    \node[draw=blue!10, dashed, scale=#1, text=red!70!black, font=\bfseries, fill=white,opacity=.5, text opacity=1,outer sep=0, inner sep=0] at (a) {#4};
}

\tikzset{
    mountain/.style={darkbrownb, fill=darkbrown, ultra thick},
    log/.style={cylinder, draw=darkbrownb, bottom color=darkbrownb, top color=darkbrown, shape aspect=1, minimum width=3mm, minimum height=3.5cm},
    c/.style={yshift=-8mm},
    d/.style={yshift=#1mm},
    ell/.style={ellipse, draw=darkbrown, fill=darkbrown, minimum width=3mm,minimum height=4mm, inner sep=0},
}

\begin{document}
\begin{tikzpicture}
\pgfmathsetseed{\pdfuniformdeviate 10000000}
\useasboundingbox (-7,-5) rectangle (7,5);

% Sky
\fill[top color=blue!40, bottom color=blue!20] (-7,-5) rectangle (7,5);

% Mountains
\draw[mountain] (-7,0) to[out=75,in=210] (-6.6,.4)
    to[out=-15,in=175] (-6.4,.35) %%
    to[out=75,in=250] (-6.1,.8)
    to[out=60,in=180] (-5.6,1.4)
    -- (-5.3,.8)
    to[out=35,in=220] (-4.4,2.5)
    -- (-4.2,2.2)
    to[out=45,in=200] (-3.5,3.1) 
    to[out=-45,in=170] (-2.9,2.6)
    to[out=75,in=250] (-1.9,3.9)
    to[out=-45,in=110] (-.6,2.2) 
    to[out=-70,in=110] (.3,.9)
    to[out=-15,in=90] (1,0)
    -- (1,-4) -- (-7,-4) -- cycle;
\draw[mountain, fill=darkbrownb] (-2.9,2.6)
    to[out=75,in=250] (-1.9,3.8) -- (-1.9,1.5) 
    to[out=195,in=90] (-2.3,.8) -- (-2.7,.8)
    to[out=170,in=-65, looseness=1.5] (-3.1,1.6);
\draw[mountain, fill=darkbrownb] (-6.6,.35) to[out=-90,in=90] (-6.4,-.4)
    to[out=-90,in=90] (-6.7,-2) -- (-6.7,-3) -- (-7,-3) -- (-7,0) to[out=75,in=210] cycle;
\draw[darkbrownb, ultra thick] (-6.4,.35) to[out=-35,in=170] (-5.4,-.4)
    to[out=-45,in=180] (-4.9,-.8);
\draw[darkbrownb, ultra thick] (-6.2,.2) to[out=245,in=90] (-5.9,-.9)
    to[out=-90,in=110] (-5.5,-2.4);
\draw[darkbrownb, ultra thick] (-4.8,-.4) to[out=-65,in=145] (-4.3,-1);
\draw[darkbrownb, ultra thick] (-4.9,.9) to[out=-65,in=175] (-4.3,.2);
\draw[darkbrownb, ultra thick] (-4.2,-.5) to[out=110,in=200] (-4,.6)
    to[out=30,in=245] (-3.4,1.7) -- (-3.1,1.6);

\fill[white, draw=darkbrownb] (-5.6,1.4) [rounded corners] 
    to[out=-60,in=110] (-4.7,-.6) [sharp corners]
    to[out=145,in=-45] (-5.3,0) 
    to[out=-95,in=-120] (-5.7,.8)
    to[out=60,in=200] cycle;

\fill[white, draw=darkbrownb] (-4.4,2.5)
    -- (-4.2,2.2)
    to[out=45,in=200] (-3.5,3.1)
    to[out=-105,in=140] (-3.4,2)
    to[out=-50,in=75] (-3.3,1.7)
    to[out=-105,in=-35, looseness=2] (-3.7,1.6) [rounded corners]
    to[out=200,in=75] (-4,.8) [sharp corners]
    to[out=140,in=-55] (-4.3,1.6) [rounded corners]
    to[out=220,in=55] (-4.7,1) [sharp corners]
    to[out=95,in=-15] (-4.85,1.6)
    to[out=75,in=220] cycle;

\fill[white, draw=darkbrownb] (-1.9,3.9)
    to[out=-45,in=110] (-.6,2.2)
    to[out=-65,in=120] (-.1,1.6)
    to[out=-90,in=-10] (-.4,1.4)
    to[out=-90,in=35] (-.5,.8)
    to[out=-75,in=85] (-.4,.1) 
    to[out=175,in=-65, looseness=.5] (-.9,.9)
    to[out=115,in=115, looseness=6] (-1.2,.8)
    to[out=120,in=-45] (-2,1.4)
    -- (-1.8,1.5)
    to[out=110,in=15] (-2.8,1.5)
    to[out=75,in=210] (-2,3.3)
    to[out=30,in=-100, looseness=.5] cycle;

\fill[darkbrownb] (-1.2,2.6) to[out=-45,in=90] (-.7,1.9) to[out=-90,in=-75] cycle;
\fill[darkbrownb] (-1.4,2.3) 
    to[out=-45,in=90] (-.8,1.4)
    to[out=155,in=75, looseness=2] (-1.4,1.6)
    to[out=165,in=0] (-1.9,2)
    to[out=90,in=180, looseness=.5] (-1.8,2.6)
    to[out=0,in=190] cycle;

\draw[mountain] (7,3) to[out=175,in=-15] (5.5,3.5) 
    -- (5.1,3.2)
    to[out=250,in=0] (4.2,2.3)
    to[out=250,in=35] (3.6,1.5)
    to[out=250,in=45] (3.3,1.1)
    to[out=210,in=0] (1,.5)
    to[out=230,in=15] (0,0)
    to[out=215,in=75] (-2,-2)
    -- (7,-2) -- cycle;
\draw[darkbrownb, ultra thick] (1,.5) to[out=-95,in=45] (0,-1);
\fill[darkbrownb, draw=darkbrown] (5.5,3.5) to[out=-85,in=75] (5.3,1.5)
    to[out=-35,in=125] (6,.5)
    to[out=270,in=65] (5.8,-.5) -- (5,-.8) -- (4.7,-2) -- (2.5,-2) -- (2.5,-1)
    to[out=65,in=-90] (3,-.5)
    to[out=15,in=-90] (4.2,2.3)
    to[out=0,in=250] (5.1,3.2)
    -- cycle;
\draw[darkbrownb, sharp corners, thick] (6,.5) to[out=35,in=195] (6.5,1) 
    to[out=-65,in=120] (6.7,.8)
    to[out=-90,in=110] (6.9,0);
\draw[darkbrownb, ultra thick] (5.5,3.5) to[out=-75,in=135] (6,2.5);

\fill[darkbrownb, draw=darkbrown] (-6.5,-3) 
    to[out=35,in=220] (-2.8,.8)
    to[out=0,in=220] (-2.3,1.2)
    to[out=-35,in=125] (0,-2)
    -- (0,-3) -- cycle;
\draw[mountain] (-2.3,1.2) 
    to[out=-90,in=90] (-2.2,.8)
    to[out=-110,in=120, looseness=1.3] (-1.9,-.7)
    to[out=-110,in=110] (-1.7,-2) -- (0,-2) 
    to[out=125,in=-35] cycle;
\fill[white, draw=darkbrownb] (-3.2,.4) 
    to[out=-120,in=90] (-3.5,-.4)
    to[out=45,in=45, looseness=9] (-3.3,-.5)
    to[out=225,in=15] (-4,-1.1)
    to[out=90,in=15, looseness=2] (-4.6,-1.5)
    to[out=75,in=-45] (-4.3,-.8)
    to[out=45,in=220] cycle;
\fill[white, draw=darkbrownb] (4.2,2.3) to[out=-75,in=45] (4.3,1)
    to[out=-45,in=-15] (4,.5) to[out=-45,in=120] (4.5,0) -- (4.3,0)
    to[out=120,in=-85] (3.5,.6)
    to[out=245,in=-145, looseness=6] (3,.7)
    to[out=35,in=-75] (3.6,1.5)
    to[out=35,in=250] cycle;
\fill[white, draw=darkbrownb] (5.5,3.5) to[out=-95,in=135] (5.8,2.5)
    -- (6,2.5) to[out=-75,in=110] (6.5,1.8)
    to[out=0,in=-90] (6.5,2.3)
    to[out=-45,in=-35, looseness=5] (6.5,2.5)
    to[out=45,in=-20] cycle;

% Front view
\fill[draw=none,left color=white,right color=blue!10,middle color=white] (-7,-3) to[out=15,in=180] (1.5,-1.6) to[out=0,in=196] (7,-1) 
    -- (7,-5) -- (-7,-5) -- cycle;
\draw[blue!10, fill=blue!9] (2,-5) to[out=25,in=0,looseness=2] (1,-2)
    to[out=170,in=180, looseness=2] (1,-1.6) -- (1.1,-1.6)
    to[out=200,in=180, looseness=1.8] (2,-2)
    to[out=0,in=90] (5,-4)
    to[out=-90,in=75] (4.8,-5) -- cycle;

% House
\foreach \numb [count=\xi starting from 1] in {-4.5,-4.2,-3.9,-3.6,-3.2,-2.85,-2.45,-2.06,-1.6,-1.2,-.8,-.4,0}{
    \coordinate (b) at (-6.7,\numb/2);
    \coordinate (c) at (0,\numb/2);
    \ifnum\xi>8
    \begin{scope}
    \path[clip] (-6.8,-1.7) -- (-5.5,-.3) -- (-3.8,-1.9) --cycle;
    \draw[bottom color=darkbrownb, top color=darkbrown, darkbrownb] (-3.8,\numb+.3) -- ($([c]b)+(0,1mm)$) arc (90:250:1mm) -- (-3.8,\numb-.3);
    \end{scope}
    \else
    \ifodd\xi
    \begin{pgfonlayer}{foreground}
        \draw[bottom color=darkbrownb, top color=darkbrown, darkbrownb] (-3.8,\numb+.2) -- ($([c]b)+(0,1mm)$) arc (90:250:1mm) -- (-3.8,\numb-.2);
        \draw[darkbrownb, fill=darkbrown] (-3.8,\numb-.2) arc (270:-90:1.5mm and 2mm);
    \end{pgfonlayer}
        \draw[bottom color=darkbrownb, top color=darkbrown, darkbrownb] (-3.8,\numb+.2) -- ($([c]c)+(0,1mm)$) arc (90:-80:1mm) -- (-3.8,\numb-.2);
    \else
    \begin{pgfonlayer}{foreground}  
        \draw[bottom color=darkbrownb, top color=darkbrown, darkbrownb] (-4.1,\numb+.2) -- ($([c]c)+(0,1mm)$) arc (90:-80:1mm) -- (-4.1,\numb-.2);
        \draw[darkbrownb, fill=darkbrown] (-4.1,\numb-.2) arc (270:-90:1.5mm and 2mm);
    \end{pgfonlayer}
        \draw[bottom color=darkbrownb, top color=darkbrown, darkbrownb] (-3.8,\numb+.2) -- ($([c]b)+(0,1mm)$) arc (90:250:1mm) -- (-3.8,\numb-.2);
    \fi
    \fi
}

\begin{pgfonlayer}{foreground}  
\draw[left color=blue!10, right color=white, rounded corners] (-6.8,-1.7) -- (-5.5,-.3) -- (-3.8,-1.9) -- (.3,-1.7) -- (-1.2,-.1) -- (-5.7,-.1) -- (-6.8,-1.4) -- cycle;
\fill[blue!15, rounded corners] (-3.8,-1.85) -- (-3.8,-1.6) -- (-5.4,-.1) --(-5.7,-.1) -- (-6.8,-1.4) -- (-6.8,-1.7) -- (-5.5,-.3) -- (-3.8,-1.9) -- cycle;

\draw[gray,thick, fill=gray!50] (-5.2,-4.5) -- (-6.4,-3.7) -- (-6.4,-2.5)
    -- (-6,-2) -- (-6,.5) -- (-5.5,.7) -- (-4.9,.7) -- (-4.9,-2.05) -- (-4.6,-2.7) -- (-4.6,-4.3) -- cycle;
\draw[gray,thick]  (-5.2,-4.5) -- (-5.2,-2.8) edge (-4.6,-2.7) -- (-5.5,-2.1) edge (-4.9,-2.05) -- (-5.5,.7);

\filldraw[darkbrownb]  (-1.8,-2.08) -- (-1.8,-3.9) --(-2.4,-4.12)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    arc (-90:90:1mm and 1.41mm)
    -- cycle;

\fill[darkbrown, draw=darkbrownb] (-1.9,-3.9) -- (-1.8,-3.9) 
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.3mm)
    -- (-1.9,-2.1) -- cycle;

\draw[darkbrownb, fill=blue!50!white!90!black] (-.5,-1.98) -- (-.5,-2.85) -- (-1,-2.97)
    arc (-90:90:1mm and 1.2mm)
    arc (-90:90:1mm and 1.2mm)
    arc (-90:90:1mm and 1.2mm)
    arc (-90:90:1mm and 1.2mm)
    -- cycle;

\draw[gray!70, ultra thick] (-.75,-2.91) -- (-.75,-2.03);
\draw[gray!70, ultra thick] (-.5,-2.43) -- (-.92,-2.52);
\fill[darkbrown, draw=darkbrownb] (-.5,-2.85) -- (-.4,-2.85) 
    arc (-90:90:1mm and 1.1mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.1mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.1mm) edge[darkbrownb] ++(-.1,0)
    arc (-90:90:1mm and 1.1mm) 
    -- (-.5,-1.98) -- cycle;
\end{pgfonlayer}

\fill[blue!10] (1.6,-.4) rectangle (1.7,-.3);
\fill[gray!50] (1.65,-.3) to[out=45,in=245, looseness=1.5] (1.6,.5) to[out=230,in=55, looseness=1.5] cycle;
\fill[lyellow] (1,-1) -- (1.4,-.4) -- (1.8,-1) -- (1.8,-1.8) -- (1,-1.8) -- cycle;
\fill[dyellow] (1.8,-1) -- (2.8,-1) -- (2.8,-1.8) -- (1.8,-1.8) -- cycle;
\fill[left color=blue!50,right color=blue!10, rounded corners] (1.4,-.4) -- (1.8,-1.1) -- (2.9,-1.1) -- (2.5,-.4) -- cycle;
\fill[blue!10, rounded corners] (1.4,-.4) -- (.9,-1) -- (1,-1) -- (1.5,-.4) -- cycle;

\fill[blue!30] (1.3,-1) rectangle (1.5,-.8);
\fill[blue!30] (2,-1.6) rectangle (2.6,-1.2);
\fill[darkbrown] (1.3,-1.6) rectangle (1.5,-1.4);

\node[cloud, cloud puffs=15.7, fill=blue!10,
        minimum width=3cm, draw, minimum height=1.24cm] (cloud) at (-4,4) {};

% Trees
\treex[.15]{6.4,-.5}
\treex[.1]{4,-.5}

% Snowman
\fill[outer color=blue!10, inner color=white] (1.5,-3.8) circle (6mm);
\draw[darkbrownb, thick] (1.2,-2.9) --++ (-.6,-.3);
\fill[outer color=blue!10, inner color=white] (1.5,-3) circle (5mm);
\foreach \button in {-2.9,-3,-3.1}{
    \fill[black] (1.4,\button) circle (1.3pt);
}
\draw[darkbrownb, thick] (1.8,-3) --++ (.5,-.5);
\fill[outer color=blue!10, inner color=white] (1.5,-2.3) circle (4mm);

\begin{pgfonlayer}{foreground}
% Snowflakes
\foreach \point in {1,...,400}{
  \pgfmathparse{rand}
  \pgfmathsetmacro\psx{-7*\pgfmathresult}
  \pgfmathparse{rand}
  \pgfmathsetmacro\psy{-5*\pgfmathresult}
  \pgfmathrandom{1,10}
  \let\pointwidth\pgfmathresult

  \node[font=\fontsize{\pointwidth}{70}, text=gray!20] at (\psx,\psy) {\Snow};
}

% Snowdays
\foreach \giorno in {1,2,...,24}{
    \pgfmathparse{rand}
    \pgfmathsetmacro\xpos{5*\pgfmathresult}
    \pgfmathparse{rand}
    \pgfmathsetmacro\ypos{4.5*\pgfmathresult}
    %\pgfmathrandom{0.1,1.75}
    %\let\pointwidth\pgfmathresult

    \ifnum\giorno<24
        \nive{\xpos}{\ypos}{\giorno}
    \else
        \nive[2]{\xpos}{\ypos}{\giorno}
    \fi
}

\end{pgfonlayer}
\end{tikzpicture}
\end{document}

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

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