Best way to draw matchstick pictures

I want to draw various matchstick pictures like this:

or like this

• How do I get the path decoration with the matchsticks?
• What's the (syntactically) easiest way to draw pictures like this or how would a tikz expert do this (to be flexible enough to draw such kind of figures but to have an easy syntax)?
-

Here's an alternative way using decorations. Match sticks are drawn on each input segment, so multiple matches can be drawn with one path. The decoration definition is a bit messy but unavoidably so in order to get the shadow opacity right.

EDITS 1 & 2: The decoration definition has been changed to make things a bit cleaner/customisable:

\documentclass[tikz,border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

\pgfdeclaredecoration{match stick}{draw}{
\state{draw}[width=\pgfdecoratedinputsegmentlength]{
\tikzset{x=\pgfdecoratedinputsegmentlength/10, y=\pgfdecorationsegmentamplitude/2}
\path [fill=match shadow, match stick path/.try];
\end{scope}
\path [match stick/.try, match stick path/.try];
}
}

\tikzset{
match/.style={
decoration={match stick, amplitude=2pt}, decorate
},
% The match stick is scaled so that
% 1 x-unit = \pgfdecoratedinputsegmentlength/10
% 1 y-unit = \pgfdecorationsegmentamplitude/2
match stick path/.style={
insert path={(1.375,-1) rectangle (8.375,1)}
},
},
transform canvas={shift=(330:1pt)},
opacity=0.5,
},
match stick/.style={
fill=yellow
},
fill=red
}
}
\begin{document}
\tikz\path [match]
% tail
(135:1) -- (0,0)
% body
(0,0) -- (1,0) -- (2,0) -- (2,-1) --
(1,-1) -- (0,-1)
(0,0) -- (0,-1)
% back legs
(0,-1) -- ++(250:1) (0,-1) -- ++(290:1)
% front legs
(2,-1) -- ++(250:1) (2,-1) -- ++(290:1)
% nose
(2,0)  -- ++(340:1)
(2,-1) -- ++(45:1);

\tikz\foreach \p in {(0:0),(60:1),(60:2), (0:1),(0:2), (30:sqrt 3)}
\path [match, shift={\p}] (0,0) -- (60:1) -- (0:1) (0,0) -- (0:1);

\end{document}


-

EDIT At the end there is a better solution for the shadows problem.

Here is an idea which combines several hacks.

1. For the match shape, use the cylinder node shape, with yellow body and red top. A drop shadow should be nice too, but for some reason it makes the cylinder to appear translucent...

2. You can make that node shape to be used as a straight line in a path, if you draw the node midway, sloped, and give it as minimum height the distance among the two ends of the intended path. In fact, you can give only a 80% of that distance, to create a gap at the ends (kind of shorten > and shorten <)

3. I think that the easiest way to specify the coordinates of a match is to give the cartesian coordinates of the beginning of the match, and then the polar coordinates of the other end with respect to its beginning. That is, for example: \match{3,2}{60:3} represents a match which starts at (3,2), and points in an angle of 60 and has a length of 3. This ensures that all matches are drawn with the same length, even if they are not perpendicular or in a grid.

I combined these ideas in the following code:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\tikzset{
match/.style = {
cylinder,
shape aspect = 1.5,
cylinder uses custom fill,
cylinder body fill=yellow,
cylinder end fill = red,
inner sep = 0pt,
minimum width = 2mm,
draw = black!20!yellow,
sloped, midway,
}
}

\def\match#1#2{
\path let
\p1=(#2),
\n1={0.8*veclen(\p1)}
in (#1) -- +(#2)
node[match,minimum height=\n1] {\phantom{x}}; % phantom is required, without it the end of the cylinder is not drawn (?)
}

\begin{tikzpicture}
\foreach \a in {0,30,...,359} {
\match{0,0}{\a:3}
}
\begin{scope}[xshift=4cm,yshift=-3cm]
\foreach \i in {0,3,...,9} {
\foreach \j in {0,3} {
\match{\i,\j}{0:3}
\match{\i,\j}{90:3}
}
}
\foreach \i in {0,3,...,9} {
\match{\i,6}{0:3}
}
\end{scope}
\end{tikzpicture}
\end{document}


Another example :-)

\begin{tikzpicture}
\foreach \a in {0,135,270} { \match{0,3}{\a:3} }
\foreach \a in {0,-60,-120} { \match{0,0}{\a:3} }
\foreach \a in {180,210,270} { \match{6,3}{\a:3} }
\foreach \a in {150,180,-60,-120} { \match{6,0}{\a:3} }
\end{tikzpicture}


And this is the result if you remove the drop shadow from match style:

In this question I learned a trick (credit to Andrew Stacey) to make the shadow to appear properly behind the matches. This is the final code, with a new example:

\documentclass{article}
\usepackage[margin=5mm,a4paper]{geometry}
\usepackage{tikz}

\pgfdeclarelayer{back}
\pgfsetlayers{back,main}

\makeatletter
\pgfkeys{%
/tikz/on layer/.code={
\pgfonlayer{#1}\begingroup
\aftergroup\endpgfonlayer
\aftergroup\endgroup
},
/tikz/node on layer/.code={
\pgfonlayer{#1}\begingroup
\expandafter\def\expandafter\tikz@node@finish\expandafter{\expandafter\endgroup\expandafter\endpgfonlayer\tikz@node@finish}%
},
}
\makeatother

\tikzset{
match/.style = {
cylinder,
shape aspect = 1.5,
cylinder uses custom fill,
cylinder body fill=yellow,
cylinder end fill = red,
inner sep = 0pt,
minimum width = 2mm,
draw = black!20!yellow,
sloped, midway,
}
}
\def\match#1#2{
\path let
\p1=(#2),
\n1={0.8*veclen(\p1)}
in (#1) -- +(#2)
node[match,minimum height=\n1] {\phantom{x}};
}

\begin{document}
\begin{tikzpicture}
\foreach \a in {0,60,...,359} { \match{0,0}{\a:3}; \match{\a:3}{\a+120:3} }
\foreach \a in {0,120,...,359} { \match{\a:3}{\a-60:3} }
\foreach \a in {60,180,...,359} { \match{\a:3}{\a+60:3} }
\end{tikzpicture}
\end{document}


Result:

Sorry! I cannot stop tweaking! If you introduce a little random rotation in the match definition:

\def\match#1#2{
\path let
\p1=(#2),
\n1={0.8*veclen(\p1)}
in (#1) -- +(#2)
node[rotate=-5+10*rnd, match, minimum height=\n1] {\phantom{x}};
}


You get more interesting (IMHO) results:

-

With PSTricks. Just 4 fun!

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\def\ms(#1)#2{%
\rput{#2}(#1){%
\psline[linewidth=6pt,linecolor=brown](3,0)
\psellipse*[linecolor=red](3,0)(6pt,4pt)}
\ignorespaces
}

\SpecialCoor
\begin{document}
\multido{\i=0+30}{12}{%
\begin{pspicture}(-4,-4)(4,4)
\ms(1;\i){\i}
\end{pspicture}}
\end{document}


-

A solution using PSTricks:

\documentclass{article}

\usepackage[
figureposition = bottom
]{caption}
\usepackage{
pstricks,
multido
}

\psset{
dimen = middel,
fillstyle = solid
}
\def\stickHori(#1,#2){%
\rput[lb](#1,#2){%
\begin{pspicture}(1.8,0.15)
\psline[linecolor = black!50, linewidth = 2\pslinewidth](0.2,0)(1.8,0)(1.8,0.15)
\psframe[linestyle = none, fillcolor = yellow!70](0.2,0)(1.65,0.15)
\psframe[linestyle = none, fillcolor = red!70](1.65,0)(1.8,0.15)
\end{pspicture}%
}%
}
\def\stickVert(#1,#2){%
\rput[lb](#1,#2){%
\begin{pspicture}(0.15,1.8)
\psline[linecolor = black!50, linewidth = 2\pslinewidth](0,0.2)(0.15,0.2)(0.15,1.8)
\psframe[linestyle = none, fillcolor = yellow!70](0,0.35)(0.15,1.8)
\psframe[linestyle = none, fillcolor = red!70](0,0.2)(0.15,0.35)
\end{pspicture}%
}%
}

\begin{document}

\begin{figure}[htbp]
\centering
\begin{pspicture}(11.25,2)
\multido{\rA = 0+1.85}{6}{%
\stickHori(\rA,0)
\stickHori(\rA,1.85)}
\multido{\rB = 0+1.85}{7}{%
\stickVert(\rB,0)}
\end{pspicture}
\caption{Stick figure.}
\label{fig:1}
\end{figure}

\end{document}


Here are the different digital digits (with optional parameters):

\documentclass{article}

\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

\newcommand*\SpaceTotal{\calc{\Width+\Space}}
\newcommand*\LengthTotal{\calc{\Length+\Width}}
\newcommand*\Bottom{\SpaceTotal}
\newcommand*\Middel{\calc{\LengthTotal+\SpaceTotal+\Space}}
\newcommand*\Top{\calc{\HeightTotal-\Width}}
\newcommand*\Lower{\SpaceTotal}
\newcommand*\Upper{\calc{\LengthTotal+2*\SpaceTotal+\Space}}
\newcommand*\Left{\SpaceTotal}
\newcommand*\Right{\calc{\LengthTotal+\SpaceTotal+\Space}}
\newcommand*\WidthTotal{\calc{\LengthTotal+2*\SpaceTotal}}
\newcommand*\HeightTotal{\calc{2*\LengthTotal+3*\SpaceTotal+\Space}}

\usepackage{pstricks}

\psset{
dimen = middel,
fillstyle = solid
}

\def\stickHori(#1,#2){%
\rput[lb](#1,#2){%
\begin{pspicture}(\LengthTotal,\Width)
\psline[linecolor = black!50, linewidth = 2\pslinewidth]%
(0,0)(\LengthTotal,0)(\LengthTotal,\Width)
\psframe[linestyle = none, fillcolor = yellow!70]%
(0,0)(\Length,\Width)
\psframe[linestyle = none, fillcolor = red!70]%
(\Length,0)(\LengthTotal,\Width)
\end{pspicture}%
}%
}
\def\stickVert(#1,#2){%
\rput[lb](#1,#2){%
\begin{pspicture}(\Width,\LengthTotal)
\psline[linecolor = black!50, linewidth = 2\pslinewidth]%
(0,0)(\Width,0)(\Width,\LengthTotal)
\psframe[linestyle = none, fillcolor = yellow!70]%
(0,\Width)(\Width,\LengthTotal)
\psframe[linestyle = none, fillcolor = red!70]%
(0,0)(\Width,\Width)
\end{pspicture}%
}%
}

\newcommand*\digitZero{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Lower)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitOne{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickVert(\Right,\Bottom)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitTwo{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitThree{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(\Right,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitFour{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,\Middel)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitFive{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\end{pspicture}%
}
\newcommand*\digitSix{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Lower)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\end{pspicture}%
}
\newcommand*\digitSeven{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,\Top)
\stickVert(\Right,\Bottom)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitEight{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Lower)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}
\newcommand*\digitNine{%
\begin{pspicture}(\WidthTotal,\HeightTotal)
\stickHori(\SpaceTotal,0)
\stickHori(\SpaceTotal,\Middel)
\stickHori(\SpaceTotal,\Top)
\stickVert(0,\Upper)
\stickVert(\Right,\Lower)
\stickVert(\Right,\Upper)
\end{pspicture}%
}

% parameters
\def\Length{1.3}
\def\Width{0.15}
\def\Space{0.05}

\begin{document}

\begin{center}
\digitZero
\end{center}
\begin{center}
\digitFive
\end{center}

\end{document}


-

With new (TikZ 3.0) arrows.meta library it's easy to draw matches. You can create a special arrow tip or just adjust provided Ellipse one. This way you don't need to use decorations at all. Unfortunately you won't have shadows.

Just a little example:

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}

\begin{document}
\begin{tikzpicture}[
match/.style={line width=3pt,
yellow,
-{Ellipse[red, length=6pt, width'=0pt .5]},
shorten <=3pt,
shorten >=3pt},
every path/.style=match]
\foreach \i [remember=\i as \lasti (initially {(135:2)})] in
{(0,0),(2,0),(4,0),(4,-2),(2,-2),(0,-2),(0,0)}
\draw \lasti--\i;
\draw (0,-2) -- ++(250:2);
\draw (0,-2) -- ++(290:2);
\draw (4,-2) -- ++(250:2);
\draw (4,-2) -- ++(290:2);
\draw[-{Ellipse[blue, length=4pt, width=4pt]}] (4,0)  -- ++(340:2);
\draw (4,-2) -- ++(45:2);
\end{tikzpicture}
\end{document}


-