63

I have been trying to recreate the following image in LaTeX

http://i.imgur.com/Ht9Gaow.jpg

and for me personally it has to be done with pdflatex. Although answers using pst-fractals From Jake I got a good start which led to the following code

\documentclass{standalone}
\usepackage{tikz}
\def\level{5}
\usetikzlibrary{lindenmayersystems}

\begin{document}
\begin{tikzpicture}[l-system={step=5pt, order=\level, angle=120},rotate=180]
    \pgfdeclarelindenmayersystem{Sierpinski triangle}{
    \symbol{X}{\pgflsystemdrawforward}
    \symbol{Y}{\pgflsystemdrawforward}
    \rule{X -> X-Y+X+Y-X}
    \rule{Y -> YY}
    }
    \draw [black] (3,2) l-system
    [l-system={Sierpinski triangle, axiom=X, anchor=north east},fill=white];
\end{tikzpicture}

\end{document}

There are however two problems with the code.

  • I layer a black triangle behind the lindenmayersystem?

  • How do I keep the size of the triangle consistent with different number of recursion levels.

1
  • Is there any formula for this? For instance we give which level we want and it produce the dimensions of the nodes?
    – enthu
    Nov 12, 2014 at 8:51

6 Answers 6

47

The width of the background triangles is 2^order*stepsize, so you can calculate the step size as a function of the desired overall width:

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

\usetikzlibrary{lindenmayersystems}

\begin{document}%
\def\trianglewidth{2cm}%
\pgfdeclarelindenmayersystem{Sierpinski triangle}{
    \symbol{X}{\pgflsystemdrawforward}
    \symbol{Y}{\pgflsystemdrawforward}
    \rule{X -> X-Y+X+Y-X}
    \rule{Y -> YY}
}%
\foreach \level in {0,...,3}{%
\tikzset{
    l-system={step=\trianglewidth/(2^\level), order=\level, angle=-120}
}%
\begin{tikzpicture}
    \fill [black] (0,0) -- ++(0:\trianglewidth) -- ++(120:\trianglewidth) -- cycle;
    \draw [draw=none] (0,0) l-system
    [l-system={Sierpinski triangle, axiom=X},fill=white];
\end{tikzpicture}
}%
\end{document}
2
  • 1
    Very good answer! I will accept it tommorow =) Do you know any way to get rid of the parenthesis around the numbers here? pastebin.com/RBziPbWY Jun 17, 2013 at 21:15
  • 2
    @N3buchadnezzar: You can use \captionsetup[subfigure]{labelformat=simple}
    – Jake
    Jun 17, 2013 at 21:23
40

An alternative way using decorations. It's a bit dependent on how the initial triangle is drawn (i.e., the direction of the path), and the nesting of decorations has to be done manually.

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

% Not sure this follows any proper defition of 
% Sirpinksi triangle. It just works.
\pgfdeclaredecoration{quasi-sirpinski}{do}{%
    \state{do}[width=\pgfdecoratedinputsegmentlength, next state=do]{%
        \pgfpathmoveto{\pgfpointpolar{-60}{\pgfdecoratedinputsegmentlength/2}}%
        \pgfpathlineto{\pgfpointorigin}%
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength/2}{0pt}}%
        \pgfpathclose%
    }
}

\begin{document}

\tikz
    \fill (0,0) -- ++(60:3) -- ++(-60:3) -- cycle;

\tikz[decoration=quasi-sirpinski]
    \fill decorate { (0,0) -- ++(60:3) -- ++(-60:3) -- cycle };

\tikz[decoration=quasi-sirpinski]
    \fill decorate { decorate { 
        (0,0) -- ++(60:3) -- ++(-60:3) -- cycle } };

\tikz[decoration=quasi-sirpinski]
    \fill decorate { decorate { decorate { 
        (0,0) -- ++(60:3) -- ++(-60:3) -- cycle } } };

\tikz[decoration=quasi-sirpinski]
    \fill decorate { decorate { decorate {  decorate {
        (0,0) -- ++(60:3) -- ++(-60:3) -- cycle } } } };

\end{document}

enter image description here

1
  • +1 This is awesome. I didn't know that you could nest decorations!
    – user30471
    Nov 17, 2017 at 22:02
34
\documentclass[pstricks]{standalone}
\usepackage{pst-fractal}
\begin{document}

\multido{\iA=1+1}{5}{%
 \begin{pspicture}(3,2.8)
 \psSier[linecolor=blue!70,fillcolor=red!40](0,0){3cm}{\iA}
 \end{pspicture}}

 \multido{\iA=1+1}{5}{%
   \begin{pspicture}(3,2.7)\psSier(0,0){3cm}{\iA}
\end{pspicture}}


\end{document}

enter image description here

enter image description here

2
  • 10
    I think the color hurts ... ;-)
    – Mensch
    Jun 17, 2013 at 20:07
  • 3
    And pstricks rocks ;).
    – user11232
    Jun 17, 2013 at 23:31
23

Just for the looping fun of it; every section is one level... you can even automate the levels etc. but it's a little xii.tex way of doing it since it then becomes a lindenmayer system :)

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}[
main tri/.style={isosceles triangle,fill,isosceles triangle apex angle=60,
                 rotate=90,inner sep=0,outer sep=0},
filler tri/.style={isosceles triangle,fill=white,rotate=-90,isosceles triangle apex angle=60,
                 inner sep=0,outer sep=0}]
\node[minimum height=2cm,main tri] (a) {};
%==================
\node[minimum height=1cm,filler tri] (b) at (a.center){};
%==================
\node[minimum height=0.5cm,filler tri,anchor=right corner] (c1) at (b.left side){};
\node[minimum height=0.5cm,filler tri,anchor=left corner] (c2) at (b.right side){};
\node[minimum height=0.5cm,filler tri,anchor=apex] (c3) at (b.west){};
% ===================
\foreach \x in {1,2,3}{
\node[minimum height=0.25cm,filler tri,anchor=right corner] (d1\x) at (c\x.left side){};
\node[minimum height=0.25cm,filler tri,anchor=left corner] (d2\x) at (c\x.right side){};
\node[minimum height=0.25cm,filler tri,anchor=apex] (d3\x) at (c\x.west){};
}
% ===================
\foreach \x in {1,2,3}{
    \foreach \y in {1,2,3}{
    \node[minimum height=0.125cm,filler tri,anchor=right corner] (e1\x\y) at (d\x\y.left side){};
    \node[minimum height=0.125cm,filler tri,anchor=left corner] (e2\x\y) at (d\x\y.right side){};
    \node[minimum height=0.125cm,filler tri,anchor=apex] (e3\x\y) at (d\x\y.west){};
    }
}

\end{tikzpicture}
\end{document}

enter image description here

11

I've just stumbled upon this problem, because it was linked to another I don't remember. Despite coming years too late, I couldn't resist to produce something with MetaPost. No particular package is loaded, it is just plain MetaPost code embedded into a LuaLaTeX program.

The main macro is simply called Sierpinsky. It takes the triangle's summits and the wished number of recursions as arguments, fills the triangle and proceeds with the required recursion.

Edit the algorithm has been improved. Now Sierpinski does not fill anything but only unfills the central subtriangle and calls itself on the other subtriangles. This at the cost of the creation of another macro, Sierpinski_triangle, which fills the first triangle and then calls Sierpinski upon it.

\documentclass[border=2mm, multi=mplibcode]{standalone}
\usepackage{luamplib}
  \everymplib{
    vardef Sierpinski(expr A, B, C, n) = % The recursive macro, à la MetaPost
      if n>0: 
        save midAC, midBC, midAB; pair midAC, midBC, midAB;
        midAC = .5[A, C]; midBC = .5[B, C]; midAB = .5[A, B]; % The midpoints
        unfill midAC -- midBC -- midAB -- cycle;
        Sierpinski(A, midAB, midAC, n-1); 
        Sierpinski(midAC, midBC, C, n-1); 
        Sierpinski(midAB, B, midBC, n-1);
      fi
    enddef;
    def Sierpinski_triangle(expr A, B, C, n) =
      fill A--B--C--cycle; Sierpinski(A, B, C, n);
    enddef;
    beginfig(1);}
  \everyendmplib{endfig;}
\begin{document}
  \begin{mplibcode}
    u = 3cm; % Size of the main triangle
    pair v; v = 1.1u*right; % translation vector
    for i = 0 upto 4:
      draw image(Sierpinski_triangle(origin, (u,0), u*dir 60, i)) shifted (i*v);
    endfor
  \end{mplibcode}
  \begin{mplibcode}
    u = 14cm;
    Sierpinski_triangle(origin, (u,0), u*dir 60, 8); % Eight levels of recursion
  \end{mplibcode}
\end{document}

enter image description here

enter image description here

4

With groups and counters.

The output

with \def\topDepth{8}

enter image description here

The code

\documentclass[tikz]{standalone}

\count5=0 % current iteration depth
\count6=1 % previous size
\count7=0 % current x
\count8=0 % current y

\def\tri
{
  \ifnum\count5=\topDepth
    \draw 
      (\the\numexpr\count7+2\relax,\the\count8) -| 
      (\the\count7,\the\numexpr\count8+2\relax) -- 
      cycle;
  \else
    \begingroup
      \advance\count5 by 1
      \multiply\count6 by 2
      %
        \tri
      %
      \begingroup
        \advance\count7 by\count6
        \tri
      \endgroup
      %
      \begingroup
        \advance\count8 by\count6
        \tri
      \endgroup
    \endgroup
  \fi
}

\pgfmathsetmacro{\mySqrt}{sqrt(.75)}

\begin{document}

\def\topDepth{5}

\begin{tikzpicture}[scale=15*.5^\topDepth,cm={1,0,.5,\mySqrt,(0,0)}]
  \tri
\end{tikzpicture}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .