Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

How can I auto-generate a Penrose tiling by TikZ? Here's my code for Mathematica:

GG = (Sqrt[5]+1)/2;
standardthin = {1/2+Sqrt[GG^2-(1/2)^2] I , 0, 1};
standardthick = {GG/2+Sqrt[1-(GG/2)^2] I, 0, GG};
sectthin[n_, t_] := 
         If[n > 0, 
             Join[sectthin[n-2, {t[[2]], t[[3]], (GG*t[[3]]+t[[1]])/(GG+1)}], 
                  sectthick[n-1, {(GG*t[[3]]+t[[1]])/(GG+1), t[[1]], t[[2]]}]],
                  {thin @@ N[t]}];
sectthick[n_, t_] := 
        If[n > 0, 
            Join[sectthick[n-2, {(GG*t[[2]]+t[[3]])/(GoldenRatio+1),t[[1]],t[[2]]}], 
                 sectthin[n-1, {t[[3]], (GG*t[[2]]+t[[3]])/(GG+1), t[[1]]}]],
                 {thick @@ N[t]}];
addtothick[n_, t_, d_] := 
        If[d == 0, {}, 
        Join[{frame @@ t}, 
           If[EvenQ[d], 
              Join[addtothick[n+2, {t[[2]], t[[3]], ((GG+1)*t[[1]]-GG*t[[3]])},d/2], 
                   sectthin[n+1, {((GG+1)*t[[1]]-GG*t[[3]]), t[[1]], t[[2]]}]], 
              Join[addtothin[n+1, {t[[2]], t[[3]], ((GG+1)*t[[1]]-t[[2]])/GG}, (d-1)/2], 
                   sectthin[n-1, {t[[3]], ((GG+1)*t[[1]]-t[[2]])/GG, t[[1]]}]]]]];

addtothin[n_, t_, d_] := 
        If[d == 0, {}, 
        Join[{frame @@ t}, 
          If[EvenQ[d], 
             Join[addtothin[n+2, {((GG+1)*t[[3]]-GG*t[[2]]), t[[1]], t[[2]]}, d/2], 
                  sectthick[n+1, {t[[3]], ((GG+1)*t[[3]]-GG*t[[2]]), t[[1]]}]], 
             Join[addtothick[n+1, {t[[3]], ((GG+1)*t[[2]]-t[[1]])/GG, t[[1]]}, (d -1)/2], 
                  sectthick[n-1, {t[[2]], t[[3]], ((GG+1)*t[[2]]-t[[1]])/GG}]]]]];

triangle[a_, b_, c_] := Graphics[Line[{Re[#], Im[#]} & /@ {a, b, c, a}]];
        thin := triangle;
        thick := triangle;

frame[a_, b_, c_] := Graphics[{Thickness[0.005], Line[{Re[#], Im[#]} & /@ {a, b, c, a}]}]

Show[addtothin[0, standardthin, 200], AspectRatio -> Automatic]

which creates something like this

share|improve this question
    
Can you provide the atoms that you want to use in the generation? –  percusse Jun 27 '12 at 16:11
3  
Short answer: by implementing the construction algorithm. ;-) -- While this is an interesting topic (I'd like to see a real answer myself) I think you can improve your question by elaborating a bit. For example: What are your efforts so far? Which penrose tiling (P1, P2 or P3) do you want? –  Fritz Jun 27 '12 at 16:12
5  
PSTricks can do that ... –  Herbert Jun 27 '12 at 16:21
    
@Fritz: I have a code I wrote in Mathematica, which does P2 :p Does it help posting the code here? –  Yuji Jun 27 '12 at 16:48
    
@Herbert Can you please undelete your answer to my recent question? I like the code; it leaves something mathematical to think about. –  kan Jun 27 '12 at 17:16
show 1 more comment

4 Answers

up vote 51 down vote accepted

Third edit: a faster and more customizable variation!

Features of this version:

  • builds Penrose tilings with Robinson's triangles (semikites and semidarts) or kite and dart.
  • uses TikZ styles to specify filling and drawing.
  • uses TikZ styles to design shapes of each pieces.
  • provides TikZ styles to use Penrose tilings as pattern.

My (long) code is divided in several parts.

Here's the longest part (preamble, some default styles and the macros to build and to draw/fill tilings by recursion):

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

% phi = golden ratio = (1+sqrt(5))/2
% invphi = 1/phi
% n: number of decompositions left to do
% ver: starting vertex
% angle: direction of first edge
% len: lenght of first edge
% rot: sense of rotation (0 => anticlockwise, 1 => clockwise)

\pgfmathsetmacro{\invphi}{2/(1+sqrt(5))}

% default styles
\tikzset{
  % borders style
  penrose line/.style={draw=black,line join=round},
  % semikites and semidarts styles
  penrose clockwise semikite/.style={penrose line},
  penrose anticlockwise semikite/.style={penrose line},
  penrose clockwise semidart/.style={penrose line},
  penrose anticlockwise semidart/.style={penrose line},
  % kites and darts styles
  penrose kite/.style={penrose line},
  penrose dart/.style={penrose line},
  % the three paths (and the three corresponding reverse paths)
  penrose common/.style={},
  penrose path 1/.style={penrose common},
  penrose path 2/.style={penrose common},
  penrose path 3/.style={penrose common},
  penrose rev path 1/.style={penrose common},
  penrose rev path 2/.style={penrose common},
  penrose rev path 3/.style={penrose common},
}

\newcommand\penrosedrawclockwisesemikite[3]{% ver, angle, len
  % semikite (clockwise)
  \path (#1) +(#2:#3) coordinate (#1-b) +(#2-36:#3) coordinate (#1-c);
  \path[penrose anticlockwise semikite] (#1)
  to[penrose path 1] (#1-b)
  to[penrose path 2] (#1-c)
  to[penrose path 3] (#1);
}

\newcommand\penrosedrawanticlockwisesemikite[3]{% ver, angle, len
  % semikite (anticlockwise)
  \path (#1) +(#2:#3) coordinate (#1-b) +(#2+36:#3) coordinate (#1-c);
  \path[penrose clockwise semikite] (#1)
  to[penrose path 1] (#1-b)
  to[penrose path 2] (#1-c)
  to[penrose path 3] (#1);
}

\newcommand\penrosesemikite[5]{% n, ver, angle, len, rot
  \ifnum#1=0 % draw or recursive decomposition ?
  \ifnum#5=1 % anticlockwise or clockwise ?
  \penrosedrawclockwisesemikite{#2}{#3}{#4}
  \else
  \penrosedrawanticlockwisesemikite{#2}{#3}{#4}
  \fi
  \else
  {
    % decomposition (semikite => 2 semikites and 1 semidart)
    \edef\dep{#1}
    \edef\ver{#2}
    \edef\angle{#3}
    \edef\len{#4}
    \edef\rot{#5}
    \pgfmathtruncatemacro{\n}{\dep-1}
    \edef\namex{\ver\n}
    \pgfmathsetlengthmacro{\newlen}{\len*\invphi}
    \ifnum#5=1 % anticlockwise or clockwise ?
    \path (\ver) ++(\angle-36:\len) coordinate (\namex);
    \pgfmathtruncatemacro{\newanglea}{mod(\angle+108,360)}
    \penrosesemikite{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosesemikite{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosesemidart{\n}{\ver}{\angle}{\newlen}{1}
    \else
    \path (\ver) ++(\angle+36:\len) coordinate (\namex);
    \pgfmathtruncatemacro{\newanglea}{mod(\angle-108,360)}
    \penrosesemikite{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosesemikite{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosesemidart{\n}{\ver}{\angle}{\newlen}{0}
    \fi
  }
  \fi
}

\newcommand\penrosedrawkite[3]{% ver, angle, len
  % kite (current clockwise semikite + opposite anticlockwise semikite)
  \path (#1)
  +(#2+36:#3) coordinate (#1-b)
  +(#2:#3)    coordinate (#1-c)
  +(#2-36:#3) coordinate (#1-d);
  \path[penrose kite] (#1)
  to[penrose path 1] (#1-b)
  to[penrose rev path 2] (#1-c)
  to[penrose path 2] (#1-d)
  to[penrose rev path 1] (#1);
}

\newcommand\penrosekite[5]{% n, ver, angle, len, rot
  \ifnum#1=0 % draw or recursive decomposition ?
  \ifnum#5=1 % draw kite if current semikite is clockwise
  \penrosedrawkite{#2}{#3}{#4}
  \fi
  \else
  {
    % decomposition (semikite => 2 semikites and 1 semidart)
    \edef\dep{#1}
    \edef\ver{#2}
    \edef\angle{#3}
    \edef\len{#4}
    \edef\rot{#5}
    \pgfmathtruncatemacro{\n}{\dep-1}
    \edef\namex{\ver\n}
    \pgfmathsetlengthmacro{\newlen}{\len*\invphi}
    \ifnum#5=1 % anticlockwise or clockwise ?
    \path (\ver) ++(\angle-36:\len) coordinate (\namex);
    \pgfmathtruncatemacro{\newanglea}{mod(\angle+108,360)}
    \penrosekite{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosekite{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosedart{\n}{\ver}{\angle}{\newlen}{1}
    \else
    \path (\ver) ++(\angle+36:\len) coordinate (\namex);
    \pgfmathtruncatemacro{\newanglea}{mod(\angle-108,360)}
    \penrosekite{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosekite{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosedart{\n}{\ver}{\angle}{\newlen}{0}
    \fi
  }
  \fi
}

\newcommand\penrosedrawclockwisesemidart[3]{
  % semidart (clockwise)
  \path (#1)
  +(#2:#3)            coordinate (#1-b)
  +(#2-36:#3*\invphi) coordinate (#1-c);
  \path[penrose anticlockwise semidart] (#1)
  to[penrose path 3] (#1-b)
  to[penrose path 2] (#1-c)
  to[penrose path 1] (#1);
}

\newcommand\penrosedrawanticlockwisesemidart[3]{
  % semidart (anticlockwise)
 \path (#1)
  +(#2:#3)            coordinate (#1-b)
  +(#2+36:#3*\invphi) coordinate (#1-c);
  \path[penrose clockwise semidart] (#1)
  to[penrose path 3] (#1-b)
  to[penrose path 2] (#1-c)
  to[penrose path 1] (#1);
 }

\newcommand\penrosesemidart[5]{% n, ver, angle, len, rot
  \ifnum#1=0 % draw or recursive decomposition ?
  \ifnum#5=1 % anticlockwise or clockwise ?
  \penrosedrawclockwisesemidart{#2}{#3}{#4}
  \else
  \penrosedrawanticlockwisesemidart{#2}{#3}{#4}
  \fi
  \else
  {
    % decomposition (semidart => 1 semikite and 1 semidart)
    \edef\dep{#1}
    \edef\ver{#2}
    \edef\angle{#3}
    \edef\len{#4}
    \edef\rot{#5}
    \pgfmathtruncatemacro{\n}{\dep-1}
    \edef\namex{\ver\n}
    \pgfmathsetlengthmacro{\newlen}{\len*\invphi}
    \path (\ver) ++(\angle:\len) coordinate (\namex);
    \ifnum#5=1 % anticlockwise or clockwise
    \pgfmathsetmacro{\newanglea}{mod(\angle-144,360)}
    \pgfmathsetmacro{\newangleb}{mod(\angle-36,360)}
    \penrosesemidart{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosesemikite{\n}{\ver}{\newangleb}{\newlen}{0}
    \else
    \pgfmathtruncatemacro{\newanglea}{mod(\angle+144,360)}
    \pgfmathtruncatemacro{\newangleb}{mod(\angle+36,360)}
    \penrosesemidart{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosesemikite{\n}{\ver}{\newangleb}{\newlen}{1}
    \fi
  }
  \fi
}

\newcommand\penrosedrawdart[3]{
  % dart (current clockwise semidart + opposite anticlockwise semidart)
  \path (#1)
  +(#2:#3)            coordinate (#1-b)
  +(#2-36:#3*\invphi) coordinate (#1-c)
  +(#2-72:#3)         coordinate (#1-d);
  \path[penrose dart] (#1)
  to[penrose path 3] (#1-b)
  to[penrose path 2] (#1-c)
  to[penrose rev path 2] (#1-d)
  to[penrose rev path 3] (#1);
}

\newcommand\penrosedart[5]{% n, ver, angle, len, rot
  \ifnum#1=0 % draw or recursive decomposition ?
  \ifnum#5=1 % draw dart if current semidart is clockwise
  \penrosedrawdart{#2}{#3}{#4}
  \fi
  \else
  {
    % decomposition (semidart => 1 semikite and 1 semidart)
    \edef\dep{#1}
    \edef\ver{#2}
    \edef\angle{#3}
    \edef\len{#4}
    \edef\rot{#5}
    \pgfmathtruncatemacro{\n}{\dep-1}
    \edef\namex{\ver\n}
    \pgfmathsetlengthmacro{\newlen}{\len*\invphi}
    \path (\ver) ++(\angle:\len) coordinate (\namex);
    \ifnum#5=1 % anticlockwise or clockwise
    \pgfmathsetmacro{\newanglea}{mod(\angle-144,360)}
    \pgfmathsetmacro{\newangleb}{mod(\angle-36,360)}
    \penrosedart{\n}{\namex}{\newanglea}{\newlen}{1}
    \penrosekite{\n}{\ver}{\newangleb}{\newlen}{0}
    \else
    \pgfmathtruncatemacro{\newanglea}{mod(\angle+144,360)}
    \pgfmathtruncatemacro{\newangleb}{mod(\angle+36,360)}
    \penrosedart{\n}{\namex}{\newanglea}{\newlen}{0}
    \penrosekite{\n}{\ver}{\newangleb}{\newlen}{1}
    \fi
  }
  \fi
}

The second part provides four styles to use Penrose tilings as fill pattern of arbitrary path:

\newcommand\setveclength[5]{%
  %\typeout{-#1-#2-#3-#4-}%
  \pgfpointanchor{#2}{#3}
  \pgfgetlastxy{\penrosexa}{\penroseya}
  \pgfpointanchor{#4}{#5}
  \pgfgetlastxy{\penrosexb}{\penroseyb}
  \pgfmathparse{veclen(\penrosexb-\penrosexa,\penroseyb-\penroseya)}
  \edef#1{\pgfmathresult}
}

\tikzset{
  semipenrose sym fill/.style={
    path picture={
      \setveclength{\mylen}%
      {path picture bounding box}{center}%
      {path picture bounding box}{north west}
      \pgfmathsetmacro{\len}{1.17*\mylen}
      \begin{scope}[shift={(path picture bounding box.center)}]
        \foreach \level in {0,...,4}{
          \begin{scope}[rotate=\level*72+9]
            \coordinate (a) at (0,0);
            \penrosesemikite{#1}{a}{0}{\len pt}{0}
            \penrosesemikite{#1}{a}{0}{\len pt}{1}
          \end{scope}
        }
      \end{scope}
    }
  },
  semipenrose fill/.style={
    path picture={
      \setveclength{\mylen}%
      {path picture bounding box}{center}%
      {path picture bounding box}{west}
      \pgfmathsetmacro{\len}{1.33*\mylen}
      \begin{scope}[shift={(path picture bounding box.center)},rotate=9]
        \coordinate (a) at (-\len pt,0);
        \path (a) +(36:2*\len pt) coordinate (b);
        \path (a) +(-36:2*\len pt) coordinate (c);
        \penrosesemidart{#1}{b}{36-180}{2*\len pt}{1}
        \penrosesemikite{#1}{a}{0}{2*\len pt}{0}
        \penrosesemikite{#1}{a}{0}{2*\len pt}{1}
        \penrosesemidart{#1}{c}{180-36}{2*\len pt}{0}
      \end{scope}
    }
  },
  penrose sym fill/.style={
    path picture={
      \setveclength{\mylen}%
      {path picture bounding box}{center}%
      {path picture bounding box}{north west}
      \pgfmathsetmacro{\len}{1.23*\mylen}
      \begin{scope}[shift={(path picture bounding box.center)}]
        \foreach \level in {0,...,4}{
          \begin{scope}[rotate=\level*72+9]
            \coordinate (a) at (0,0);
            \penrosekite{#1}{a}{18}{\len pt}{0}
            \penrosekite{#1}{a}{18}{\len pt}{1}
          \end{scope}
        }
      \end{scope}
    }
  },
  penrose fill/.style={
    path picture={
      \setveclength{\mylen}%
      {path picture bounding box}{center}%
      {path picture bounding box}{west}
      \pgfmathsetmacro{\len}{2.38*\mylen}
      \begin{scope}[shift={(path picture bounding box.center)},rotate=9]
        \coordinate (a) at (-\len pt,0);
        \path (a) +(36:2*\len pt) coordinate (b);
        \path (a) +(-36:2*\len pt) coordinate (c);
        \penrosedart{#1}{b}{36-180}{2*\len pt}{1}
        \penrosekite{#1}{a}{0}{2*\len pt}{0}
        \penrosekite{#1}{a}{0}{2*\len pt}{1}
        \penrosedart{#1}{c}{180-36}{2*\len pt}{0}
      \end{scope}
    }
  },
}

...then some examples.

First example (with default values):

\usetikzlibrary{shapes.arrows}
\pgfmathsetlengthmacro{\len}{4cm}
\pgfmathtruncatemacro{\recurs}{5}
\begin{document}
\begin{tikzpicture}
  \tikzset{
    gray arrow/.style={
      fill=gray,minimum height=.5cm,rotate=-90,
      single arrow,single arrow head extend=1mm,
    },
  }
  % explanations of building process
  \begin{scope}
    \path (-4cm,0)   coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemikite{0}{a}{0}{1.5cm}{0}
    \penrosesemikite{1}{b}{0}{1.5cm}{0}
    \node[gray arrow] at (arr){};

    \path (-2cm,0)   coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemikite{0}{a}{0}{1.5cm}{1}
    \penrosesemikite{1}{b}{0}{1.5cm}{1}
    \node[gray arrow] at (arr){};

    \path (0cm,0)    coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemidart{0}{a}{0}{1.5cm}{0}
    \penrosesemidart{1}{b}{0}{1.5cm}{0}
    \node[gray arrow] at (arr){};

    \path (2cm,0)    coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemidart{0}{a}{0}{1.5cm}{1}
    \penrosesemidart{1}{b}{0}{1.5cm}{1}
    \node[gray arrow] at (arr){};
  \end{scope}
  % example of semidarts and semikites
  \begin{scope}[yshift=-2*\len]
    \foreach \level in {0,...,4}{
      \begin{scope}[rotate=\level*72]
        \coordinate (a) at (0,0);
        \penrosesemikite{\recurs}{a}{0}{\len}{0}
        \penrosesemikite{\recurs}{a}{0}{\len}{1}
      \end{scope}
    }
  \end{scope}
  % explanations of building process
  \begin{scope}[yshift=-3.3*\len]
    \path (-3cm,0)   coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemikite{0}{a}{0}{1.5cm}{1}
    \penrosesemikite{0}{a}{0}{1.5cm}{0}
    \penrosekite{0}{b}{0}{1.5cm}{1}
    \penrosekite{0}{b}{0}{1.5cm}{0}
    \node[gray arrow] at (arr){};

    \path (1cm,0)    coordinate (a)
    +(.75cm,-1.25cm) coordinate (arr)
    ++(0,-2.5cm)     coordinate (b);
    \penrosesemidart{0}{a}{36}{1.5cm}{1}
    \penrosesemidart{0}{a}{-36}{1.5cm}{0}
    \penrosedart{0}{b}{36}{1.5cm}{1}
    \penrosedart{0}{b}{-36}{1.5cm}{0}
    \node[gray arrow] at (arr){};
  \end{scope}
  % example of darts and kites
  \begin{scope}[yshift=-5.2*\len]
    \foreach \level in {0,...,4}{
      \begin{scope}[rotate=\level*72]
        \coordinate (a) at (0,0);
        \penrosekite{\recurs}{a}{0}{\len}{0}
        \penrosekite{\recurs}{a}{0}{\len}{1}
      \end{scope}
    }
  \end{scope}
\end{tikzpicture}
\end{document}

first example (with default values)

The same example by appending the following lines :

  \tikzset{
    % style for borders
    line/.style={draw=white,rounded corners=0pt},
    % styles for semikites and semidarts
    penrose clockwise semikite/.style={fill=orange,line},
    penrose anticlockwise semikite/.style={fill=orange!50!black,line},
    penrose clockwise semidart/.style={fill=cyan!80,line},
    penrose anticlockwise semidart/.style={fill=cyan!50,line},
    % styles for kites and darts
    penrose kite/.style={fill=red!75!black,line},
    penrose dart/.style={fill=olive!75!white,line},
  }

second example with colors

Third example with shape variations (by appending the following lines):

  % set the three paths (and the three reverse paths)
  \pgfmathtruncatemacro{\defang}{36}
  \tikzset{
    common/.style={relative,looseness=1},
    penrose path 1/.style={out=\defang,in=180-\defang,common},
    penrose path 2/.style={out=\defang,in=180-\defang,common},
    penrose path 3/.style={out=-\defang,in=180+\defang,common},
    penrose rev path 1/.style={out=-\defang,in=180+\defang,common},
    penrose rev path 2/.style={out=-\defang,in=180+\defang,common},
    penrose rev path 3/.style={out=\defang,in=180-\defang,common},
  }

third example with shape variations

Last example: using Penrose tiling as pattern.

\begin{document}
\begin{tikzpicture}
  % some colors
  \tikzset{
    penrose line/.style={draw=white,line join=round,
      line width=.1pt,rounded corners=2pt},
    penrose kite/.style={left color=blue,right color=cyan,penrose line},
    penrose dart/.style={left color=yellow,right color=red,penrose line},
  }
  \begin{scope}
    % four styles exists: 'penrose fill', 'penrose sym fill',
    % 'semipenrose fill' and 'semipenrose sym fill'.
    % (argument is depth of recursion)
    \path[penrose fill=7,rounded corners=0mm]
    (0,.2) -- (4,0) -- (3,3) -- (2,2) -- (1,2) -- cycle;
  \end{scope}
\end{tikzpicture}
\end{document}

Penrose pattern

share|improve this answer
    
Is that really a penrose tiling? Interesing nonetheless. –  Fritz Jun 29 '12 at 6:30
1  
@Fritz Each of the ten triangles are a Penrose tiling. If you are in doubt, follow the first link I gave. –  Paul Gaborit Jun 29 '12 at 6:35
    
Great addition!! Do you think that it can be transformed into a custom fill pattern as in this one : tex.stackexchange.com/questions/54358/… ? Then Herbert's answer is truly replicated. By the way here is an interesting lecture from Peter Lu if you want to kill time: Harvard Colloquium Lecture –  percusse Jun 30 '12 at 18:24
    
@percusse: Good question! A fill pattern (as defined by TikZ/pgf) is periodic. Penrose tiling is non-periodic. How to transform a non-periodic tiling into a periodic pattern ? –  Paul Gaborit Jun 30 '12 at 19:37
2  
Fantastic. I hope this finds its way to the official version! –  percusse Jul 16 '12 at 23:35
show 2 more comments

run with pdflatex -shell-escape or pdflatex -enable-write18 (for Windows)

\documentclass{article}
\usepackage[pdf]{pstricks}
\begin{document}

\begin{pspicture}(10,8)
\pspolygon[fillstyle=penrose](0,4)(5,8)(10,4)
\pspolygon[fillstyle=penrose,psscale=0.2](0,0)(5,4)(10,0)
\end{pspicture}

\begin{pspicture}(10,8)
\pspolygon[fillstyle=penroseA,hatchcolor=white](0,4)(5,8)(10,4)
\pspolygon[fillstyle=penroseA,psscale=0.5,
  kitecolor=yellow,dartcolor=cyan,hatchcolor=blue](0,0)(5,4)(10,0)
\end{pspicture}
\end{document}

for the fillstyle=penroseA it needs the current pstricks.tex and pstricks.pro from http://texnik.dante.de/

enter image description here

share|improve this answer
    
What pstricks documentation should I read to learn more? –  Paul Gaborit Jun 30 '12 at 21:45
    
May be a bug with \pspolygon[fillstyle=penrose,psscale=0.2](0,0)(0,15)(15,15)(15,0)? –  Paul Gaborit Jun 30 '12 at 21:54
    
you need the pstricks.tex and pstricks.pro from texnik.dante.de The example code can be found in texnik.dante.de/doc/generic/pstricks/pst-news12.pdf With the fillstyle penrose an extremely fast algoithm is used the reason why it can be a problem with small scaling values because the predefined area then can be smaller than the clipping area. However, I'll improve the code. It doesn't happened with the fill style penroseA which uses an other algorithm. –  Herbert Jul 2 '12 at 9:11
add comment

Altermundus' lovely green star, like much of his code, can do with a simple loop.

\documentclass{scrartcl}
\usepackage[dvipsnames]{xcolor}
\usepackage{tikz}
\usetikzlibrary{shapes}
\def\ydo#1,#2,#3,#4;{%
  \ifx\ydo#1\else
    \noexpand\node[sub penta,red,anchor=corner #1,draw=black]%
      (p#2)\if0#3\else at(p#3.corner #4)\fi{};
    \expandafter\ydo
  \fi
}
\begin{document}
\def\alterl{0.382cm}
\begin{tikzpicture}[
  scale=2,transform shape,
  penta/.style={%
    shape=regular polygon,regular polygon sides=5,minimum size=#1,
    inner sep=0pt,outer sep=0pt,anchor=south,fill=lightgray
  }
]
  \begin{scope}[sub penta/.style={draw,penta=\alterl}]
    \pgfextra{%
      \edef\x{\ydo 4,1,0,0;3,2,1,5;4,3,2,1;5,4,3,2;1,5,4,3;\ydo,,,;}\x
    }%
    \fill[green](p1.corner 5)--(p3.corner 2)--(p5.corner 4)
      --(p2.corner 1)--(p4.corner 3)--cycle;
  \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
add comment

This is my first attempt with TikZ. I try to make this : Penrose_tiling(P1). I agree with Herbert that the better method is to use a recursion but for the moment, I don't know how to begin a recursion in this case. So here I try only to reproduce the drawing that you can see in the link.

version 7

Remarks :

1) Now with the same methods, it's easy to get the complete figure given in the link.

2) Now it's interesting to find another way ...

3) I changed some names for options like penta instead of hexa. I added the green stars surrounded by five pentagons. I added the code for the little part at the end of my answer.

Some explanations. First I draw a pentagone (s) then I draw inside (s) five pentagons. I used \l=0.382 cm because I have not had the courage to make an effort to calculate the ratio between the lengths of pentagons ( but it's not a real great problem).

enter image description here

\documentclass{scrartcl}
\usepackage[dvipsnames]{xcolor}  
\usepackage{tikz}
\usetikzlibrary{shapes}

\begin{document} 
\def\l{0.382cm} 

\begin{tikzpicture} [scale=2,
                     transform shape,
                     penta/.style= {shape                 =  regular polygon,
                                   regular polygon sides = 5,
                                   minimum size          = #1,
                                   inner sep             = 0,
                                   outer sep             = 0,
                                   anchor                = south,
                                   fill                  = lightgray}] 
\node[penta=1cm,fill=yellow] (s) {};
\foreach \i in {1,...,5} {\node[draw,penta=\l,anchor=corner \i]  at (s.corner \i) {};}
\node[penta=\l,anchor=center,fill=MidnightBlue,rotate=36]  at (s.center) {}; 

\begin{scope}[rotate=108,sub penta/.style= {draw,penta=\l,anchor=corner \j}]
         \foreach \i in {1,...,5}{%
      \node[penta=1cm,fill=yellow,anchor=corner \i] (s\i) at (s.corner \i){};
      \foreach \j in {1,...,5}{%
         \pgfmathtruncatemacro\k{mod(\i,5)+1}
         \ifnum\j=\i \tikzset{sub penta/.append style={fill=red}}         \fi
         \ifnum\j=\k \tikzset{sub penta/.append style={fill=red}}         \fi
         \node[sub penta] (s\i\j) at (s\i.corner \j){};
         }
   \node[penta=\l,anchor=center,fill=MidnightBlue,rotate=36]  at (s\i.center) {};
     \pgfmathtruncatemacro\ii{mod(\i+1,5)+1} 
     \pgfmathtruncatemacro\iii{mod(\i+3,5)+1} 
   \node[penta=\l,anchor=corner \ii,fill=red,rotate=36,draw] (ss\i)  at (s\i.corner \iii) {};
                     }  
    \foreach \i in {1,...,5}{%
      \pgfmathtruncatemacro\ii{mod(\i,5)+1}
      \pgfmathtruncatemacro\j{mod(\i+1,5)+1}
      \pgfmathtruncatemacro\k{mod(\i+2,5)+1}
      \pgfmathtruncatemacro\h{mod(\i+2,5)+1} 
      \pgfmathtruncatemacro\l{mod(\i+3,5)+1} 
      \fill[MidnightBlue!40,draw=black] (s.corner \i) 
                                     -- (s\i\i.corner \l) 
                                     -- (s\i\i.corner \k) 
                                     -- (ss\i.corner \ii)  
                                     -- (ss\i.corner \i)
                                     -- (s\ii\j.corner \l) 
                                     -- (s\ii\j.corner \h) 
                                     -- cycle;
    }   
   \foreach \i in {1,...,5}{%
   \pgfmathtruncatemacro\j{mod(\i+2,5)+1}  
     \node[penta=1cm,fill=yellow,anchor=corner \i,rotate=-36] (t\i) at (s\i\j.corner \j) {t}; 
     \node[penta=1cm,fill=yellow,anchor=corner \i,rotate=108] (u\i) at (s\i\j.corner \j) {};
      \foreach \k in {1,...,5} {%
      \node[draw,penta=\l,anchor=corner \k,rotate=-36,fill=red] (t\i\k)  at (t\i.corner \k) {};}
      \foreach \k in {1,...,5} {%
      \node[draw,penta=\l,anchor=corner \k,rotate=108,fill=red]
            (u\i\k) at  (u\i.corner \k) {};}  
           \node[penta=\l,anchor=center,fill=MidnightBlue]  at (t\i.center) {}; 
           \node[penta=\l,anchor=center,fill=MidnightBlue]  at (u\i.center) {}; 
           } 
           \foreach \i in {1,...,5} {%
           \pgfmathtruncatemacro\j{mod(\i+3,5)+1}
           \node[sub penta,fill=lightgray,anchor=center,rotate=36]  at (t\i\j){}; 
           \node[sub penta,fill=lightgray,anchor=center,rotate=36]  at (u\j\i){};     
           }   

   \foreach \i in {1,...,5} {%
            \pgfmathtruncatemacro\j{mod(\i+2,5)+1}
            \pgfmathtruncatemacro\k{mod(\i+3,5)+1}
            \pgfmathtruncatemacro\h{mod(\i+1,5)+1} 
            \pgfmathtruncatemacro\l{mod(\i,5)+1} 
      \fill[green] (ss\i.corner \h)  -- (t\l\h.corner \k) --
                   (u\i\j.corner \i) -- (ss\i.corner \k)  --
                   (u\i\j.corner \j) -- cycle;
      }   
\end{scope}
 \foreach \j in {1,...,5}{%
      \pgfmathtruncatemacro\k{mod(\j+1,5)+1} 
  \begin{scope}[rotate=108]
    \node[penta=1cm,fill=yellow,anchor=corner \k] (xs\j) at (u\j.corner \k) {};
     \foreach \i in {1,...,5} {\node[draw,penta=\l,anchor=corner \i]  at 
                              (xs\j.corner \i) {};}
   \node[penta=\l,anchor=center,fill=MidnightBlue,rotate=36]  at (xs\j.center) {}; 
  \end{scope}  
   }     
  \foreach \i in {1,...,5}{% 
   \pgfmathtruncatemacro\j{mod(\i,5)+1}
   \pgfmathtruncatemacro\k{mod(\i+1,5)+1} \pgfmathtruncatemacro\h{mod(\i+2,5)+1}
  \begin{scope}[sub penta/.style= {draw,penta=\l},rotate=36+(\i-1)*72]
  \node[sub penta,red,anchor=corner 4,draw=black] (p1) at (t\j\i.corner \j) {};
  \node[sub penta,red,anchor=corner 3,draw=black] (p2) at (p1.corner 5) {};
  \node[sub penta,red,anchor=corner 4,draw=black] (p3) at (p2.corner 1) {};
  \node[sub penta,red,anchor=corner 5,draw=black] (p4) at (p3.corner 2) {};
  \node[sub penta,red,anchor=corner 1,draw=black] (p5) at (p4.corner 3) {}; 
  \fill[green] (p1.corner 5) -- (p3.corner 2) -- (p5.corner 4) -- (p2.corner 1) -- 
   (p4.corner 3) -- cycle;
  \fill[MidnightBlue!40,draw=black] (p1.corner 3) -- (p1.corner 4) -- 
                                    (t\j\i.corner \k)  --  
                                    (t\j\j.corner \i)  -- 
                                    (t\j\j.corner \j) -- 
                                    (u\j\j.corner \k)  -- (u\j\j.corner \h) -- cycle;        
  \end{scope}}  
    \end{tikzpicture}  

\end{document}   

Green star surrounded by five pentagons

   \begin{tikzpicture} [scale=2,
                         transform shape,
                         penta/.style= {shape                 =  regular polygon,
                                       regular polygon sides = 5,
                                       minimum size          = #1,
                                       inner sep             = 0,
                                       outer sep             = 0,
                                       anchor                = south,
                                       fill                  = lightgray}] 
      \begin{scope}[sub penta/.style= {draw,penta=\l}]
      \node[sub penta,red,anchor=corner 4,draw=black] (p1)  {};
      \node[sub penta,red,anchor=corner 3,draw=black] (p2) at (p1.corner 5) {};
      \node[sub penta,red,anchor=corner 4,draw=black] (p3) at (p2.corner 1) {};
      \node[sub penta,red,anchor=corner 5,draw=black] (p4) at (p3.corner 2) {};
      \node[sub penta,red,anchor=corner 1,draw=black] (p5) at (p4.corner 3) {}; 
      \fill[green] (p1.corner 5) -- (p3.corner 2) -- (p5.corner 4) -- 
                   (p2.corner 1) -- (p4.corner 3) -- cycle;      
      \end{scope}

 \end{tikzpicture}

enter image description here

With

  \def\r{2.31}
  \draw[shift=(s.center),clip] (-54:\r) -- (18:\r) -- (90:\r) -- (162:\r) -- (234:\r) -- cycle;  

we get :

enter image description here

share|improve this answer
    
without a recursion you don't get the correct Penrose tiling –  Herbert Jun 28 '12 at 12:19
    
I agree that a recursion is the better way but I think that it's possible to reproduce Penrose_Tiling_(P1).svg en.wikipedia.org/wiki/File%3aPenrose_Tiling_%28P1%29.svg . The only difficulty is to add the colors. Is it possible to make this drawing with pstricks ? –  Alain Matthes Jun 28 '12 at 12:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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