% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*readme>
----------------------------------------------------------------
penrose --- TikZ library for producing Penrose tilings
E-mail: loopspace@mathforge.org
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

This package is for the creation of Penrose tilings using either kite-and-dart or rhombuses, and either by manual placement or automatic generation.
%</readme>
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
  \expandafter\begingroup
\fi
%</internal>
%<*install>
\input l3docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble
----------------------------------------------------------------
penrose --- TikZ library for producing Penrose tilings
E-mail: loopspace@mathforge.org
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
----------------------------------------------------------------

\endpreamble
\postamble

Copyright (C) 2014-2019 by Andrew Stacey <loopspace@mathforge.org>

This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License (LPPL), either
version 1.3c of this license or (at your option) any later
version.  The latest version of this license is in the file:

http://www.latex-project.org/lppl.txt

This work is "maintained" (as per LPPL maintenance status) by
Andrew Stacey.

This work consists of the files  penrose_code.dtx
                                 penrose.tex
and the derived files            penrose.ins
                                 penrose_code.pdf
                                 penrose.pdf
                                 tikzlibrarypenrose.code.tex
                                 README.txt

\endpostamble
\usedir{tex/latex/penrose}
\generate{
  \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{package}}
}
%</install>
%<install>\endbatchfile
%<*internal>
\usedir{source/latex/penrose}
\generate{
  \file{\jobname.ins}{\from{\jobname.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/latex/penrose}
\generate{
  \file{README.txt}{\from{\jobname.dtx}{readme}}
}
\ifx\fmtname\nameofplainTeX
  \expandafter\endbatchfile
\else
  \expandafter\endgroup
\fi
%</internal>
%<*driver>
\documentclass{l3doc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
%\usepackage{trace}
\usetikzlibrary{penrose}
%\traceoff
%\usepackage[numbered]{hypdoc}
\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} 
 
\usepackage{listings}
\lstloadlanguages{[LaTeX]TeX}
\lstset{breakatwhitespace=true,breaklines=true,language=TeX}
 
\usepackage{fancyvrb}

\newenvironment{example}
  {\VerbatimEnvironment
   \begin{VerbatimOut}[gobble=2]{example.out}}
  {\end{VerbatimOut}
   \begin{center}
%   \setlength{\parindent}{0pt}
   \fbox{\begin{minipage}{.9\linewidth}
     \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small}
     \lstinputlisting[]{example.out}
   \end{minipage}}

   \fbox{\begin{minipage}{.9\linewidth}
     \input{example.out}
   \end{minipage}}
\end{center}
}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{2944}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{1.0}{2014/05/07}{Converted to DTX file}
% \changes{1.2}{2019/02/23}{Added general tile creation code}
% \changes{1.4}{2021/01/22}{Adapted to latest version of spath3}
%
% \DoNotIndex
%   {
%     \begingroup,
%     \catcode,
%     \active,
%     \csname,
%     \endcsname,
%   }%
%
%
% \providecommand*{\url}{\texttt}
% \GetFileInfo{tikzlibrarypenrose.code.tex}
% \title{The \textsf{Penrose} package}
% \author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}}
% \date{\fileversion~from \filedate}
%
%
% \maketitle
%
% \tableofcontents
%
% \begin{documentation}
% 
% \section{Introduction}
%
% This is a TikZ library for drawing Penrose tiles (kite/dart, rhombus, and pentagon versions).
% It provides two methods of drawing: one in which an automatic pattern is built, and one where the tiles can be placed ``by hand''.
% The tiles can be shaped and (hopefully!) still fit together.
% For full user documentation, see the \Verb+penrose.pdf+ file.
%
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{Implementation}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%    \begin{macrocode}
%<@@=penrose>
%    \end{macrocode}
%
% \subsection{Initialisation}
%
%
% We use the \Verb+spath3+ library for manipulating the paths that will make up the tiles.
%
%    \begin{macrocode}
\ProvidesExplFile {tikzlibrarypenrose.code.tex} {2021/01/22} {1.4} {TikZ pics for Penrose and other tiles}
\RequirePackage{spath3}
\usetikzlibrary{spath3}
%    \end{macrocode}
% Now we move in to the realm of \LaTeX3.
%    \begin{macrocode}
\ExplSyntaxOn
%    \end{macrocode}
%
% Start with some basic paths (lines) for the sides of the tiles so that we know that we have well-defined tiles at the outset.
% These are globally defined as we will frequently want to define them in one tikzpicture and use them in another.
%
%    \begin{macrocode}
\tl_new:N \g_@@_side_a_tl
\tl_new:N \g_@@_side_b_tl
\tl_new:N \g_@@_side_c_tl
\tl_new:N \g_@@_side_d_tl
\tl_new:N \g_@@_side_e_tl
\tl_new:N \g_@@_side_A_tl
\tl_new:N \g_@@_side_B_tl
\tl_new:N \g_@@_side_C_tl
\tl_new:N \g_@@_side_D_tl
\tl_new:N \g_@@_side_E_tl
\tl_gset:Nn \g_@@_side_a_tl
{
  \pgfsyssoftpath@movetotoken{0pt}{0pt}
  \pgfsyssoftpath@linetotoken{1pt}{0pt}
}
\tl_gset_eq:NN \g_@@_side_b_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_c_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_d_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_e_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_A_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_B_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_C_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_D_tl \g_@@_side_a_tl
\tl_gset_eq:NN \g_@@_side_E_tl \g_@@_side_a_tl
%    \end{macrocode}
%
% \begin{variable}{\l_@@_tmpa_fp, \l_@@_tmpb_fp, \l_@@_tmpc_fp, \l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpc_tl, \l_@@_tmpd_tl, \l_@@_tmpa_int, \l_@@_tmpb_int, \l_@@_xa_dim, \l_@@_ya_dim, \l_@@_xb_dim, \l_@@_yb_dim, \l_@@_tmpa_prop}
% We need a few temporary variables to hold intermediate calculations.
%
%    \begin{macrocode}
\fp_new:N \l_@@_tmpa_fp
\fp_new:N \l_@@_tmpb_fp
\fp_new:N \l_@@_tmpc_fp
\str_new:N \l_@@_tmpa_str
\str_new:N \l_@@_tmpb_str
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
\tl_new:N \l_@@_tmpc_tl
\tl_new:N \l_@@_tmpd_tl
\tl_new:N \l_@@_tmp_tile_path_tl
\tl_new:N \g_@@_smuggle_tl
\int_new:N \l_@@_tmpa_int
\int_new:N \l_@@_tmpb_int
\dim_new:N \l_@@_xa_dim
\dim_new:N \l_@@_ya_dim
\dim_new:N \l_@@_xb_dim
\dim_new:N \l_@@_yb_dim
\prop_new:N \l_@@_tmpa_prop
%    \end{macrocode}
% \end{variable}
%
% \subsection{Creating the Tiles}
%
% \begin{macro}[internal]{\@@_normalise_path:Nn}
% When defining the path for a side, we normalise so that it starts at the origin and ends at \Verb+(1pt,0pt)+.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_normalise_path:Nn #1#2
{
%    \end{macrocode}
% Get the initial point of the path and convert to floating point.
%    \begin{macrocode}
  \group_begin:
  \spath_initialpoint:Nn \l_@@_tmpa_tl {#2}
  \fp_set:Nn \l_@@_tmpa_fp {\tl_head:N \l_@@_tmpa_tl}
  \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
  \fp_set:Nn \l_@@_tmpb_fp {\tl_head:N \l_@@_tmpa_tl}
%    \end{macrocode}
% Get the final point of the path, and compute the difference of the final and initial points.
%
% The resulting numbers, say \(a\) and \(b\), will be put into a matrix to rotate and scale the path.
% The formula for the matrix is:
%^^A
% \[
% \frac{1}{a^2 + b^2}
% \begin{bmatrix} a & b \\ -b & a \end{bmatrix}
% \]
%
%    \begin{macrocode}
  \spath_finalpoint:Nn \l_@@_tmpa_tl {#2}
  \fp_set:Nn \l_@@_tmpa_fp
  {\tl_head:N \l_@@_tmpa_tl - \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
  \fp_set:Nn \l_@@_tmpb_fp
  {\tl_head:N \l_@@_tmpa_tl - \l_@@_tmpb_fp}
%    \end{macrocode}
% Now compute the square of the length of the path for scaling.
%    \begin{macrocode}
  \fp_set:Nn \l_@@_tmpc_fp
  {\l_@@_tmpa_fp^2 + \l_@@_tmpb_fp^2}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_tmpa_fp/\l_@@_tmpc_fp}
  \fp_set:Nn \l_@@_tmpb_fp {\l_@@_tmpb_fp/\l_@@_tmpc_fp}
  \fp_set:Nn \l_@@_tmpc_fp {-\l_@@_tmpb_fp}
%    \end{macrocode}
% Now construct the matrix.
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpb_tl
  {
    {\fp_use:N \l_@@_tmpa_fp}
    {\fp_use:N \l_@@_tmpc_fp} % swapped
    {\fp_use:N \l_@@_tmpb_fp} % swapped
    {\fp_use:N \l_@@_tmpa_fp}
  }
%    \end{macrocode}
% Get the initial point back again for the translation part.
%    \begin{macrocode}
  \spath_initialpoint:Nn \l_@@_tmpa_tl {#2}
%    \end{macrocode}
% But we need to premultiply by the matrix because of how the transformations are applied.
%    \begin{macrocode}
  \fp_set:Nn \l_@@_tmpa_fp
  {
    (-1) * \l_@@_tmpa_fp * \tl_head:N \l_@@_tmpa_tl
    + (-1) * \l_@@_tmpb_fp * \tl_tail:N \l_@@_tmpa_tl
  }
  \fp_set:Nn \l_@@_tmpb_fp
  {
    (-1) * \l_@@_tmpa_fp * \tl_tail:N \l_@@_tmpa_tl
    +  \l_@@_tmpb_fp * \tl_head:N \l_@@_tmpa_tl
  }
%    \end{macrocode}
% Finally, we apply the transformation to the path.
%    \begin{macrocode}
  \tl_put_right:Nx \l_@@_tmpb_tl {
    {\fp_to_dim:N \l_@@_tmpa_fp}
    {\fp_to_dim:N \l_@@_tmpb_fp}
  }
  \spath_transform:NnV \l_@@_tmpa_tl {#2} \l_@@_tmpb_tl
  \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpa_tl
  \group_end:
  \tl_set_eq:NN #1 \g_@@_smuggle_tl
  \tl_gclear:N \g_@@_smuggle_tl
}
\cs_generate_variant:Nn \@@_normalise_path:Nn {NV, cn, cV}
\cs_new_protected_nopar:Npn \@@_normalise_path:N #1
{
  \@@_normalise_path:NV #1#1
}
\cs_generate_variant:Nn \@@_normalise_path:N {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{function}{\SetPenrosePath}
% This sets the path corresponding to a particular side to the current path, and normalises it.
%    \begin{macrocode}
\NewDocumentCommand \SetPenrosePath { m }
{
  \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
  \@@_normalise_path:N \l_@@_tmpa_tl
  \tl_gset_eq:cN {g_@@_side_#1_tl} \l_@@_tmpa_tl
}
%    \end{macrocode}
% \end{function}
%
% \begin{macro}[internal]{\tikz_scan_point:n}
% This is a wrapper around \Verb+\tikz@scan@one@point+ to make it easier to use with \LaTeX3 variables.
%    \begin{macrocode}
\cs_new_nopar:Npn \tikz_scan_point:n #1
{
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
}
\cs_generate_variant:Nn \tikz_scan_point:n {V}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_make_tile:nnn}
% This builds the tile path from its pieces.
% The arguments are the name of the tile, the descriptions of the sides, and a token list of the coordinates.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_make_tile:nnn #1#2#3
{
%    \end{macrocode}
% Get the first coordinate and initialise the path with a move to this point.
%    \begin{macrocode}
  \group_begin:
  \tl_set:Nn \l_@@_tmpa_tl {#3}
  \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
  \tl_set:Nn \l_@@_tmpa_tl {\pgfsyssoftpath@movetotoken}
  \tikz_scan_point:V \l_@@_tmpb_tl
  \tl_put_right:Nx \l_@@_tmpa_tl
  {
    {\dim_use:N \pgf@x}{\dim_use:N \pgf@y}
  }
  \tl_set_eq:NN \l_@@_tmp_tile_path_tl \l_@@_tmpa_tl
%    \end{macrocode}
% Now we have our path initialised, we can start appending the side paths according to the specification in the second argument.
%
% We append the initial coordinate to the end of the list to make a closed cycle.
%    \begin{macrocode}
  \tl_set:Nn \l_@@_tmpa_tl {#3}
  \tl_put_right:Nx \l_@@_tmpa_tl {{\tl_head:N \l_@@_tmpa_tl}}
%    \end{macrocode}
% Now we walk through the description of the sides, adding the specified paths to our tile path.
%    \begin{macrocode}
  \tl_map_inline:nn {#2} {
%    \end{macrocode}
% Clone the path for this side.
%    \begin{macrocode}
    \tl_set:Nx \l_@@_tmpc_tl {\tl_head:n {##1}}
    \tl_set_eq:Nc \l_@@_tmpd_tl {g_@@_side_ \tl_use:N \l_@@_tmpc_tl _tl}
%    \end{macrocode}
% Strip off the next coordinate, and convert it to a point.
%    \begin{macrocode}
    \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
    \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
    \tikz_scan_point:V \l_@@_tmpb_tl
%    \end{macrocode}
% Store the resulting coordinate.
%    \begin{macrocode}
    \fp_set:Nn \l_@@_tmpa_fp { \pgf@x }
    \fp_set:Nn \l_@@_tmpb_fp { \pgf@y }
%    \end{macrocode}
% Now get the next coordinate.
%    \begin{macrocode}
    \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
    \tikz_scan_point:V \l_@@_tmpb_tl
%    \end{macrocode}
% We want the difference between the two coordinates.
%    \begin{macrocode}
    \fp_set:Nn \l_@@_tmpa_fp {\pgf@x - \l_@@_tmpa_fp}
    \fp_set:Nn \l_@@_tmpb_fp {\pgf@y - \l_@@_tmpb_fp}
%    \end{macrocode}
% This is converted into a transformation matrix.
%    \begin{macrocode}
    \fp_set:Nn \l_@@_tmpc_fp {-\l_@@_tmpb_fp}
    \tl_set:Nx \l_@@_tmpb_tl
    {
      {\fp_use:N \l_@@_tmpa_fp}
      {\fp_use:N \l_@@_tmpb_fp} % not swapped
      {\fp_use:N \l_@@_tmpc_fp} % not swapped
      {\fp_use:N \l_@@_tmpa_fp}
      {0}
      {0}
    }
%    \end{macrocode}
% The transformation is applied to the cloned path.
%    \begin{macrocode}
    \spath_transform:NV \l_@@_tmpd_tl \l_@@_tmpb_tl
%    \end{macrocode}
% And this is welded to the tile path.
%    \begin{macrocode}
    \spath_weld:NV \l_@@_tmp_tile_path_tl \l_@@_tmpd_tl
  }
%    \end{macrocode}
% At the end we close the path.
%    \begin{macrocode}
  \spath_close:N \l_@@_tmp_tile_path_tl
  \tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmp_tile_path_tl
  \group_end:
  \tl_gclear_new:c {g_@@_tile_#1_tl}
  \tl_gset_eq:cN {g_@@_tile_#1_tl} \g_@@_smuggle_tl
  \tl_gclear:N \g_@@_smuggle_tl
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_make_tile:nn}
% A wrapper around the above which allows us to specify the second two arguments as two items in a token list.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_make_tile:nn #1#2
{
  \@@_make_tile:nnn {#1} #2
}
\cs_generate_variant:Nn \@@_make_tile:nn {nV}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Specifying the Tiles}
%
% The tile specifications are contained in a \Verb+prop+.
%    \begin{macrocode}
\prop_new:N \g_@@_tiles_prop
%    \end{macrocode}
%
% \begin{macro}[internal]{\@@_add_coordinate:Nnn, \@@_add_coordinate:w}
% Process a coordinate through \Verb+fp+ and adds it to a token list.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_add_coordinate:Nnn #1#2#3 {
  \fp_set:Nn \l_@@_tmpa_fp{#2}
  \fp_set:Nn \l_@@_tmpb_fp{#3}
  \tl_put_right:Nx #1
  {
    {(\fp_use:N \l_@@_tmpa_fp, \fp_use:N \l_@@_tmpb_fp)}
  }
}
%    \end{macrocode}
% Wrapper around the add coordinate command to split at a comma.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_add_coordinate:w #1#2,#3 \q_stop
{
  \@@_add_coordinate:Nnn \l_@@_tmpa_tl {#2}{#3}
}
%    \end{macrocode}
% \end{macro}
%
% Now we specify the tiles.
% The specification is a clockwise list of the vertices together with the labels of the corresponding sides.
% There are three basic paths, \Verb+a+, \Verb+b+, \Verb+c+, and their complements (which are capitalised).
%
% \begin{itemize}
% \item Thin Rhombus.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(18)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}

\prop_gput:Nnx \g_@@_tiles_prop {thin~ rhombus}
{{a A B b} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Thick Rhombus.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}

\prop_gput:Nnx \g_@@_tiles_prop {thick~ rhombus}
{{B a A b} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Dart.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{2*sind(18)*cosd(108)}{2*sind(18)*sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*sind(18)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{2*sind(18)*cosd(108)}{-2*sind(18)*sind(108)}

\prop_gput:Nnx \g_@@_tiles_prop {dart}
{{c a A C} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Kite.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}

\prop_gput:Nnx \g_@@_tiles_prop {kite}
{{a c C A} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Golden Triangle.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}

\prop_gput:Nnx \g_@@_tiles_prop {golden~ triangle}
{{a c b} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Reverse Golden Triangle.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}

\prop_gput:Nnx \g_@@_tiles_prop {reverse~ golden~ triangle}
{{B C A} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Golden Gnomon
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}

\prop_gput:Nnx \g_@@_tiles_prop {golden~ gnomon}
{{C b A} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Reverse Golden Gnomon
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(36)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(36)}{-sind(36)}
\prop_gput:Nnx \g_@@_tiles_prop {reverse~ golden~ gnomon}
{{a B c} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Primary Pentagon (pentagon 5)
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{1+cosd(72)+cosd(144)}{sind(72)+sind(144)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1+cosd(72)}{sind(72)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 5}
{{a a a a a} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Secondary Pentagon (pentagon 3)
%    \begin{macrocode}
\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 3}
{{A b a a b} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Tertiary Pentagon (pentagon 2)
%    \begin{macrocode}
\prop_gput:Nnx \g_@@_tiles_prop {pentagon~ 2}
{{d A e c A} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Pentagram
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1-cosd(36)}{-sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{1-cosd(36)-cosd(108)}{-sind(36)-sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{-sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+3*cosd(108)+cosd(36)}{-sind(36)-sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+2*cosd(108)+cosd(36)}{-sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {-1+2*cosd(108)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(108)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\prop_gput:Nnx \g_@@_tiles_prop {pentagram}
{{C E C E C E C E C E} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Boat
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {-1+2*cosd(108)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(108)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(108)}{sind(108)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {1-cosd(36)}{-sind(36)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl
{-1+2*cosd(108)+cosd(36)}{-sind(36)}
\prop_gput:Nnx \g_@@_tiles_prop {boat}
{{C E C E B D B} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \item Diamond.
%    \begin{macrocode}
\tl_clear:N \l_@@_tmpa_tl
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {0}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{sind(18)}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {2*cosd(18)}{0}
\@@_add_coordinate:Nnn \l_@@_tmpa_tl {cosd(18)}{-sind(18)}
\prop_gput:Nnx \g_@@_tiles_prop {diamond}
{{D B B D} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
%
% \end{itemize}
%
% \begin{function}{\BakePenroseTile}
% This is the user wrapper around the tile creation macros.
%    \begin{macrocode}
\NewDocumentCommand \BakePenroseTile {m}
{
  \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
  \@@_make_tile:nV {#1} \l_@@_tmpa_tl
}
%    \end{macrocode}
% For backwards compatibility.
%    \begin{macrocode}
\cs_set_eq:NN \MakePenroseTile \BakePenroseTile
%    \end{macrocode}
% \end{function}
%
% \begin{function}{\UsePenroseTile}
% This is the command that actually places a tile on the page.
% The first argument is optional and is for styling.
%    \begin{macrocode}
\NewDocumentCommand \UsePenroseTile {O{} m} 
{
%    \end{macrocode}
% We need to transform the tile to correspond to the current transformation matrix.
% To ensure that we only transform the current tile, we clone it first.
%    \begin{macrocode}
  \tl_set_eq:Nc \l_@@_tmp_tile_path_tl {g_@@_tile_#2_tl}
%    \end{macrocode}
% The transformation matrix returned by PGF appears to be transposed from what it should be.
% (This needs a little more investigation, it might be that I've implemented the multiplication incorrectly here.)
%    \begin{macrocode}
  \pgfgettransform \l_@@_tmpa_tl
%  \tl_clear:N \l_@@_tmpb_tl
%  \tl_set:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
%  \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
%  \tl_put_right:Nx \l_@@_tmpb_tl
%  {
%    {\tl_item:Nn \l_@@_tmpa_tl {1}}
%  }
%  \tl_put_right:Nx \l_@@_tmpb_tl
%  {
%    {\tl_item:Nn \l_@@_tmpa_tl {2}}
%  }
%  \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
%  \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
%  \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
%    \end{macrocode}
% Apply the transformation, protocol the path, and render it.
%    \begin{macrocode}
  \spath_transform:NV \l_@@_tmp_tile_path_tl \l_@@_tmpa_tl
  \spath_tikz_path:nV {#1} \l_@@_tmp_tile_path_tl
}
%    \end{macrocode}
% \end{function}
%
% \begin{macro}{save Penrose path}
% This is a style for a user to take a path and make it into the path for one of the sides.
% It needs to store both that side and the reverse.
%    \begin{macrocode}
\tikzset{
  save~ Penrose~ path/.code={
    \tikz@addmode{
%    \end{macrocode}
% Get the current path.
%    \begin{macrocode}
      \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
%    \end{macrocode}
% Normalise the path and save.
%    \begin{macrocode}
      \@@_normalise_path:N \l_@@_tmpa_tl
      \tl_gclear_new:c {g_@@_side_#1_tl}
      \tl_gset_eq:cN {g_@@_side_#1_tl} \l_@@_tmpa_tl
%    \end{macrocode}
% Now create the reverse path.
% The name is the upper case version.
%    \begin{macrocode}
      \tl_set:Nx \l_@@_tmpb_tl {\str_uppercase:n {#1}}
%    \end{macrocode}
% Reverse the path, and relocate to the interval \([0,1]\).
%    \begin{macrocode}
      \spath_reverse:N \l_@@_tmpa_tl
      \spath_transform:Nnnnnnn \l_@@_tmpa_tl {-1} {0} {0} {-1} {1} {0}
      \tl_gclear_new:c {g_@@_side_ \tl_use:N \l_@@_tmpb_tl _tl}
      \tl_gset_eq:cN {g_@@_side_ \tl_use:N \l_@@_tmpb_tl _tl} \l_@@_tmpa_tl
    }
  },
  clone~ Penrose~ side~ path/.style~ 2~ args={
    spath/set~ name=Penrose~side,
    spath/clone~ global={#1}{#2}
  },
  spath/prefix/Penrose~side/.style={
    spath/set~ prefix=g_@@_side_,
  },
  spath/suffix/Penrose~side/.style={
    spath/set~ suffix=_tl,
  },
  clone~ Penrose~ tile~ path/.style~ 2~ args={
    spath/set~ name=Penrose~tile,
    spath/clone~ global={#1}{#2}
  },
  spath/prefix/Penrose~tile/.style={
    spath/set~ prefix=g_@@_tile_,
  },
  spath/suffix/Penrose~tile/.style={
    spath/set~ suffix=_tl,
  },
  expand~ key/.code={
    \exp_args:NV \pgfkeysalso #1
  }
}
%    \end{macrocode}
% \end{macro}
%
% Create the basic tile shapes.
%    \begin{macrocode}
\BakePenroseTile {thin~ rhombus}
\BakePenroseTile {thick~ rhombus} 
\BakePenroseTile {dart}
\BakePenroseTile {kite}
\BakePenroseTile {golden~ triangle}
\BakePenroseTile {reverse~ golden~ triangle}
\BakePenroseTile {golden~ gnomon}
\BakePenroseTile {reverse~ golden~ gnomon}
\BakePenroseTile {pentagon~ 5}
\BakePenroseTile {pentagon~ 3}
\BakePenroseTile {pentagon~ 2}
\BakePenroseTile {pentagram}
\BakePenroseTile {boat}
\BakePenroseTile {diamond}
%    \end{macrocode}
%
%
% \subsection{User-Definable Tiles}
%
% The commands in this section are for enabling a user to define their own tile.
%
%
% \begin{macro}[internal]{\@@_transform_side:nn}
% Apply a transformation to make a given side lie on the x-axis.
% First argument is the tile, second is the side.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_transform_side:nn #1#2
{
%    \end{macrocode}
% Get our tile data.
%    \begin{macrocode}
  \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
%    \end{macrocode}
% Start with the edge list.
%
% Initialise the counter.
%    \begin{macrocode}
  \int_zero:N \l_@@_tmpb_int
  \int_incr:N \l_@@_tmpb_int
%    \end{macrocode}
% Get the path type list.
%
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
%    \end{macrocode}
%
% Iterate through the path type list, looking for the requested path.
%    \begin{macrocode}
  \tl_map_inline:Nn \l_@@_tmpc_tl {
    \str_if_eq:nnT {##1} {#2} {
      \tl_map_break:
    }
    \int_incr:N \l_@@_tmpb_int
  }
%    \end{macrocode}
% Get the coordinate list.
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpa_tl}
%    \end{macrocode}
% Strip off the outer braces.
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl {\tl_item:Nn \l_@@_tmpc_tl {1}}
%    \end{macrocode}
% Add the first coordinate at the end.
%    \begin{macrocode}
  \tl_put_right:Nx \l_@@_tmpc_tl
  {{\tl_item:Nn \l_@@_tmpc_tl {1}}}
%    \end{macrocode}
% Get the coordinates for this edge.
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpa_tl
  {\tl_item:Nn \l_@@_tmpc_tl {\int_use:N \l_@@_tmpb_int}}
  \tl_set:Nx \l_@@_tmpb_tl
  {\tl_item:Nn \l_@@_tmpc_tl {\int_use:N \l_@@_tmpb_int + 1}}
%    \end{macrocode}
% Translate second to origin.
%    \begin{macrocode}
  \tikz_scan_point:V \l_@@_tmpb_tl
  \dim_set_eq:Nc \l_@@_xa_dim {pgf@x}
  \dim_set_eq:Nc \l_@@_ya_dim {pgf@y}
%    \end{macrocode}
% Rotate and scale first to unit x-vector.
%    \begin{macrocode}
  \tikz_scan_point:V \l_@@_tmpa_tl
  \dim_set_eq:Nc \l_@@_xb_dim {pgf@x}
  \dim_set_eq:Nc \l_@@_yb_dim {pgf@y}

  \dim_sub:Nn \l_@@_xb_dim {\l_@@_xa_dim }
  \dim_sub:Nn \l_@@_yb_dim {\l_@@_ya_dim }
%    \end{macrocode}
% And normalise the vector along it.
%    \begin{macrocode}
  \pgfpointnormalised{\pgfpoint{\l_@@_xb_dim}{\l_@@_yb_dim}}
  \dim_set_eq:Nc \l_@@_xb_dim {pgf@x}
  \dim_set_eq:Nc \l_@@_yb_dim {pgf@y}
%    \end{macrocode}
% Now rotate so that the \(x\)--axis lies along the edge.
%    \begin{macrocode}
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\l_@@_xb_dim}{-\l_@@_yb_dim}}
    {\pgfpoint{\l_@@_yb_dim}{\l_@@_xb_dim}}

  \pgftransformshift{\pgfpoint{-\l_@@_xa_dim}{-\l_@@_ya_dim}}

}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\cs_generate_variant:Nn \tl_if_eq:nnT {nVT}
\cs_generate_variant:Nn \@@_transform_side:nn {nx,nV}
%    \end{macrocode}
%
% \begin{macro}[internal]{\TransformAlongSide}
% Make this available outside the \LaTeX3 environment.
%    \begin{macrocode}
\DeclareDocumentCommand \TransformAlongSide {m m}
{
  \@@_transform_side:nx {#1}{#2}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_coordinates_at_vertices:n}
% This places TikZ coordinates at the vertices of the tile.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_coordinates_at_vertices:n #1
{
%    \end{macrocode}
% Get our tile data
%    \begin{macrocode}
  \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl
%    \end{macrocode}
% Start with the edge list
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
%    \end{macrocode}
% Get the coordinate list
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpa_tl}
%    \end{macrocode}
% Strip off the outer braces
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl
  {\tl_item:Nn \l_@@_tmpc_tl {1}}
%    \end{macrocode}
% Add the first coordinate at the end
%    \begin{macrocode}
  \tl_put_right:Nx \l_@@_tmpc_tl
  {{\tl_item:Nn \l_@@_tmpc_tl {1}}}
%    \end{macrocode}
% Get the first coordinate
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpa_tl {\tl_head:N \l_@@_tmpc_tl}
  \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
%    \end{macrocode}
% Iterate through the path type list, looking for the requested path
%    \begin{macrocode}
  \tl_map_inline:Nn \l_@@_tmpb_tl {
    \tl_set:Nx \l_@@_tmpd_tl {
      \exp_not:N \coordinate
      (-edge~ ##1~ start)~ at \tl_use:N \l_@@_tmpa_tl;
    }
    \tl_use:N \l_@@_tmpd_tl
    \tl_set:Nx \l_@@_tmpa_tl {\tl_head:N \l_@@_tmpc_tl}
    \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
    \tl_set:Nx \l_@@_tmpd_tl {
      \exp_not:N \coordinate
      (-edge~ ##1~ end)~ at \tl_use:N \l_@@_tmpa_tl;
    }
    \tl_use:N \l_@@_tmpd_tl
  }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\CoordinatesAtVertices}
% User-accessible wrapper around the above.
%    \begin{macrocode}
\DeclareDocumentCommand \CoordinatesAtVertices {m}
{
  \@@_coordinates_at_vertices:n {#1}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{function}{\DefineTile}
% This is the user function for defining a tile.
%    \begin{macrocode}
\DeclareDocumentCommand \DefineTile { m m m }
{
%    \end{macrocode}
% Clear the temporary variable.
%    \begin{macrocode}  
  \tl_clear:N \l_@@_tmpa_tl
%    \end{macrocode}
% The 3rd parameter is a list of coordinates at vertices, iterate through them and add them to the list.
%    \begin{macrocode}  
  \tl_map_inline:nn {#3} {
    \@@_add_coordinate:w \l_@@_tmpa_tl ##1 \q_stop
  }
%    \end{macrocode}
% Now we make a list of the edge types (from the 2nd parameter), using a prop to keep track of whether an edge is repeated.
%    \begin{macrocode}
  \prop_clear:N \l_@@_tmpa_prop
  \tl_map_inline:nn {#2} {
    \prop_if_in:NnTF \l_@@_tmpa_prop {##1}
    {
      \prop_put:Nnn \l_@@_tmpa_prop {##1} {1}
    }
    {
      \prop_put:Nnn \l_@@_tmpa_prop {##1} {0}
    }
  }
%    \end{macrocode}
% Having established their multiplicity, we now create the edges with their names, appending numbers to their names if used more than once.
%    \begin{macrocode}
  \tl_clear:N \l_@@_tmpb_tl
  \tl_map_inline:nn {#2}
  {
    \tl_clear:N \l_@@_tmpc_tl
    \tl_put_right:Nn \l_@@_tmpc_tl {##1}
    \int_compare:nF {\prop_item:Nn \l_@@_tmpa_prop {##1} == 0} {
      \tl_put_right:Nx \l_@@_tmpc_tl
      {\prop_item:Nn \l_@@_tmpa_prop {##1}}
      \prop_put:Nnx \l_@@_tmpa_prop {##1}
      {\int_eval:n {\prop_item:Nn \l_@@_tmpa_prop {##1} + 1}}
    }
    \tl_put_right:Nx \l_@@_tmpb_tl {{ \l_@@_tmpc_tl }}
  }
%    \end{macrocode}
% Finally, we can create our tile and add it to the global tile prop.
%    \begin{macrocode}
  \prop_gput:Nnx \g_@@_tiles_prop {#1}
  {{\tl_use:N \l_@@_tmpb_tl} {\tl_use:N \l_@@_tmpa_tl}}
%    \end{macrocode}
% Having created the tile, we make a TikZ pic to place it on the page.
%    \begin{macrocode}
  \tikzset{
    #1/.pic={
      \begin{scope}
%    \end{macrocode}
% Were we given a tile to align ourselves against?
%    \begin{macrocode}
      \pgfkeysgetvalue{/tikz/Penrose/alignment~ location}{\prloc}
      \ifx\prloc\pgfutil@empty
      \else
%    \end{macrocode}
% Yes, we were.
% So we adjust our position accordingly.
% The first job is to transform so that we're along the edge of the receiving tile.
%    \begin{macrocode}
    \begingroup
%    \end{macrocode}
% We get the locations of the start and end of the receiving tile.
% As \Verb+pic+ sets the node prefix, we have to temporarily suspend that (hence working in a group).
%    \begin{macrocode}
      \tikzset{name~ prefix~ ..}%
      \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge~ \pgfkeysvalueof{/tikz/Penrose/alignment~ edge}~ start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge~ \pgfkeysvalueof{/tikz/Penrose/alignment~ edge}~ end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
      \endgroup
%    \end{macrocode}
% We store the initial points in \Verb+\pgf@xa+ and \Verb+\pgf@ya+ but we want \Verb+\pgf@xb+ and \Verb+\pgf@yb+ to be a vector along the edge.
%    \begin{macrocode}
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
%    \end{macrocode}
% We shift to the start of the edge.
%    \begin{macrocode}
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
%    \end{macrocode}
% And normalise the vector along it.
%    \begin{macrocode}
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
%    \end{macrocode}
% Now rotate so that the \(x\)--axis lies along the edge.
%    \begin{macrocode}
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}
%    \end{macrocode}
% The next job is to shift and rotate the current tile so that the correct edge ends up against the receiving tile.
%    \begin{macrocode}
    \str_set:Nx \l_@@_tmpa_str
    {\pgfkeysvalueof{/tikz/Penrose/alignment~ edge}}
    \str_set:Nx \l_@@_tmpa_str {\str_head:N \l_@@_tmpa_str}
    \str_put_right:Nx \l_@@_tmpa_str
    {\pgfkeysvalueof{/tikz/Penrose/alignment~ new~ edge}}
    \str_set:Nx \l_@@_tmpb_str {\str_lowercase:f { \l_@@_tmpa_str}}
    \str_if_eq:NNT \l_@@_tmpa_str \l_@@_tmpb_str
    {
      \str_set:Nx \l_@@_tmpb_str
      {\str_uppercase:f { \l_@@_tmpa_str}}
    }

    \@@_transform_side:nV {#1} \l_@@_tmpb_str
    \fi
%    \end{macrocode}
% Now that the transformation is finalised, we can render the tile.
% We clip against the tile path so that the tiles don't ``bleed''.
% If we didn't do this, drawing the tile would result in overlaps which can look a bit ugly.
% On the other hand, tight clipping can lead to ``gaps'' between the tiles so we make this optional by enclosing it in a style.
%    \begin{macrocode}
    \UsePenroseTile[
      every~ Penrose~ tile~ clip/.try,
      every~ #1~ clip/.try
    ]{#1}
    \UsePenroseTile[
      every~ Penrose~ tile/.try,
      every~ #1/.try,
      pic~ actions
    ]{#1}
% Lastly, we put coordinates at each vertex, labelled by which edge they are.
%    \begin{macrocode}
    \@@_coordinates_at_vertices:n {#1}
    \end{scope}
    },
%    \end{macrocode}
% This is a shortcut for installing the \Verb+pic+ type.
%    \begin{macrocode}
  #1/.style={
    every~ Penrose~ pic/.try,
    pic~ type=#1,
    },
  }
}
%    \end{macrocode}
% \end{function}
%
%
% \subsection{Lindenmayer System}
% 
% This is an implementation of the Lindenmayer System description of Penrose tilings as a way of generating tilings from a specific starting seed.
%
% The implementation uses \Verb+prop+s to store \emph{rules} and \emph{actions}.
% The rules are used to expand the starting seed to a certain level, after which the actions are carried out.
% The syntax is based on the PGF library, but as we're already using \LaTeX3 it is reimplemented in that.
%
% These are the rules for generating rhombus tilings.
%    \begin{macrocode}
\prop_new:N \g_@@_rhombus_lms_rule_prop
\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {T} {[f*sT][f>g]}
\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {t} {[f_st][f>G]}
\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {G} {[f+sG][sf>g][sf*sT]}
\prop_gput:Nnn \g_@@_rhombus_lms_rule_prop {g} {[f-sg][sf>G][sf_st]}
%    \end{macrocode}
%
% These are the rules for generating kite and dart tilings.
%    \begin{macrocode}
\prop_new:N \g_@@_kite_lms_rule_prop
\prop_gput:Nnn \g_@@_kite_lms_rule_prop {T} {[f*sT][f>st][+sg]}
\prop_gput:Nnn \g_@@_kite_lms_rule_prop {t} {[f_st][f>sT][-sG]}
\prop_gput:Nnn \g_@@_kite_lms_rule_prop {G} {[f*+sG][sT]}
\prop_gput:Nnn \g_@@_kite_lms_rule_prop {g} {[f-_sg][st]}
%    \end{macrocode}
%
% These are the rules for generating pentagon tilings.
%    \begin{macrocode}
\prop_new:N \g_@@_pentagon_lms_rule_prop
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {P}
{[s>P][1sF+Q][1+sF+Q][1*sF+Q][1-sF+Q][1_sF+Q]} % pentagon 5
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {Q}
{[s>P][1+sFR][1*sF*R][1-sF+Q][1_sF+Q][1sF+Q][->fsD]} % pentagon 3
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {R}
{[s>P][1-sF+Q][1+sF*R][1*sFR][1_sF*R][1sFR][_>fsD][>fsD]} % pentagon 2
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {G}
{
  [s>G]
  [se[>d+R][e1B]]
  [+se[>d+R][e1B]]
  [-se[>d+R][e1B]]
  [*se[>d+R][e1B]]
  [_se[>d+R][e1B]]
} % pentagram
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {B}
{
  [s>G]
  [se[>d+R][e1B]]
  [+se[>d+R][e1B]]
  [-se[>d+R][e1B]]
} % boat
\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {D}
{[s>d+R][s>eG][se1B]} % diamond
%    \end{macrocode}
%
% Each of the standard tilings can also be drawn using triangles using the same rules.
%    \begin{macrocode}
\prop_gset_eq:NN \g_@@_rtriangle_lms_rule_prop
\g_@@_rhombus_lms_rule_prop
\prop_gset_eq:NN \g_@@_ktriangle_lms_rule_prop
\g_@@_kite_lms_rule_prop
%    \end{macrocode}
%
% These hold the various actions.
%    \begin{macrocode}
\prop_new:N \g_@@_default_lms_action_prop
\prop_new:N \g_@@_rhombus_lms_action_prop
\prop_new:N \g_@@_kite_lms_action_prop
\prop_new:N \g_@@_rtriangle_lms_action_prop
\prop_new:N \g_@@_ktriangle_lms_action_prop
\prop_new:N \g_@@_pentagon_lms_action_prop
%    \end{macrocode}
%
% We need some parameters.
%    \begin{macrocode}
\dim_new:N \l_@@_step_dim
\dim_set:Nn \l_@@_step_dim {1cm}
%    \end{macrocode}
%
% These are the defaults, which will be used in all the rule sets.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_default_lms_action_prop {[} {\group_begin:}
\prop_gput:Nnn \g_@@_default_lms_action_prop {]} {\group_end:}
\prop_gput:Nnn \g_@@_default_lms_action_prop {f}
{\pgftransformxshift{\l_@@_step_dim}}
\prop_gput:Nnn \g_@@_default_lms_action_prop {s} {
  \fp_set:Nn \l_@@_tmpa_fp { 2 * sind(18) * \l_@@_step_dim }
  \dim_set:Nn \l_@@_step_dim {\fp_to_dim:N \l_@@_tmpa_fp}
}
%    \end{macrocode}
%
% The rhombus rules need a variety of turns.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {+}
{\pgftransformrotate{144}}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {*}
{\pgftransformrotate{108}}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {-}
{\pgftransformrotate{216}}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {_}
{\pgftransformrotate{252}}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {>}
{\pgftransformrotate{180}}
%    \end{macrocode}
%
% Up to now, the actions for the rhombus and its triangle replacement are the same.
%    \begin{macrocode}
\prop_gset_eq:NN \g_@@_rtriangle_lms_action_prop
\g_@@_rhombus_lms_action_prop
%    \end{macrocode}
%
% Now we do the actions that actually draw something.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {T} {
  \group_begin:
%    \end{macrocode}
% As we go through, we keep track of how many tiles we've drawn.
%    \begin{macrocode}
  \int_gincr:N \g_@@_tile_int
%    \end{macrocode}
% Set up the position, size, and angle correctly.
%    \begin{macrocode}
  \pgftransformrotate{198}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*2*cosd(18)}
  \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
%    \end{macrocode}
% Now we draw the thin rhombus, applying every style we can possibly imagine.
% The \Verb+Penrose tile+ style gets the current tile and total tile numbers passed to it.
%    \begin{macrocode}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ thin~ rhombus/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{thin~rhombus}
  \group_end:
}
%    \end{macrocode}
%
% Same for the thick rhombus.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {G} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ thick~ rhombus/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{thick~rhombus}
  \group_end:
}
%    \end{macrocode}
%
% Now we do the same for the kite and dart tiling.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {+} {\pgftransformrotate{36}}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {*} {\pgftransformrotate{108}}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {-} {\pgftransformrotate{-36}}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {_}
{\pgftransformrotate{-108}}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {>} {\pgftransformrotate{180}}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gset_eq:NN \g_@@_ktriangle_lms_action_prop
\g_@@_kite_lms_action_prop
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {T} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{36}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ kite/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{kite}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_kite_lms_action_prop {g} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{144}
  \pgftransformxshift{-\l_@@_step_dim * 2 * sin(18)}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ dart/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{dart}
  \group_end:
}
%    \end{macrocode}
%
% Now we set up the actions for the triangle variations.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {T} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{18}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ reverse~ golden~ triangle/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{reverse~ golden~ triangle}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {t} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{-18}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ golden~ triangle/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{golden~ triangle}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {G} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{180}
  \pgftransformxshift{-\l_@@_step_dim}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ reverse~ golden~ gnomon/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{reverse~ golden~ gnomon}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {g} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{180}
  \pgftransformxshift{-\l_@@_step_dim}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ golden~ gnomon/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{golden~ gnomon}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {T} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{18}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ reverse~ golden~ triangle/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{reverse~ golden~ triangle}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {t} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{-18}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ golden~ triangle/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{golden~ triangle}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {G} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{180}
  \pgftransformxshift{-\l_@@_step_dim}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ reverse~ golden~ gnomon/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{reverse~ golden~ gnomon}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {g} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{180}
  \pgftransformxshift{-\l_@@_step_dim}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)/(2*cosd(36))}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ golden~ gnomon/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{golden~ gnomon}
  \group_end:
}
%    \end{macrocode}
%
% Now we do the same for the pentagonal tilings.
%
% The rules need a variety of turns.
%    \begin{macrocode}
\int_new:N \l_@@_pentagon_parity_int
\seq_new:N \l_@@_pentagon_parity_seq
\seq_set_from_clist:Nn \l_@@_pentagon_parity_seq {odd,even}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {1} {
  \int_set:Nn \l_@@_pentagon_parity_int
  {3 -  \l_@@_pentagon_parity_int}
  }
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {+}
{\pgftransformrotate{72}}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {*}
{\pgftransformrotate{144}}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {-}
{\pgftransformrotate{288}}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {_}
{\pgftransformrotate{216}}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {>}
{\pgftransformrotate{180}}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {|}
{\pgftransformxscale{-1}}
%    \end{macrocode}
% The scale factor is different.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {s} {
  \fp_set:Nn \l_@@_tmpa_fp
  {
    1/(2 + 2 * cosd(72) ) * \l_@@_step_dim
  }
  \dim_set:Nn \l_@@_step_dim {\fp_to_dim:N \l_@@_tmpa_fp}
}
%    \end{macrocode}
% And we tend to work better vertically.
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {f} {
  \fp_set:Nn \l_@@_tmpa_fp {  tand(54)/2 * \l_@@_step_dim }
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {F} {
  \fp_set:Nn \l_@@_tmpa_fp {  tand(54) * \l_@@_step_dim }
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {d} {
  \fp_set:Nn \l_@@_tmpa_fp
  {
    (tand(54)/2 - tand(72)/2 + sind(36) ) * \l_@@_step_dim
  }
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {e} {
  \fp_set:Nn \l_@@_tmpa_fp
  {
    tand(54) * cosd(36) * \l_@@_step_dim
  }
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {P} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
  \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
  \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ pentagon/.try,
    every~
    \seq_item:Nn \l_@@_pentagon_parity_seq
    {\l_@@_pentagon_parity_int}
    \space pentagon/.try,
    every~ pentagon~ 5/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{pentagon~5}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {Q} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
  \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
  \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ pentagon/.try,
    every~
    \seq_item:Nn \l_@@_pentagon_parity_seq
    {\l_@@_pentagon_parity_int}
    \space pentagon/.try,
    every~ pentagon~ 3/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{pentagon~3}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {R} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/2}
  \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)/2}
  \pgftransformyshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ pentagon/.try,
    every~
    \seq_item:Nn \l_@@_pentagon_parity_seq
    {\l_@@_pentagon_parity_int}
    \space pentagon/.try,
    every~ pentagon~ 2/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{pentagon~2}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {G} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
%  \pgftransformrotate{198}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(72)}
  \pgftransformxshift{\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)*cosd(72)}
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ pentagram/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{pentagram}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {B} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
%  \pgftransformrotate{198}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(72)}
  \pgftransformxshift{\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*tand(54)*cosd(72)}
  \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ boat/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{boat}
  \group_end:
}
%    \end{macrocode}
%
%    \begin{macrocode}
\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {D} {
  \group_begin:
  \int_gincr:N \g_@@_tile_int
  \pgftransformrotate{90}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim*cosd(18)}
  \pgftransformxshift{-\fp_to_dim:N \l_@@_tmpa_fp}
  \fp_set:Nn \l_@@_tmpa_fp {\l_@@_step_dim/(1cm)}
  \pgftransformscale{\fp_use:N \l_@@_tmpa_fp}
  \tl_set:Nx \l_@@_tmpc_tl
  {
    {\int_use:N  \g_@@_tile_int}
    {\int_use:N \g_@@_tiles_int}
  }
  \UsePenroseTile[
    every~ Penrose~ tile/.try,
    every~ diamond/.try,
    Penrose~ tile~ \int_use:N \g_@@_tile_int/.try,
    Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl
  ]{diamond}
  \group_end:
}
%    \end{macrocode}
%
% \begin{macro}[internal]{\@@_make_lms:Nnnn}
% This creates the token list of actions, starting with the seed.
% The arguments are: a token list to store the result in, the name of the system, the number of iterations, and the initial state.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_make_lms:Nnnn #1#2#3#4
{
  \group_begin:
%    \end{macrocode}
% On the first time round, we start with the given seed.
%    \begin{macrocode}
  \tl_set:Nn \l_@@_tmpb_tl {#4}
%    \end{macrocode}
% We repeat the specified number of times.
%    \begin{macrocode}
  \prg_replicate:nn {#3} {
%    \end{macrocode}
% Duplicate the current state.
%    \begin{macrocode}
    \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmpb_tl
%    \end{macrocode}
% Clear the receiving token list.
%    \begin{macrocode}
    \tl_clear:N \l_@@_tmpb_tl
%    \end{macrocode}
% Walk through the current list, appending to the receiving list according to the rules.
%    \begin{macrocode}
    \tl_map_inline:Nn \l_@@_tmpa_tl
    {
%    \end{macrocode}
% If a rule exists, copy that.
%    \begin{macrocode}
      \prop_if_in:cnTF {g_@@_#2_lms_rule_prop} {##1}
      {
        \tl_put_right:Nx \l_@@_tmpb_tl
        {\prop_item:cn {g_@@_#2_lms_rule_prop} {##1} }
      }
      {
%    \end{macrocode}
% Otherwise, just copy the token.
%    \begin{macrocode}
        \tl_put_right:Nn \l_@@_tmpb_tl {##1}
      }
    }
  }
%    \end{macrocode}
% We've done all this inside a group, now pass the result outside.
%    \begin{macrocode}
  \tl_set:Nn \l_@@_tmpa_tl {
    \group_end:
    \tl_set:Nn #1
  }
  \tl_put_right:Nx \l_@@_tmpa_tl {{\tl_use:N \l_@@_tmpb_tl}}
  \tl_use:N \l_@@_tmpa_tl
}
\cs_generate_variant:Nn \@@_make_lms:Nnnn {Nnnx}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_invoke_lms:Nn}
% This carries out the actions specified by the resulting rules.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_invoke_lms:Nn #1#2
{
  \group_begin:
%    \end{macrocode}
% Walk through the given list, carrying out the corresponding action if it exists.
% If not, look at the default.
% Otherwise, just do nothing.
%    \begin{macrocode}
  \tl_map_inline:Nn #1 {
    \prop_if_in:cnTF {g_@@_#2_lms_action_prop} {##1}
    {
      \prop_item:cn {g_@@_#2_lms_action_prop} {##1}
    }
    {
      \prop_if_in:cnT {g_@@_default_lms_action_prop} {##1}
      {
        \prop_item:cn {g_@@_default_lms_action_prop} {##1}
      }
    }
  }
  \group_end:
}
%    \end{macrocode}
% \end{macro}
%
% We keep track of the number of tiles.
%    \begin{macrocode}
\int_new:N \g_@@_tile_int
\int_new:N \g_@@_tiles_int
%    \end{macrocode}
%
% \begin{function}{\PenroseDecomposition}
% This is the user macro to invoke the decomposition.
% The arguments are: optional styles, the name, number of iterations, and starting seed.
%    \begin{macrocode}
\NewDocumentCommand \PenroseDecomposition { O{} m m m }
{
  \group_begin:
  \tikzset{#1}
  \@@_make_lms:Nnnx \l_@@_tmpa_tl {#2} {#3} {#4}
  \@@_count_lms:N \l_@@_tmpa_tl
  \int_gzero:N \g_@@_tile_int
  \int_set:Nn \l_@@_pentagon_parity_int {2}
  \@@_invoke_lms:Nn \l_@@_tmpa_tl {#2}
  \group_end:
}
%    \end{macrocode}
% \end{function}
%
% \begin{macro}[internal]{\@@_count_lms:N}
% This counts the number of tiles in the string.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_count_lms:N #1
{
  \int_gzero:N \g_@@_tiles_int
  \tl_map_inline:Nn #1
  {
    \tl_if_eq:nnT {##1} {T}
    {
      \int_gincr:N \g_@@_tiles_int
    }
    \tl_if_eq:nnT {##1} {t}
    {
      \int_gincr:N \g_@@_tiles_int
    }
    \tl_if_eq:nnT {##1} {G}
    {
      \int_gincr:N \g_@@_tiles_int
    }
    \tl_if_eq:nnT {##1} {g}
    {
      \int_gincr:N \g_@@_tiles_int
    }
  }
}
%    \end{macrocode}
% \end{macro}
%
% This is a \Verb+\tikzset+ mechanism for setting the dimensions of the tiling.
%    \begin{macrocode}
\tikzset{
  Penrose~ step/.code={
    \dim_set:Nn \l_@@_step_dim {#1}
  }
}
%    \end{macrocode}
%
% We're done with \LaTeX3, so turn off the syntax.
%    \begin{macrocode}
\ExplSyntaxOff
%    \end{macrocode}
%
% \subsection{TikZ Pictures}
%
% New in TikZ3.0 is the ability to make pictures that can be reused.
% Penrose tiles seems an obvious use for this.
% These pictures can be placed alongside other tiles, matching by edge type.
%
% There are a variety of constants that are frequently used and reused, so we define them all here.
% These are the PGF versions.
%
%    \begin{macrocode}
\pgfmathsetmacro\pr@chphi{cos(18)}
\pgfmathsetmacro\pr@shphi{sin(18)}
\pgfmathsetmacro\pr@cphi{cos(36)}
\pgfmathsetmacro\pr@sphi{sin(36)}
\pgfmathsetmacro\pr@invphi{2/(sqrt(5)+1)}
\pgfmathsetmacro\pr@phi{(sqrt(5)+1)/2}
\pgfmathsetmacro\pr@invphisq{\pr@invphi*\pr@invphi}
\pgfmathsetmacro\pr@ominvphisq{\pr@invphi - \pr@invphisq}
\pgfmathsetmacro\pr@ominvphi{1 - \pr@invphi}
%    \end{macrocode}
%
%    \begin{macrocode}
\newif\if@edgealign
\def\pr@getfirst#1#2\pr@stop{#1}%
\def\test@edgealign#1{%
  \pgfkeysgetvalue{/tikz/Penrose/alignment edge}{\@penrose@tmpa}%
  \edef\@penrose@tmpb{#1}%
  \edef\@penrose@tmpa{\expandafter\pr@getfirst\@penrose@tmpa.\pr@stop}%
  \ifx\@penrose@tmpa\@penrose@tmpb
  \@edgealigntrue
  \else
  \@edgealignfalse
  \fi
}%
%    \end{macrocode}
%
%    \begin{macrocode}
\newif\if@newedge
\def\test@newedge#1{%
  \pgfkeysgetvalue{/tikz/Penrose/alignment new edge}{\@penrose@tmpa}%
  \edef\@penrose@tmpb{#1}%
  \edef\@penrose@tmpa{\@penrose@tmpa}%
  \ifx\@penrose@tmpa\@penrose@tmpb
  \@newedgetrue
  \else
  \@newedgefalse
  \fi
}%
%    \end{macrocode}
%
% The implementation is essentially the same for each, so only the first will be commented.
%    \begin{macrocode}
\tikzset{
%    \end{macrocode}
% The key \Verb+align with=<tile> along <edge>+ is used to set the parameters for placing a tile next to an existing one.
% For most tiles, that's enough to specify how the new tile should be placed.
% Some, though, need more information.
% For those, use \Verb+align with=<tile> along <edge> using <number>+. 
%    \begin{macrocode}
  align with/.code args={#1 along #2}{%
    \pgfutil@in@{ using }{#2}
    \ifpgfutil@in@%
    \tikzset{
      Penrose/alignment location=#1,
      Penrose/alignment set edges=#2,
    }%
    \else
    \tikzset{
      Penrose/alignment location=#1,
      Penrose/alignment edge=#2,
    }%
    \fi
  },
  Penrose/alignment set edges/.code args={#1 using #2}{%
    \tikzset{
      Penrose/alignment edge=#1,
      Penrose/alignment new edge=#2
    },
  },
  Penrose/alignment location/.initial={},
  Penrose/alignment edge/.initial=a,
  Penrose/alignment new edge/.initial={},
%    \end{macrocode}
% Default clipping style.
%    \begin{macrocode}
  every Penrose tile clip/.style={clip},
%    \end{macrocode}
% This is the code for setting up a \Verb+pic+.
%    \begin{macrocode}
  thin rhombus/.pic={
    \begin{scope}
%    \end{macrocode}
% Were we given a tile to align ourselves against?
%    \begin{macrocode}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
%    \end{macrocode}
% Yes, we were.
% So we adjust our position accordingly.
% The first job is to transform so that we're along the edge of the receiving tile.
%    \begin{macrocode}
    \begingroup
%    \end{macrocode}
% We get the locations of the start and end of the receiving tile.
% As \Verb+pic+ sets the node prefix, we have to temporarily suspend that (hence working in a group).
%    \begin{macrocode}
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
%    \end{macrocode}
% We store the initial points in \Verb+\pgf@xa+ and \Verb+\pgf@ya+ but we want \Verb+\pgf@xb+ and \Verb+\pgf@yb+ to be a vector along the edge.
%    \begin{macrocode}
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
%    \end{macrocode}
% We shift to the start of the edge.
%    \begin{macrocode}
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
%    \end{macrocode}
% And normalise the vector along it.
%    \begin{macrocode}
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
%    \end{macrocode}
% Now rotate so that the \(x\)--axis lies along the edge.
%    \begin{macrocode}
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}
%    \end{macrocode}
% The next job is to shift and rotate the current tile so that the correct edge ends up against the receiving tile.
%    \begin{macrocode}
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}b\relax
    \pgftransformrotate{-18}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{\pr@shphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}B\relax
    \pgftransformrotate{18}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \pgftransformrotate{198}%
    \pgftransformshift{\pgfpoint{-2*\pr@chphi cm}{0 cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{162}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{-\pr@shphi cm}}%
    \fi\fi\fi\fi
    \fi
%    \end{macrocode}
% Now that the transformation is finalised, we can render the tile.
% We clip against the tile path so that the tiles don't ``bleed''.
% If we didn't do this, drawing the tile would result in overlaps which can look a bit ugly.
% On the other hand, tight clipping can lead to ``gaps'' between the tiles so we make this optional by enclosing it in a style.
%    \begin{macrocode}
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every thin rhombus clip/.try
    ]{thin rhombus}
    \UsePenroseTile[
      every Penrose tile/.try,
      every thin rhombus/.try,
      pic actions
    ]{thin rhombus}
%    \end{macrocode}
% These draw the arcs that designate the joining rules.
% We draw full circles so that it doesn't matter what shape the tiles are.
%    \begin{macrocode}
    \UsePenroseTile[
      every Penrose arc clip/.try,
      every thin rhombus arc clip/.try
    ]{thin rhombus}
    \path[every circle arc/.try] (18:1) circle[radius=1/4];
    \path[every long arc/.try] (-18:1) circle[radius=1/4];
%    \end{macrocode}
% Lastly, we put coordinates at each vertex, labelled by which edge they are.
%    \begin{macrocode}
\coordinate (-edge a start) at (0,0);
\coordinate (-edge a end) at (18:1);
\coordinate (-edge A start) at (18:1);
\coordinate (-edge A end) at (2*\pr@chphi,0);
\coordinate (-edge B start) at (2*\pr@chphi,0);
\coordinate (-edge B end) at (-18:1);
\coordinate (-edge b start) at (-18:1);
\coordinate (-edge b end) at (0,0);
    \end{scope}
  },
%    \end{macrocode}
% This is a shortcut for installing the \Verb+pic+ type.
%    \begin{macrocode}
  thin rhombus/.style={
    every Penrose pic/.try,
    pic type=thin rhombus,
  },
%    \end{macrocode}
% Same again, but for the thick rhombus.
%    \begin{macrocode}
  thick rhombus/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}b\relax
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{-\pr@sphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}B\relax
    \pgftransformrotate{36}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \pgftransformrotate{-36}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{216}%
    \pgftransformshift{\pgfpoint{-2*\pr@cphi cm}{0 cm}}%
    \fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every thick rhombus clip/.try
    ]{thick rhombus}
    \UsePenroseTile[
      every Penrose tile/.try,
      every thick rhombus/.try,
      pic actions
    ]{thick rhombus}
    \UsePenroseTile[
      every Penrose arc clip/.try,
      every thick rhombus arc clip/.try
    ]{thick rhombus}
\path[every circle arc/.try] (2*\pr@cphi,0) circle[radius=1/4];
\path[every long arc/.try] (0,0) circle[radius=3/4];
\coordinate (-edge B start) at (0,0);
\coordinate (-edge B end) at (36:1);
\coordinate (-edge a start) at (36:1);
\coordinate (-edge a end) at (2*\pr@cphi,0);
\coordinate (-edge A start) at (2*\pr@cphi,0);
\coordinate (-edge A end) at (-36:1);
\coordinate (-edge b start) at (-36:1);
\coordinate (-edge b end) at (0,0);
    \end{scope}
  },
  thick rhombus/.style={
    every Penrose pic/.try,
    pic type=thick rhombus,
  },
%    \end{macrocode}
% Now the kite.
%    \begin{macrocode}
  kite/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}c\relax
    \pgftransformrotate{-72}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}C\relax
    \pgftransformrotate{-108}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \pgftransformrotate{36}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{-\pr@sphi cm}}%
    \fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every kite clip/.try
    ]{kite}
    \UsePenroseTile[
      every Penrose tile/.try,
      every kite/.try,
      pic actions
    ]{kite}
    \UsePenroseTile[
      every Penrose arc clip/.try,
      every kite arc clip/.try
    ]{kite}
\path[every circle arc/.try] (0,0) circle[radius=\pr@invphi];
\path[every long arc/.try] (1,0) circle[radius=\pr@invphisq];
\coordinate (-edge a start) at (0,0);
\coordinate (-edge a end) at (36:1);
\coordinate (-edge c start) at (36:1);
\coordinate (-edge c end) at (1,0);
\coordinate (-edge C start) at (1,0);
\coordinate (-edge C end) at (-36:1);
\coordinate (-edge A start) at (-36:1);
\coordinate (-edge A end) at (0,0);
    \end{scope}
  },
%    \end{macrocode}
% The dart is next.
%    \begin{macrocode}
  dart/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}c\relax
    \pgftransformrotate{108}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}C\relax
    \pgftransformrotate{72}%
    \pgftransformshift%
    {\pgfpoint{\pr@invphi*\pr@shphi cm}{-\pr@invphi*\pr@chphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \pgftransformrotate{-36}%
    \pgftransformshift%
    {\pgfpoint{\pr@invphi*\pr@shphi cm}{\pr@invphi*\pr@chphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{216}%
    \pgftransformshift{\pgfpoint{-\pr@invphi cm}{0 cm}}%
    \fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every dart clip/.try
    ]{dart}
    \UsePenroseTile[
      every Penrose tile/.try,
      every dart/.try,
      pic actions
    ]{dart}
    \UsePenroseTile[
      every Penrose arc clip/.try,
      every dart arc clip/.try
    ]{dart}
\path[every circle arc/.try] (\pr@invphi,0) circle[radius=\pr@ominvphi];
\path[every long arc/.try] (0,0) circle[radius=\pr@ominvphisq];
\coordinate (-edge c start) at (0,0);
\coordinate (-edge c end) at (108:\pr@invphi);
\coordinate (-edge a start) at (108:\pr@invphi);
\coordinate (-edge a end) at (\pr@invphi,0);
\coordinate (-edge A start) at (\pr@invphi,0);
\coordinate (-edge A end) at (-108:\pr@invphi);
\coordinate (-edge C start) at (-108:\pr@invphi);
\coordinate (-edge C end) at (0,0);
    \end{scope}
  },
  kite/.style={
    every Penrose pic/.try,
    pic type=kite,
  },
  dart/.style={
    every Penrose pic/.try,
    pic type=dart,
  },
%    \end{macrocode}
% The golden triangle.
%    \begin{macrocode}
  golden triangle/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}B\relax
    \pgftransformrotate{18}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}C\relax
    \pgftransformrotate{-90}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{\pr@shphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{162}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{-\pr@shphi cm}}%
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every golden triangle clip/.try
    ]{golden triangle}
    \UsePenroseTile[
      every Penrose tile/.try,
      every golden triangle/.try,
      pic actions
    ]{golden triangle}
\coordinate (-edge a start) at (0,0);
\coordinate (-edge a end) at (18:1);
\coordinate (-edge c start) at (18:1);
\coordinate (-edge c end) at (-18:1);
\coordinate (-edge b start) at (-18:1);
\coordinate (-edge b end) at (0,0);
    \end{scope}
  },
  golden triangle/.style={
    every Penrose pic/.try,
    pic type=golden triangle,
  },
%    \end{macrocode}
% The reverse golden triangle (is there a better name?).
%    \begin{macrocode}
  reverse golden triangle/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}b\relax
    \pgftransformrotate{162}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{-\pr@shphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}c\relax
    \pgftransformrotate{-90}%
    \pgftransformshift{\pgfpoint{-\pr@chphi cm}{\pr@shphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \pgftransformrotate{18}%
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every reverse golden triangle clip/.try
    ]{reverse golden triangle}
    \UsePenroseTile[
      every Penrose tile/.try,
      every reverse golden triangle/.try,
      pic actions
    ]{reverse golden triangle}
\coordinate (-edge B start) at (0,0);
\coordinate (-edge B end) at (18:1);
\coordinate (-edge C start) at (18:1);
\coordinate (-edge C end) at (-18:1);
\coordinate (-edge A start) at (-18:1);
\coordinate (-edge A end) at (0,0);
    \end{scope}
  },
  reverse golden triangle/.style={
    every Penrose pic/.try,
    pic type=reverse golden triangle,
  },
%    \end{macrocode}
% The golden gnomon.
%    \begin{macrocode}
  golden gnomon/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}c\relax
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{-\pr@sphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}B\relax
    \pgftransformrotate{-144}%
    \pgftransformshift{\pgfpoint{-2*\pr@cphi cm}{0 cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}a\relax
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every golden gnomon clip/.try
    ]{golden gnomon}
    \UsePenroseTile[
      every Penrose tile/.try,
      every golden gnomon/.try,
      pic actions
    ]{golden gnomon}
\coordinate (-edge C start) at (0,0);
\coordinate (-edge C end) at (36:1);
\coordinate (-edge b start) at (36:1);
\coordinate (-edge b end) at (2*\pr@cphi,0);
\coordinate (-edge A start) at (2*\pr@cphi,0);
\coordinate (-edge A end) at (0,0);
    \end{scope}
  },
  golden gnomon/.style={
    every Penrose pic/.try,
    pic type=golden gnomon,
  },
%    \end{macrocode}
% The reverse golden gnomon.
%    \begin{macrocode}
  reverse golden gnomon/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}C\relax
    \pgftransformrotate{36}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}b\relax
    \pgftransformrotate{-36}%
    \pgftransformshift{\pgfpoint{-\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \if\pgfkeysvalueof{/tikz/Penrose/alignment edge}A\relax
    \pgftransformrotate{180}%
    \pgftransformshift{\pgfpoint{-2*\pr@cphi cm}{0 cm}}%
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every reverse golden gnomon clip/.try
    ]{reverse golden gnomon}
    \UsePenroseTile[
      every Penrose tile/.try,
      every reverse golden gnomon/.try,
      pic actions
    ]{reverse golden gnomon}
\coordinate (-edge a start) at (0,0);
\coordinate (-edge a end) at (2*\pr@cphi,0);
\coordinate (-edge B start) at (2*\pr@cphi,0);
\coordinate (-edge B end) at (-36:1);
\coordinate (-edge c start) at (-36:1);
\coordinate (-edge c end) at (0,0);
    \end{scope}
  },
  reverse golden gnomon/.style={
    every Penrose pic/.try,
    pic type=reverse golden gnomon,
  },
%    \end{macrocode}
% The primary pentagon.
%    \begin{macrocode}
  pentagon 5/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@newedge{1}%
    \if@newedge
    \pgftransformrotate{180}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \test@newedge{2}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm}{0 cm}}%
    \pgftransformrotate{108}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \test@newedge{3}%
    \if@newedge
    \pgftransformshift%
    {\pgfpoint{\pr@phi * \pr@shphi cm}{- \pr@phi * \pr@chphi cm}}%
    \pgftransformrotate{36}%
    \else
    \test@newedge{4}%
    \if@newedge
    \pgftransformshift{\pgfpoint{- \pr@shphi cm}{-\pr@chphi cm}}%
    \pgftransformrotate{-36}%
    \else
    \test@newedge{5}%
    \if@newedge
    \pgftransformrotate{-108}%
    \fi\fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every pentagon clip/.try,
      every pentagon 5 clip/.try
    ]{pentagon 5}
    \UsePenroseTile[
      every Penrose tile/.try,
      every pentagon/.try,
      every pentagon 5/.try,
      pic actions
    ]{pentagon 5}
\coordinate (-edge a1 start) at (0,0);
\coordinate (-edge a1 end) at (1,0);
\coordinate (-edge a2 start) at (1,0);
\coordinate (-edge a2 end) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge a3 start) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge a3 end) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge a4 start) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge a4 end) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge a5 start) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge a5 end) at (0,0);
    \end{scope}
  },
  pentagon 5/.style={
    every Penrose pic/.try,
    pic type=pentagon 5,
  },
%    \end{macrocode}
% The secondary pentagon.
%    \begin{macrocode}
  pentagon 3/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@edgealign{a}%
    \if@edgealign
    \pgftransformrotate{180}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \test@edgealign{B}%
    \if@edgealign%
    \test@newedge{1}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm}{0 cm}}%
    \pgftransformrotate{108}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \pgftransformrotate{-108}%
    \fi
    \else
    \test@newedge{1}%
    \if@newedge
    \pgftransformshift%
    {\pgfpoint{\pr@phi * \pr@shphi cm}{- \pr@phi * \pr@chphi cm}}%
    \pgftransformrotate{36}%
    \else
    \pgftransformshift{\pgfpoint{- \pr@shphi cm}{-\pr@chphi cm}}%
    \pgftransformrotate{-36}%
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every pentagon clip/.try,
      every pentagon 3 clip/.try
    ]{pentagon 3}
    \UsePenroseTile[
      every Penrose tile/.try,
      every pentagon/.try,
      every pentagon 3/.try,
      pic actions
    ]{pentagon 3}
\coordinate (-edge A start) at (0,0);
\coordinate (-edge A end) at (1,0);
\coordinate (-edge b1 start) at (1,0);
\coordinate (-edge b1 end) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge a1 start) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge a1 end) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge a2 start) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge a2 end) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge b2 start) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge b2 end) at (0,0);
    \end{scope}
  },
  pentagon 3/.style={
    every Penrose pic/.try,
    pic type=pentagon 3,
  },
%    \end{macrocode}
% The tertiary pentagon.
%    \begin{macrocode}
  pentagon 2/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@edgealign{D}%
    \if@edgealign
    \pgftransformrotate{180}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \test@edgealign{a}%
    \if@edgealign%
    \test@newedge{1}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm}{0 cm}}%
    \pgftransformrotate{108}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \pgftransformrotate{-108}%
    \fi
    \else
    \test@newedge{1}%
    \if@newedge
    \pgftransformshift%
    {\pgfpoint{\pr@phi * \pr@shphi cm}{- \pr@phi * \pr@chphi cm}}%
    \pgftransformrotate{36}%
    \else
    \pgftransformshift{\pgfpoint{- \pr@shphi cm}{-\pr@chphi cm}}%
    \pgftransformrotate{-36}%
    \fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every pentagon clip/.try,
      every pentagon 2 clip/.try
    ]{pentagon 2}
    \UsePenroseTile[
      every Penrose tile/.try,
      every pentagon/.try,
      every pentagon 2/.try,
      pic actions
    ]{pentagon 2}
\coordinate (-edge d start) at (0,0);
\coordinate (-edge d end) at (1,0);
\coordinate (-edge A1 start) at (1,0);
\coordinate (-edge A1 end) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge c1 start) at (1+\pr@shphi,\pr@chphi);
\coordinate (-edge c1 end) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge c2 start) at (\pr@cphi-\pr@shphi,\pr@sphi+\pr@chphi);
\coordinate (-edge c2 end) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge A2 start) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge A2 end) at (0,0);
    \end{scope}
  },
  pentagon 2/.style={
    every Penrose pic/.try,
    pic type=pentagon 2,
  },
%    \end{macrocode}
% The pentagram.
%    \begin{macrocode}
  pentagram/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@newedge{2}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm}{0 cm}}%
    \pgftransformrotate{72}%
    \else
    \test@newedge{3}%
    \if@newedge
    \pgftransformrotate{-72}%
    \pgftransformshift{\pgfpoint{2 * \pr@shphi cm}{0 cm}}%
    \else
    \test@newedge{4}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm + 2 * \pr@shphi cm}{0 cm}}%
    \else
    \test@newedge{5}%
    \if@newedge
    \pgftransformrotate{216}%
    \pgftransformshift{\pgfpoint{\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \test@newedge{6}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1cm}{0cm}}%
    \pgftransformrotate{-72}%
    \pgftransformshift{\pgfpoint{\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \test@newedge{7}%
    \if@newedge
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{\pr@shphi cm}{\pr@chphi cm}}%
    \else
    \test@newedge{8}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm + 2*\pr@shphi cm}{0cm}}%
    \pgftransformrotate{216}%
    \pgftransformshift{\pgfpoint{\pr@cphi cm}{\pr@sphi cm}}%
    \else
    \test@newedge{9}%
    \if@newedge
    \pgftransformshift{\pgfpoint{-2*\pr@shphi cm}{0cm}}%
    \pgftransformrotate{72}%
    \else
    \test@newedge{10}%
    \if@newedge
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \fi\fi\fi\fi\fi\fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every pentagram clip/.try
    ]{pentagram}
    \UsePenroseTile[
      every Penrose tile/.try,
      every pentagram/.try,
      pic actions
    ]{pentagram}
\coordinate (-edge C1 start) at (1,0);
\coordinate (-edge C1 end) at (0,0);
\coordinate (-edge C2 start) at (0,0);
\coordinate (-edge C2 end) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge C3 start) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge C3 end) at (-2*\pr@shphi,0);
\coordinate (-edge C4 start) at (-2*\pr@shphi,0);
\coordinate (-edge C4 end) at (-1-2*\pr@shphi,0);
\coordinate (-edge C5 start) at (-1-2*\pr@shphi,0);
\coordinate (-edge C5 end) at (-\pr@cphi,-\pr@sphi);
\coordinate (-edge C6 start) at (-\pr@cphi,-\pr@sphi);
\coordinate (-edge C6 end) at (-\pr@cphi-\pr@shphi,-\pr@sphi-\pr@chphi);
\coordinate (-edge C7 start) at (-\pr@cphi-\pr@shphi,-\pr@sphi-\pr@chphi);
\coordinate (-edge C7 end) at (-\pr@shphi,-\pr@chphi);
\coordinate (-edge C8 start) at (-\pr@shphi,-\pr@chphi);
\coordinate (-edge C8 end) at (1-\pr@cphi+\pr@shphi,-\pr@sphi-\pr@chphi);
\coordinate (-edge C9 start) at (1-\pr@cphi+\pr@shphi,-\pr@sphi-\pr@chphi);
\coordinate (-edge C9 end) at (1-\pr@cphi,-\pr@sphi);
\coordinate (-edge C10 start) at (1-\pr@cphi,-\pr@sphi);
\coordinate (-edge C10 end) at (1,0);
    \end{scope}
  },
  pentagram/.style={
    every Penrose pic/.try,
    pic type=pentagram,
  },
%    \end{macrocode}
% The boat.
%    \begin{macrocode}
  boat/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@edgealign{d}%
    \if@edgealign
    \pgftransformrotate{180}%
    \pgftransformshift{\pgfpoint{\pr@cphi cm - 1cm}{\pr@sphi cm}}%
    \else
    \test@edgealign{b}%
    \if@edgealign%
    \test@newedge{2}%
    \if@newedge
    \pgftransformrotate{144}%
    \pgftransformshift{\pgfpoint{-1 cm}{0 cm}}%
    \else
    \pgftransformrotate{216}%
    \pgftransformshift{\pgfpoint{\pr@cphi cm}{\pr@sphi cm}}%
    \fi
    \else
    \test@edgealign{c}%
    \if@edgealign%
    \test@newedge{2}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm}{0 cm}}%
    \pgftransformrotate{72}%
    \else
    \test@newedge{3}%
    \if@newedge
    \pgftransformrotate{-72}%
    \pgftransformshift{\pgfpoint{2 * \pr@shphi cm}{0 cm}}%
    \else
    \test@newedge{4}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1 cm + 2 * \pr@shphi cm}{0 cm}}%
    \else
    \fi\fi\fi\fi\fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every boat clip/.try
    ]{boat}
    \UsePenroseTile[
      every Penrose tile/.try,
      every boat/.try,
      pic actions
    ]{boat}
\coordinate (-edge C1 start) at (1,0);
\coordinate (-edge C1 end) at (0,0);
\coordinate (-edge C2 start) at (0,0);
\coordinate (-edge C2 end) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge C3 start) at (-\pr@shphi,\pr@chphi);
\coordinate (-edge C3 end) at (-2*\pr@shphi,0);
\coordinate (-edge C4 start) at (-2*\pr@shphi,0);
\coordinate (-edge C4 end) at (-1-2*\pr@shphi,0);
\coordinate (-edge B1 start) at (-1-2*\pr@shphi,0);
\coordinate (-edge B1 end) at (-\pr@cphi,-\pr@sphi);
\coordinate (-edge D start) at (-\pr@cphi,-\pr@sphi);
\coordinate (-edge D end) at (1-\pr@cphi,-\pr@sphi);
\coordinate (-edge B2 start) at (1-\pr@cphi,-\pr@sphi);
\coordinate (-edge B2 end) at (1,0);
    \end{scope}
  },
  boat/.style={
    every Penrose pic/.try,
    pic type=boat,
  },
%    \end{macrocode}
% The diamond.
%    \begin{macrocode}
  diamond/.pic={
    \begin{scope}
    \pgfkeysgetvalue{/tikz/Penrose/alignment location}{\prloc}
    \ifx\prloc\pgfutil@empty
    \else
    \begingroup
    \tikzset{name prefix ..}%
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} start)%
    \global\pgf@xa=\pgf@x
    \global\pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone%
    (\prloc-edge \pgfkeysvalueof{/tikz/Penrose/alignment edge} end)%
    \global\pgf@xb=\pgf@x
    \global\pgf@yb=\pgf@y
    \endgroup
    \advance\pgf@xb by -\pgf@xa
    \advance\pgf@yb by -\pgf@ya
    \pgftransformshift{\pgfpoint{\pgf@xa}{\pgf@ya}}%
    \pgfpointnormalised{\pgfpoint{\pgf@xb}{\pgf@yb}}
    \pgf@xb=\pgf@x
    \pgf@yb=\pgf@y
    \pgftransformtriangle%
    {\pgfpoint{0pt}{0pt}}%
    {\pgfpoint{\pgf@xb}{\pgf@yb}}%
    {\pgfpoint{-\pgf@yb}{\pgf@xb}}%
    \test@edgealign{d}%
    \if@edgealign%
    \test@newedge{2}%
    \if@newedge
    \pgftransformshift{\pgfpoint{1cm}{0cm}}%
    \pgftransformrotate{-162}%
    \else
    \pgftransformrotate{-18}%
    \fi
    \else
    \test@newedge{2}%
    \if@newedge
    \pgftransformrotate{162}%
    \pgftransformshift{\pgfpoint{- 2 * \pr@chphi cm}{0cm}}%
    \else
    \pgftransformshift{\pgfpoint{- \pr@cphi cm}{-\pr@sphi cm}}%
    \pgftransformrotate{18}%
    \fi\fi
    \fi
    \UsePenroseTile[
      every Penrose tile clip/.try,
      every diamond clip/.try
    ]{diamond}
    \UsePenroseTile[
      every Penrose tile/.try,
      every diamond/.try,
      pic actions
    ]{diamond}
\coordinate (-edge D1 start) at (0,0);
\coordinate (-edge D1 end) at (\pr@chphi,\pr@shphi);
\coordinate (-edge B1 start) at (\pr@chphi,\pr@shphi);
\coordinate (-edge B1 end) at (2*\pr@chphi,0);
\coordinate (-edge B2 start) at (2*\pr@chphi,0);
\coordinate (-edge B2 end) at (\pr@chphi,-\pr@shphi);
\coordinate (-edge D2 start) at (\pr@chphi,-\pr@shphi);
\coordinate (-edge D2 end) at (0,0);
    \end{scope}
  },
  diamond/.style={
    every Penrose pic/.try,
    pic type=diamond,
  },
}
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
%\Finale
\endinput
