diff options
author | Karl Berry <karl@freefriends.org> | 2018-07-14 21:29:04 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-07-14 21:29:04 +0000 |
commit | 35efc33cff8eef46f16c51cf575eefb184d7014b (patch) | |
tree | a09bb4da71a31129b8d5ac6c42d859b907a18ca8 /Master/texmf-dist/source/latex/penrose | |
parent | dc072067d34f630b6ad24b60fd64d2e11e3a3fa0 (diff) |
penrose (12jul18)
git-svn-id: svn://tug.org/texlive/trunk@48202 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/penrose')
-rw-r--r-- | Master/texmf-dist/source/latex/penrose/penrose.ins | 77 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/penrose/penrose_code.dtx | 2724 |
2 files changed, 2801 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/penrose/penrose.ins b/Master/texmf-dist/source/latex/penrose/penrose.ins new file mode 100644 index 00000000000..328a9328594 --- /dev/null +++ b/Master/texmf-dist/source/latex/penrose/penrose.ins @@ -0,0 +1,77 @@ +%% +%% This is file `penrose.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% penrose.dtx (with options: `install') +%% ---------------------------------------------------------------- +%% 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 +%% ---------------------------------------------------------------- +%% +\input docstrip.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-2016 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.dtx + penrose_doc.tex +and the derived files penrose.ins + penrose_code.pdf + tikzlibrarypenrose.code.tex + penrose.pdf + README + +\endpostamble +\usedir{tex/latex/penrose} +\generate{ + \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{library}} +} +\endbatchfile +%% +%% Copyright (C) 2014-2016 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.dtx +%% penrose_doc.tex +%% and the derived files penrose.ins +%% penrose_code.pdf +%% tikzlibrarypenrose.code.tex +%% penrose.pdf +%% README +%% +%% +%% End of file `penrose.ins'. diff --git a/Master/texmf-dist/source/latex/penrose/penrose_code.dtx b/Master/texmf-dist/source/latex/penrose/penrose_code.dtx new file mode 100644 index 00000000000..be7030312fe --- /dev/null +++ b/Master/texmf-dist/source/latex/penrose/penrose_code.dtx @@ -0,0 +1,2724 @@ +% \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-2018 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 penrose3.dtx + penrose.tex +and the derived files penrose.ins + penrose3.pdf + penrose.pdf + tikzlibrarypenrose.code.tex + README + +\endpostamble +\usedir{tex/latex/penrose} +\generate{ + \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{library}} +} +%</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[full]{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} +% +% \DoNotIndex +% { +% \begingroup, +% \catcode, +% \active, +% \csname, +% \endcsname, +% }% +% +% \providecommand*{\url}{\texttt} +% \title{The \textsf{Penrose} package} +% \author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}} +% \date{1.0 from 2018/07/10} +% +% +% \maketitle +% +% +% \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 user documentation, see the \Verb+penrose.pdf+ file. +% +% \StopEventually{} +% +% \section{Implementation} +% +% \iffalse +%<*library> +% \fi +% \subsection{Initialisation} +% +% +% \begin{macrocode} +%<@@=penrose> +% \end{macrocode} +% We use the \Verb+spath3+ library for manipulating the paths that will make up the tiles. +% +% \begin{macrocode} +\RequirePackage{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. +% +% \begin{macrocode} +\MakeSPath{Penrose path a} + { + \pgfsyssoftpath@movetotoken{0pt}{0pt} + \pgfsyssoftpath@linetotoken{1pt}{0pt} + } +\SPathPrepare{Penrose path a} +\CloneSPath {Penrose path a}{Penrose path b} +\CloneSPath {Penrose path a}{Penrose path c} +\CloneSPath {Penrose path a}{Penrose path d} +\CloneSPath {Penrose path a}{Penrose path A} +\CloneSPath {Penrose path a}{Penrose path B} +\CloneSPath {Penrose path a}{Penrose path C} +\CloneSPath {Penrose path a}{Penrose path D} +% \end{macrocode} +% +% \begin{variable}{\l__penrose_tmpa_fp, \l__penrose_tmpb_fp, \l__penrose_tmpc_fp, \l__penrose_tmpa_tl, \l__penrose_tmpb_tl, \l__penrose_tmpc_tl} +% We need a few temporary variables to hold intermediate calculations. +% +% \begin{macrocode} +\fp_new:N \l__penrose_tmpa_fp +\fp_new:N \l__penrose_tmpb_fp +\fp_new:N \l__penrose_tmpc_fp +\tl_new:N \l__penrose_tmpa_tl +\tl_new:N \l__penrose_tmpb_tl +\tl_new:N \l__penrose_tmpc_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Creating the Tiles} +% +% \begin{macro}[internal]{\penrose_normalise_path:n} +% 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 \penrose_normalise_path:n #1 +{ +% \end{macrocode} +% Get the initial point of the path and convert to floating point. +% \begin{macrocode} + \spath_get:nnN {#1} {initial point} \l__penrose_tmpa_tl + \fp_set:Nn \l__penrose_tmpa_fp {\tl_head:N \l__penrose_tmpa_tl} + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \fp_set:Nn \l__penrose_tmpb_fp {\tl_head:N \l__penrose_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_get:nnN {#1} {final point} \l__penrose_tmpa_tl + \fp_set:Nn \l__penrose_tmpa_fp + {\tl_head:N \l__penrose_tmpa_tl - \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \fp_set:Nn \l__penrose_tmpb_fp + {\tl_head:N \l__penrose_tmpa_tl - \l__penrose_tmpb_fp} +% \end{macrocode} +% Now compute the square of the length of the path for scaling. +% \begin{macrocode} + \fp_set:Nn \l__penrose_tmpc_fp + {\l__penrose_tmpa_fp^2 + \l__penrose_tmpb_fp^2} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_tmpa_fp/\l__penrose_tmpc_fp} + \fp_set:Nn \l__penrose_tmpb_fp {\l__penrose_tmpb_fp/\l__penrose_tmpc_fp} + \fp_set:Nn \l__penrose_tmpc_fp {-\l__penrose_tmpb_fp} +% \end{macrocode} +% Now construct the matrix. +% \begin{macrocode} + \tl_set:Nx \l__penrose_tmpb_tl + { + {\fp_use:N \l__penrose_tmpa_fp} + {\fp_use:N \l__penrose_tmpb_fp} + {\fp_use:N \l__penrose_tmpc_fp} + {\fp_use:N \l__penrose_tmpa_fp} + } +% \end{macrocode} +% Get the initial point back again for the translation part. +% \begin{macrocode} + \spath_get:nnN {#1} {initial point} \l__penrose_tmpa_tl +% \end{macrocode} +% But we need to premultiply by the matrix because of how the transformations are applied. +% \begin{macrocode} + \fp_set:Nn \l__penrose_tmpa_fp + { + (-1) * \l__penrose_tmpa_fp * \tl_head:N \l__penrose_tmpa_tl + + (-1) * \l__penrose_tmpb_fp * \tl_tail:N \l__penrose_tmpa_tl + } + \fp_set:Nn \l__penrose_tmpb_fp + { + (-1) * \l__penrose_tmpa_fp * \tl_tail:N \l__penrose_tmpa_tl + + \l__penrose_tmpb_fp * \tl_head:N \l__penrose_tmpa_tl + } +% \end{macrocode} +% Finally, we apply the transformation to the path. +% \begin{macrocode} + \tl_put_right:Nx \l__penrose_tmpb_tl { + {\fp_to_dim:N \l__penrose_tmpa_fp} + {\fp_to_dim:N \l__penrose_tmpb_fp} + } + \spath_transform:nV {#1} \l__penrose_tmpb_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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__penrose_tmpa_tl + \spath_clear_new:n {Penrose path #1} + \spath_put:nnV {Penrose path #1} {path} \l__penrose_tmpa_tl + \penrose_normalise_path:n {Penrose path #1} +} +% \end{macrocode} +% \end{macro} +% +% \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]{\penrose_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 \penrose_make_tile:nnn #1#2#3 +{ +% \end{macrocode} +% Get the first coordinate and initialise the path with a move to this point. +% \begin{macrocode} + \tl_set:Nn \l__penrose_tmpa_tl {#3} + \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl} + \tl_set:Nn \l__penrose_tmpa_tl {\pgfsyssoftpath@movetotoken} + \tikz_scan_point:V \l__penrose_tmpb_tl + \tl_put_right:Nx \l__penrose_tmpa_tl + { + {\dim_use:N \pgf@x}{\dim_use:N \pgf@y} + } + \spath_clear_new:n {Penrose path tile #1} + \spath_put:nnV {Penrose path tile #1} {path} \l__penrose_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__penrose_tmpa_tl {#3} + \tl_put_right:Nx \l__penrose_tmpa_tl {{\tl_head:N \l__penrose_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} + \spath_clone:nn {Penrose path ##1} {Penrose path tmpa} +% \end{macrocode} +% Strip off the next coordinate, and convert it to a point. +% \begin{macrocode} + \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl} + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \tikz_scan_point:V \l__penrose_tmpb_tl +% \end{macrocode} +% Store the resulting coordinate. +% \begin{macrocode} + \fp_set:Nn \l__penrose_tmpa_fp { \pgf@x } + \fp_set:Nn \l__penrose_tmpb_fp { \pgf@y } +% \end{macrocode} +% Now get the next coordinate. +% \begin{macrocode} + \tl_set:Nx \l__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl} + \tikz_scan_point:V \l__penrose_tmpb_tl +% \end{macrocode} +% We want the difference between the two coordinates. +% \begin{macrocode} + \fp_set:Nn \l__penrose_tmpa_fp {\pgf@x - \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpb_fp {\pgf@y - \l__penrose_tmpb_fp} +% \end{macrocode} +% This is converted into a transformation matrix. +% \begin{macrocode} + \fp_set:Nn \l__penrose_tmpc_fp {-\l__penrose_tmpb_fp} + \tl_set:Nx \l__penrose_tmpb_tl + { + {\fp_use:N \l__penrose_tmpa_fp} + {\fp_use:N \l__penrose_tmpc_fp} + {\fp_use:N \l__penrose_tmpb_fp} + {\fp_use:N \l__penrose_tmpa_fp} + {0} + {0} + } +% \end{macrocode} +% The transformation is applied to the cloned path. +% \begin{macrocode} + \spath_transform:nV {Penrose path tmpa} \l__penrose_tmpb_tl +% \end{macrocode} +% And this is welded to the tile path. +% \begin{macrocode} + \spath_weld:nn {Penrose path tile #1} {Penrose path tmpa} + } +% \end{macrocode} +% At the end we close the path. +% \begin{macrocode} + \spath_close_path:n {Penrose path tile #1} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\penrose_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 \penrose_make_tile:nn #1#2 +{ + \penrose_make_tile:nnn {#1} #2 +} +\cs_generate_variant:Nn \penrose_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__penrose_tiles_prop +% \end{macrocode} +% +% \begin{macro}[internal]{\tl_add_coordinate:Nnn} +% Process a coordinate through \Verb+fp+ and adds it to a token list. +% \begin{macrocode} +\cs_new_nopar:Npn \tl_add_coordinate:Nnn #1#2#3 { + \fp_set:Nn \l__penrose_tmpa_fp{#2} + \fp_set:Nn \l__penrose_tmpb_fp{#3} + \tl_put_right:Nx #1 + { + {(\fp_use:N \l__penrose_tmpa_fp, \fp_use:N \l__penrose_tmpb_fp)} + } +} +% \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__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(18)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)} + +\prop_gput:Nnx \g__penrose_tiles_prop {thin~ rhombus} +{{a A B b} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Thick Rhombus. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)} + +\prop_gput:Nnx \g__penrose_tiles_prop {thick~ rhombus} +{{B a A b} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Dart. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{2*sind(18)*cosd(108)}{2*sind(18)*sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*sind(18)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{2*sind(18)*cosd(108)}{-2*sind(18)*sind(108)} + +\prop_gput:Nnx \g__penrose_tiles_prop {dart} +{{c a A C} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Kite. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)} + +\prop_gput:Nnx \g__penrose_tiles_prop {kite} +{{a c C A} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Golden Triangle. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)} + +\prop_gput:Nnx \g__penrose_tiles_prop {golden~ triangle} +{{a c b} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Reverse Golden Triangle. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)} + +\prop_gput:Nnx \g__penrose_tiles_prop {reverse~ golden~ triangle} +{{B C A} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Golden Gnomon +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0} + +\prop_gput:Nnx \g__penrose_tiles_prop {golden~ gnomon} +{{C b A} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Reverse Golden Gnomon +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(36)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(36)}{-sind(36)} +\prop_gput:Nnx \g__penrose_tiles_prop {reverse~ golden~ gnomon} +{{a B c} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Primary Pentagon (pentagon 5) +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{1+cosd(72)+cosd(144)}{sind(72)+sind(144)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1+cosd(72)}{sind(72)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0} +\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 5} +{{a a a a a} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Secondary Pentagon (pentagon 3) +% \begin{macrocode} +\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 3} +{{A b a a b} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Tertiary Pentagon (pentagon 2) +% \begin{macrocode} +\prop_gput:Nnx \g__penrose_tiles_prop {pentagon~ 2} +{{d A c c A} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Pentagram +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1-cosd(36)}{-sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{1-cosd(36)-cosd(108)}{-sind(36)-sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{-sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{-1+3*cosd(108)+cosd(36)}{-sind(36)-sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{-1+2*cosd(108)+cosd(36)}{-sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {-1+2*cosd(108)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(108)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\prop_gput:Nnx \g__penrose_tiles_prop {pentagram} +{{C C C C C C C C C C} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Boat +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {-1+2*cosd(108)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(108)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{sind(108)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {1-cosd(36)}{-sind(36)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +{-1+2*cosd(108)+cosd(36)}{-sind(36)} +\prop_gput:Nnx \g__penrose_tiles_prop {boat} +{{C C C C B D B} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \item Diamond. +% \begin{macrocode} +\tl_clear:N \l__penrose_tmpa_tl +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{sind(18)} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*cosd(18)}{0} +\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(18)}{-sind(18)} +\prop_gput:Nnx \g__penrose_tiles_prop {diamond} +{{D B B D} {\tl_use:N \l__penrose_tmpa_tl}} +% \end{macrocode} +% +% \end{itemize} +% +% \begin{macro}[internal]{\MakePenroseTile} +% This is the user wrapper around the tile creation macros. +% \begin{macrocode} +\NewDocumentCommand \MakePenroseTile {m} +{ + \prop_get:NnN \g__penrose_tiles_prop {#1} \l__penrose_tmpa_tl + \penrose_make_tile:nV {#1} \l__penrose_tmpa_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\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} + \spath_clone:nn {Penrose path tile #2} {Penrose path tmpa} +% \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__penrose_tmpa_tl + \tl_clear:N \l__penrose_tmpb_tl + \tl_set:Nx \l__penrose_tmpb_tl {{\tl_head:N \l__penrose_tmpa_tl}} + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \tl_put_right:Nx \l__penrose_tmpb_tl + { + {\tl_item:Nn \l__penrose_tmpa_tl {2}} + } + \tl_put_right:Nx \l__penrose_tmpb_tl + { + {\tl_item:Nn \l__penrose_tmpa_tl {1}} + } + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \tl_set:Nx \l__penrose_tmpa_tl {\tl_tail:N \l__penrose_tmpa_tl} + \tl_put_right:NV \l__penrose_tmpb_tl \l__penrose_tmpa_tl +% \end{macrocode} +% Apply the transformation, protocol the path, and render it. +% \begin{macrocode} + \spath_transform:nV {Penrose path tmpa} \l__penrose_tmpb_tl + \spath_protocol_path:n {Penrose path tmpa} + \spath_tikz_path:nn {#1}{Penrose path tmpa} +} +% \end{macrocode} +% \end{macro} +% +% 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__penrose_tmpa_tl +% \end{macrocode} +% Clear the receiving path, and store the current path in it. +% \begin{macrocode} + \spath_clear_new:n {Penrose path #1} + \spath_put:nnV {Penrose path #1} {path} \l__penrose_tmpa_tl +% \end{macrocode} +% Normalise the path. +% \begin{macrocode} + \penrose_normalise_path:n {Penrose path #1} +% \end{macrocode} +% Now create the reverse path. +% The name is the upper case version. +% \begin{macrocode} + \tex_uppercase:D {\tl_set:Nx \l__penrose_tmpa_tl {#1}} +% \end{macrocode} +% Clone the path. +% \begin{macrocode} + \spath_clone:nn {Penrose path #1} + {Penrose path \tl_use:N \l__penrose_tmpa_tl } +% \end{macrocode} +% Reverse it. +% \begin{macrocode} + \spath_reverse:n {Penrose path \tl_use:N \l__penrose_tmpa_tl} +% \end{macrocode} +% Swap the start and end. +% \begin{macrocode} + \spath_transform:nnnnnnn {Penrose path \tl_use:N \l__penrose_tmpa_tl} + {-1} {0} {0} {-1} {1} {0} + } + }, + expand~ key/.code={ + \exp_args:NV \pgfkeysalso #1 + } +} +% \end{macrocode} +% +% Create the basic tile shapes. +% \begin{macrocode} +\MakePenroseTile {thin~ rhombus} +\MakePenroseTile {thick~ rhombus} +\MakePenroseTile {dart} +\MakePenroseTile {kite} +\MakePenroseTile {golden~ triangle} +\MakePenroseTile {reverse~ golden~ triangle} +\MakePenroseTile {golden~ gnomon} +\MakePenroseTile {reverse~ golden~ gnomon} +\MakePenroseTile {pentagon~ 5} +\MakePenroseTile {pentagon~ 3} +\MakePenroseTile {pentagon~ 2} +\MakePenroseTile {pentagram} +\MakePenroseTile {boat} +\MakePenroseTile {diamond} +% \end{macrocode} +% +% \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__penrose_rhombus_lms_rule_prop +\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {T} {[f*sT][f>g]} +\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {t} {[f_st][f>G]} +\prop_put:Nnn \g__penrose_rhombus_lms_rule_prop {G} {[f+sG][sf>g][sf*sT]} +\prop_put:Nnn \g__penrose_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__penrose_kite_lms_rule_prop +\prop_put:Nnn \g__penrose_kite_lms_rule_prop {T} {[f*sT][f>st][+sg]} +\prop_put:Nnn \g__penrose_kite_lms_rule_prop {t} {[f_st][f>sT][-sG]} +\prop_put:Nnn \g__penrose_kite_lms_rule_prop {G} {[f*+sG][sT]} +\prop_put:Nnn \g__penrose_kite_lms_rule_prop {g} {[f-_sg][st]} +% \end{macrocode} +% +% These are the rules for generating pentagon tilings. +% \begin{macrocode} +\prop_new:N \g__penrose_pentagon_lms_rule_prop +\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {P} +{[s>P][1sF+Q][1+sF+Q][1*sF+Q][1-sF+Q][1_sF+Q]} % pentagon 5 +\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {Q} +{[s>P][1+sFR][1*sF*R][1-sF+Q][1_sF+Q][1sF+Q][->fsD]} % pentagon 3 +\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {R} +{[s>P][1-sF+Q][1+sF*R][1*sFR][1_sF*R][1sFR][_>fsD][>fsD]} % pentagon 2 +\prop_put:Nnn \g__penrose_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_put:Nnn \g__penrose_pentagon_lms_rule_prop {B} +{ + [s>G] + [se[>d+R][e1B]] + [+se[>d+R][e1B]] + [-se[>d+R][e1B]] +} % boat +\prop_put:Nnn \g__penrose_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_set_eq:NN \g__penrose_rtriangle_lms_rule_prop +\g__penrose_rhombus_lms_rule_prop +\prop_set_eq:NN \g__penrose_ktriangle_lms_rule_prop +\g__penrose_kite_lms_rule_prop +% \end{macrocode} +% +% These hold the various actions. +% \begin{macrocode} +\prop_new:N \g__penrose_default_lms_action_prop +\prop_new:N \g__penrose_rhombus_lms_action_prop +\prop_new:N \g__penrose_kite_lms_action_prop +\prop_new:N \g__penrose_rtriangle_lms_action_prop +\prop_new:N \g__penrose_ktriangle_lms_action_prop +\prop_new:N \g__penrose_pentagon_lms_action_prop +% \end{macrocode} +% +% We need some parameters. +% \begin{macrocode} +\dim_new:N \l__penrose_step_dim +\dim_set:Nn \l__penrose_step_dim {1cm} +% \end{macrocode} +% +% These are the defaults, which will be used in all the rule sets. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_default_lms_action_prop {[} {\group_begin:} +\prop_put:Nnn \g__penrose_default_lms_action_prop {]} {\group_end:} +\prop_put:Nnn \g__penrose_default_lms_action_prop {f} +{\pgftransformxshift{\l__penrose_step_dim}} +\prop_put:Nnn \g__penrose_default_lms_action_prop {s} { + \fp_set:Nn \l__penrose_tmpa_fp { 2 * sind(18) * \l__penrose_step_dim } + \dim_set:Nn \l__penrose_step_dim {\fp_to_dim:N \l__penrose_tmpa_fp} +} +% \end{macrocode} +% +% The rhombus rules need a variety of turns. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {+} +{\pgftransformrotate{144}} +\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {*} +{\pgftransformrotate{108}} +\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {-} +{\pgftransformrotate{216}} +\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {_} +{\pgftransformrotate{252}} +\prop_put:Nnn \g__penrose_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_set_eq:NN \g__penrose_rtriangle_lms_action_prop +\g__penrose_rhombus_lms_action_prop +% \end{macrocode} +% +% Now we do the actions that actually draw something. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_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 \l__penrose_tile_int +% \end{macrocode} +% Set up the position, size, and angle correctly. +% \begin{macrocode} + \pgftransformrotate{198} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*2*cosd(18)} + \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_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__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ thin~ rhombus/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{thin~rhombus} + \group_end: +} +% \end{macrocode} +% +% Same for the thick rhombus. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {G} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ thick~ rhombus/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{thick~rhombus} + \group_end: +} +% \end{macrocode} +% +% Now we do the same for the kite and dart tiling. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {+} {\pgftransformrotate{36}} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {*} {\pgftransformrotate{108}} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {-} {\pgftransformrotate{-36}} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {_} +{\pgftransformrotate{-108}} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {>} {\pgftransformrotate{180}} +% \end{macrocode} +% +% \begin{macrocode} +\prop_set_eq:NN \g__penrose_ktriangle_lms_action_prop +\g__penrose_kite_lms_action_prop +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {T} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{36} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ kite/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{kite} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_kite_lms_action_prop {g} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{144} + \pgftransformxshift{-\l__penrose_step_dim * 2 * sin(18)} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ dart/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{dart} + \group_end: +} +% \end{macrocode} +% +% Now we set up the actions for the triangle variations. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {T} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{18} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ reverse~ golden~ triangle/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{reverse~ golden~ triangle} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {t} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{-18} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ golden~ triangle/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{golden~ triangle} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {G} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{180} + \pgftransformxshift{-\l__penrose_step_dim} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ reverse~ golden~ gnomon/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{reverse~ golden~ gnomon} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {g} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{180} + \pgftransformxshift{-\l__penrose_step_dim} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ golden~ gnomon/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{golden~ gnomon} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {T} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{18} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ reverse~ golden~ triangle/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{reverse~ golden~ triangle} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {t} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{-18} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ golden~ triangle/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{golden~ triangle} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {G} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{180} + \pgftransformxshift{-\l__penrose_step_dim} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ reverse~ golden~ gnomon/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{reverse~ golden~ gnomon} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_ktriangle_lms_action_prop {g} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{180} + \pgftransformxshift{-\l__penrose_step_dim} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)/(2*cosd(36))} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ golden~ gnomon/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_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__penrose_pentagon_parity_int +\seq_new:N \l__penrose_pentagon_parity_seq +\seq_set_from_clist:Nn \l__penrose_pentagon_parity_seq {odd,even} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {1} { + \int_set:Nn \l__penrose_pentagon_parity_int + {3 - \l__penrose_pentagon_parity_int} + } +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {+} +{\pgftransformrotate{72}} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {*} +{\pgftransformrotate{144}} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {-} +{\pgftransformrotate{288}} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {_} +{\pgftransformrotate{216}} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {>} +{\pgftransformrotate{180}} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {|} +{\pgftransformxscale{-1}} +% \end{macrocode} +% The scale factor is different. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {s} { + \fp_set:Nn \l__penrose_tmpa_fp + { + 1/(2 + 2 * cosd(72) ) * \l__penrose_step_dim + } + \dim_set:Nn \l__penrose_step_dim {\fp_to_dim:N \l__penrose_tmpa_fp} +} +% \end{macrocode} +% And we tend to work better vertically. +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {f} { + \fp_set:Nn \l__penrose_tmpa_fp { tand(54)/2 * \l__penrose_step_dim } + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} +} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {F} { + \fp_set:Nn \l__penrose_tmpa_fp { tand(54) * \l__penrose_step_dim } + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} +} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {d} { + \fp_set:Nn \l__penrose_tmpa_fp + { + (tand(54)/2 - tand(72)/2 + sind(36) ) * \l__penrose_step_dim + } + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} +} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {e} { + \fp_set:Nn \l__penrose_tmpa_fp + { + tand(54) * cosd(36) * \l__penrose_step_dim + } + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {P} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2} + \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2} + \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ pentagon/.try, + every~ + \seq_item:Nn \l__penrose_pentagon_parity_seq + {\l__penrose_pentagon_parity_int} + \space pentagon/.try, + every~ pentagon~ 5/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{pentagon~5} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {Q} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2} + \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2} + \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ pentagon/.try, + every~ + \seq_item:Nn \l__penrose_pentagon_parity_seq + {\l__penrose_pentagon_parity_int} + \space pentagon/.try, + every~ pentagon~ 3/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{pentagon~3} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {R} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/2} + \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)/2} + \pgftransformyshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ pentagon/.try, + every~ + \seq_item:Nn \l__penrose_pentagon_parity_seq + {\l__penrose_pentagon_parity_int} + \space pentagon/.try, + every~ pentagon~ 2/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{pentagon~2} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {G} { + \group_begin: + \int_gincr:N \l__penrose_tile_int +% \pgftransformrotate{198} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(72)} + \pgftransformxshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)*cosd(72)} + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ pentagram/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{pentagram} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {B} { + \group_begin: + \int_gincr:N \l__penrose_tile_int +% \pgftransformrotate{198} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(72)} + \pgftransformxshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*tand(54)*cosd(72)} + \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ boat/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{boat} + \group_end: +} +% \end{macrocode} +% +% \begin{macrocode} +\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {D} { + \group_begin: + \int_gincr:N \l__penrose_tile_int + \pgftransformrotate{90} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim*cosd(18)} + \pgftransformxshift{-\fp_to_dim:N \l__penrose_tmpa_fp} + \fp_set:Nn \l__penrose_tmpa_fp {\l__penrose_step_dim/(1cm)} + \pgftransformscale{\fp_use:N \l__penrose_tmpa_fp} + \tl_set:Nx \l__penrose_tmpc_tl + { + {\int_use:N \l__penrose_tile_int} + {\int_use:N \l__penrose_tiles_int} + } + \UsePenroseTile[ + every~ Penrose~ tile/.try, + every~ diamond/.try, + Penrose~ tile~ \int_use:N \l__penrose_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + ]{diamond} + \group_end: +} +% \end{macrocode} +% +% \begin{macro}[internal]{\penrose_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 \penrose_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__penrose_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__penrose_tmpa_tl \l__penrose_tmpb_tl +% \end{macrocode} +% Clear the receiving token list. +% \begin{macrocode} + \tl_clear:N \l__penrose_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__penrose_tmpa_tl + { +% \end{macrocode} +% If a rule exists, copy that. +% \begin{macrocode} + \prop_if_in:cnTF {g__penrose_#2_lms_rule_prop} {##1} + { + \tl_put_right:Nx \l__penrose_tmpb_tl + {\prop_item:cn {g__penrose_#2_lms_rule_prop} {##1} } + } + { +% \end{macrocode} +% Otherwise, just copy the token. +% \begin{macrocode} + \tl_put_right:Nn \l__penrose_tmpb_tl {##1} + } + } + } +% \end{macrocode} +% We've done all this inside a group, now pass the result outside. +% \begin{macrocode} + \tl_set:Nn \l__penrose_tmpa_tl { + \group_end: + \tl_set:Nn #1 + } + \tl_put_right:Nx \l__penrose_tmpa_tl {{\tl_use:N \l__penrose_tmpb_tl}} + \tl_use:N \l__penrose_tmpa_tl +} +\cs_generate_variant:Nn \penrose_make_lms:Nnnn {Nnnx} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\penrose_invoke_lms:Nn} +% This carries out the actions specified by the resulting rules. +% \begin{macrocode} +\cs_new_nopar:Npn \penrose_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__penrose_#2_lms_action_prop} {##1} + { + \prop_item:cn {g__penrose_#2_lms_action_prop} {##1} + } + { + \prop_if_in:cnT {g__penrose_default_lms_action_prop} {##1} + { + \prop_item:cn {g__penrose_default_lms_action_prop} {##1} + } + } + } + \group_end: +} +% \end{macrocode} +% \end{macro} +% +% We keep track of the number of tiles. +% \begin{macrocode} +\int_new:N \l__penrose_tile_int +\int_new:N \l__penrose_tiles_int +% \end{macrocode} +% +% \begin{macro}[internal]{\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} + \penrose_make_lms:Nnnx \l__penrose_tmpa_tl {#2} {#3} {#4} + \penrose_count_lms:N \l__penrose_tmpa_tl + \int_gzero:N \l__penrose_tile_int + \int_gset:Nn \l__penrose_pentagon_parity_int {2} + \penrose_invoke_lms:Nn \l__penrose_tmpa_tl {#2} + \group_end: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[internal]{\penrose_count_lms:N} +% This counts the number of tiles in the string. +% \begin{macrocode} +\cs_new_nopar:Npn \penrose_count_lms:N #1 +{ + \int_gzero:N \l__penrose_tiles_int + \tl_map_inline:Nn #1 + { + \tl_if_eq:nnT {##1} {T} + { + \int_incr:N \l__penrose_tiles_int + } + \tl_if_eq:nnT {##1} {t} + { + \int_incr:N \l__penrose_tiles_int + } + \tl_if_eq:nnT {##1} {G} + { + \int_incr:N \l__penrose_tiles_int + } + \tl_if_eq:nnT {##1} {g} + { + \int_incr:N \l__penrose_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__penrose_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} +% +% \iffalse +%</library> +% \fi +%\Finale +\endinput |