From 9456871cc89612c1f974af157f0ed08b9630c4c6 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 24 Jan 2021 03:03:37 +0000 Subject: CTAN sync 202101240303 --- graphics/pgf/contrib/penrose/README | 8 + graphics/pgf/contrib/penrose/README.txt | 8 - graphics/pgf/contrib/penrose/penrose.pdf | Bin 552561 -> 557513 bytes graphics/pgf/contrib/penrose/penrose.tex | 151 +- graphics/pgf/contrib/penrose/penrose_code.dtx | 1588 ++++-- graphics/pgf/contrib/penrose/penrose_code.pdf | Bin 394873 -> 464179 bytes graphics/pgf/contrib/spath3/README | 2 +- graphics/pgf/contrib/spath3/calligraphy.pdf | Bin 0 -> 259679 bytes graphics/pgf/contrib/spath3/calligraphy.tex | 271 + graphics/pgf/contrib/spath3/calligraphy_doc.pdf | Bin 288184 -> 0 bytes graphics/pgf/contrib/spath3/calligraphy_doc.tex | 258 - graphics/pgf/contrib/spath3/knots.pdf | Bin 0 -> 333450 bytes graphics/pgf/contrib/spath3/knots.tex | 516 ++ graphics/pgf/contrib/spath3/knots_doc.pdf | Bin 384979 -> 0 bytes graphics/pgf/contrib/spath3/knots_doc.tex | 484 -- graphics/pgf/contrib/spath3/spath3.dtx | 4228 -------------- graphics/pgf/contrib/spath3/spath3.pdf | Bin 0 -> 337099 bytes graphics/pgf/contrib/spath3/spath3.tex | 650 +++ graphics/pgf/contrib/spath3/spath3_code.dtx | 6719 +++++++++++++++++++++++ graphics/pgf/contrib/spath3/spath3_code.pdf | Bin 439282 -> 547140 bytes 20 files changed, 9267 insertions(+), 5616 deletions(-) create mode 100644 graphics/pgf/contrib/penrose/README delete mode 100644 graphics/pgf/contrib/penrose/README.txt create mode 100644 graphics/pgf/contrib/spath3/calligraphy.pdf create mode 100644 graphics/pgf/contrib/spath3/calligraphy.tex delete mode 100644 graphics/pgf/contrib/spath3/calligraphy_doc.pdf delete mode 100644 graphics/pgf/contrib/spath3/calligraphy_doc.tex create mode 100644 graphics/pgf/contrib/spath3/knots.pdf create mode 100644 graphics/pgf/contrib/spath3/knots.tex delete mode 100644 graphics/pgf/contrib/spath3/knots_doc.pdf delete mode 100644 graphics/pgf/contrib/spath3/knots_doc.tex delete mode 100644 graphics/pgf/contrib/spath3/spath3.dtx create mode 100644 graphics/pgf/contrib/spath3/spath3.pdf create mode 100644 graphics/pgf/contrib/spath3/spath3.tex create mode 100644 graphics/pgf/contrib/spath3/spath3_code.dtx (limited to 'graphics/pgf') diff --git a/graphics/pgf/contrib/penrose/README b/graphics/pgf/contrib/penrose/README new file mode 100644 index 0000000000..43c2298f5f --- /dev/null +++ b/graphics/pgf/contrib/penrose/README @@ -0,0 +1,8 @@ +---------------------------------------------------------------- +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. diff --git a/graphics/pgf/contrib/penrose/README.txt b/graphics/pgf/contrib/penrose/README.txt deleted file mode 100644 index 43c2298f5f..0000000000 --- a/graphics/pgf/contrib/penrose/README.txt +++ /dev/null @@ -1,8 +0,0 @@ ----------------------------------------------------------------- -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. diff --git a/graphics/pgf/contrib/penrose/penrose.pdf b/graphics/pgf/contrib/penrose/penrose.pdf index 089af30724..67ea7a9309 100644 Binary files a/graphics/pgf/contrib/penrose/penrose.pdf and b/graphics/pgf/contrib/penrose/penrose.pdf differ diff --git a/graphics/pgf/contrib/penrose/penrose.tex b/graphics/pgf/contrib/penrose/penrose.tex index b381149ee2..be44311844 100644 --- a/graphics/pgf/contrib/penrose/penrose.tex +++ b/graphics/pgf/contrib/penrose/penrose.tex @@ -1,4 +1,4 @@ -\immediate\write18{tex penrose_code.dtx} +%\immediate\write18{tex penrose_code.dtx} \documentclass{ltxdoc} \usepackage[T1]{fontenc} \usepackage{trace} @@ -12,8 +12,15 @@ \usepackage{listings} \lstloadlanguages{[LaTeX]TeX} -\lstset{breakatwhitespace=true,breaklines=true,language=TeX} - +\lstset{ + breakatwhitespace=true, + breaklines=true, + language=[LaTeX]TeX, + basicstyle=\small\ttfamily, + keepspaces=true, + columns=fullflexible +} + \usepackage{fancyvrb} \newenvironment{example} @@ -23,7 +30,6 @@ \begin{center} \setlength{\parindent}{0pt} \fbox{\begin{minipage}{.9\linewidth} - \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} \lstinputlisting[]{example.out} \end{minipage}} @@ -41,7 +47,6 @@ \begin{center} \setlength{\parindent}{0pt} \fbox{\begin{minipage}{.9\linewidth} - \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} \lstinputlisting[]{example.out} \end{minipage}} \end{center} @@ -73,18 +78,21 @@ \makeatother \providecommand*{\url}{\texttt} +\GetFileInfo{tikzlibrarypenrose.code.tex} \title{The \textsf{Penrose} Package: Documentation} \author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}} -\date{1.0~from 2018/07/10} + \date{\fileversion~from \filedate} \begin{document} \maketitle +\tableofcontents + \section{Introduction} The \textsf{Penrose} package is a TikZ library for drawing Penrose tiles. -It currently supports the kite/dart, rhombus, and pentagon tile sets. +It currently supports natively the kite/dart, rhombus, and pentagon tile sets, but has provision for defining new tiles. There are two main methods for their placement: one that automatically generates a tiling, and one that allows for ``by hand'' placement. Furthermore, the tiles themselves can be deformed and will still (hopefully!) fit together in the correct fashion. @@ -148,7 +156,7 @@ If the shortcut keys are used to specify the tiles, this can be put in the \Verb TikZ \Verb+pic+s can be named, using the \Verb+name=+ key. When a Penrose tile has been named then it can be used for positioning other tiles. -Each edge is assigned a label from \Verb+a b c A B C+ and a new tile can be aligned with an old one along a matching edge (\Verb+a+ matches with \Verb+A+ and so on). +Each edge is assigned a label from \Verb+a b c d e A B C D E+ and a new tile can be aligned with an old one along a matching edge (\Verb+a+ matches with \Verb+A+ and so on). The edge labels are as follows. For the \Verb+pentagon 5+, for example, the edges are all the same and the numbers are used to distinguish between them. @@ -273,7 +281,7 @@ In practical terms, this means that if drawn then the line width is half that wh There is a way to specify a Penrose tiling using \emph{Lindenmayer systems}. In brief, this takes a golden triangle or gnomon (or one of the reverse ones) and repeatedly decomposes it into smaller triangles and gnomon. Once a desired level has been reached, the resulting triangles and gnomon are glued together in pairs to create either darts and kites or rhombuses (of both types). -This library contains an implementation of this both for each of the tilings. +This library contains an implementation of this for each of the tilings. The user command is: % @@ -351,41 +359,44 @@ Indeed, by using asymmetric paths, the matching rules can be enforced without th Internally, the \Verb+penrose+ library uses the \Verb+spath3+ package for storing and manipulating the paths. -To create a new edge path, use the key \Verb+save Penrose path=+ where \Verb++ is one of \Verb+a+, \Verb+b+, \Verb+c+, or \Verb+d+. +To create a new edge path, use the key \Verb+save Penrose path=+ where \Verb++ is a symbol used in the edge description of a tile. There are no constraints on the size of the path as all paths are scaled and transformed to fit the tiles. Once the edge paths have been specified, they are welded together into the tiles using the following command: % \begin{verbatim} -\MakePenroseTile{} +\BakePenroseTile{} \end{verbatim} % Here, \Verb++ is one of the names of the tiles. This has global effect, as does the definition of the edge paths. -Internally, the tile paths are stored as \Verb+spath+ objects (from the \Verb+spath3+ package) so the commands of that package can be used to, for example, make a copy of a tile. -The internal name for a tile path is \Verb+Penrosepathtile+ (no spaces) so can be cloned via: +Paths, both sides and tiles, can be cloned via: % \begin{verbatim} -\CloneSPath{Penrosepathtile}{My Amazing Penrose Tile} +\tikzset{clone Penrose side path={target}{source} +\tikzset{clone Penrose tile path={target}{source} \end{verbatim} % and restored with the same command (but names switched). +The initial version of this package used \Verb!\MakePenroseTile! for this command. +That command is still available for backwards compatibility. + \begin{example} \begin{tikzpicture} \pic[draw,dart,name=dart]; \pic[draw,kite,align with=dart along c]; \pic[draw,kite,align with=dart along C]; -\CloneSPath{Penrosepathtilekite}{Original kite} -\CloneSPath{Penrosepathtiledart}{Original dart} +\tikzset{clone Penrose tile path={original kite}{kite}} +\tikzset{clone Penrose tile path={original dart}{dart}} \path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0); \path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0); -\MakePenroseTile{kite} -\MakePenroseTile{dart} +\BakePenroseTile{kite} +\BakePenroseTile{dart} \pic[xshift=2cm,draw,dart,name=dart]; \pic[draw,kite,align with=dart along c]; \pic[draw,kite,align with=dart along C]; -\CloneSPath{Original kite}{Penrosepathtilekite} -\CloneSPath{Original dart}{Penrosepathtiledart} +\tikzset{clone Penrose tile path={kite}{original kite}} +\tikzset{clone Penrose tile path={dart}{original dart}} \pic[xshift=4cm,draw,dart,name=dart]; \pic[draw,kite,align with=dart along c]; \pic[draw,kite,align with=dart along C]; @@ -394,6 +405,58 @@ and restored with the same command (but names switched). With deformed tiles, there is no guarantee that the inner arcs will match up perfectly. +\section{Defining New Tiles} + +This package includes the capability to define new tiles. +The command to do this is: +% +\begin{verbatim} +\DefineTile{}{}{} +\end{verbatim} +% +For example, +% +\begin{verbatim} +\DefineTile {square}{a A a A} +{ + {0,0} + {1,0} + {1,1} + {0,1} +} +\end{verbatim} +% +The \Verb!! is a list of sides for matching rules. +Each letter used matches against its opposite case (so it is possible to create a side that matches against itself by using a symbol that \TeX\ regards as having the same upper as lower case; not all symbols work, I've used \Verb+!+ successfully). +These are also used in path replacing, both a letter and its opposite case are replaced by the corresponding path (but in opposite directions) when the tile is ``baked''. +The coordinates are passed to the \Verb!fp! module of \LaTeX3 so can involve complicated expressions. +Note that the trigonometric functions for angles in degrees are \Verb!cosd!, \Verb!sind!, and \Verb!tand!. + +Note that the tile must be baked via the command \Verb!\BakePenroseTile! before it can be used. + +The new tile can be used with all the same features as the pre-defined Penrose tiles, except for the Lindenmayer systems. + +\begin{example} +\DefineTile {square}{a A a A} +{ + {0,0} + {1,0} + {1,1} + {0,1} +} + +\begin{tikzpicture} +\path[save Penrose path=a] (0,0) to[out=45,in=135] (1,0); +\BakePenroseTile{square} +\pic[square,name=A,fill=green]; +\pic[square,align with=A along a1 using 2,name=B,fill=red]; +\pic[square,align with=A along A1 using 2,fill=red]; +\pic[square,align with=A along A2 using 1,fill=red]; +\pic[square,align with=B along a1 using 2,fill=green]; +\pic[square,align with=B along a2 using 1,fill=green]; +\end{tikzpicture} +\end{example} + \section{More Examples} Let's set some aesthetically pleasing shapes. @@ -403,14 +466,14 @@ Let's set some aesthetically pleasing shapes. \path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0); \path[save Penrose path=b] (0,0) to[out=0,in=140] (1,0); \path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0); -\MakePenroseTile{thin rhombus} -\MakePenroseTile{thick rhombus} -\MakePenroseTile{golden triangle} -\MakePenroseTile{reverse golden triangle} -\MakePenroseTile{golden gnomon} -\MakePenroseTile{reverse golden gnomon} -\MakePenroseTile{kite} -\MakePenroseTile{dart} +\BakePenroseTile{thin rhombus} +\BakePenroseTile{thick rhombus} +\BakePenroseTile{golden triangle} +\BakePenroseTile{reverse golden triangle} +\BakePenroseTile{golden gnomon} +\BakePenroseTile{reverse golden gnomon} +\BakePenroseTile{kite} +\BakePenroseTile{dart} \end{tikzpicture} \end{justexample} @@ -418,14 +481,14 @@ Let's set some aesthetically pleasing shapes. \path[save Penrose path=a] (0,0) to[out=-30,in=100] (1,0); \path[save Penrose path=b] (0,0) to[out=0,in=140] (1,0); \path[save Penrose path=c] (0,0) to[out=-40,in=140] (1,0); -\MakePenroseTile{thin rhombus} -\MakePenroseTile{thick rhombus} -\MakePenroseTile{golden triangle} -\MakePenroseTile{reverse golden triangle} -\MakePenroseTile{golden gnomon} -\MakePenroseTile{reverse golden gnomon} -\MakePenroseTile{kite} -\MakePenroseTile{dart} +\BakePenroseTile{thin rhombus} +\BakePenroseTile{thick rhombus} +\BakePenroseTile{golden triangle} +\BakePenroseTile{reverse golden triangle} +\BakePenroseTile{golden gnomon} +\BakePenroseTile{reverse golden gnomon} +\BakePenroseTile{kite} +\BakePenroseTile{dart} \end{tikzpicture} @@ -676,14 +739,14 @@ Lastly, here's an example that generates full page patterns. \path[save Penrose path=a] (0,0) -- (1,0); \path[save Penrose path=b] (0,0) -- (1,0); \path[save Penrose path=c] (0,0) -- (1,0); -\MakePenroseTile{thin rhombus} -\MakePenroseTile{thick rhombus} -\MakePenroseTile{golden triangle} -\MakePenroseTile{reverse golden triangle} -\MakePenroseTile{golden gnomon} -\MakePenroseTile{reverse golden gnomon} -\MakePenroseTile{kite} -\MakePenroseTile{dart} +\BakePenroseTile{thin rhombus} +\BakePenroseTile{thick rhombus} +\BakePenroseTile{golden triangle} +\BakePenroseTile{reverse golden triangle} +\BakePenroseTile{golden gnomon} +\BakePenroseTile{reverse golden gnomon} +\BakePenroseTile{kite} +\BakePenroseTile{dart} \end{tikzpicture} \newpage diff --git a/graphics/pgf/contrib/penrose/penrose_code.dtx b/graphics/pgf/contrib/penrose/penrose_code.dtx index be7030312f..cdc6356965 100644 --- a/graphics/pgf/contrib/penrose/penrose_code.dtx +++ b/graphics/pgf/contrib/penrose/penrose_code.dtx @@ -34,7 +34,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2014-2018 by Andrew Stacey +Copyright (C) 2014-2019 by Andrew Stacey This work may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either @@ -46,18 +46,18 @@ 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 +This work consists of the files penrose_code.dtx penrose.tex and the derived files penrose.ins - penrose3.pdf + penrose_code.pdf penrose.pdf tikzlibrarypenrose.code.tex - README + README.txt \endpostamble \usedir{tex/latex/penrose} \generate{ - \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{library}} + \file{tikzlibrarypenrose.code.tex}{\from{\jobname.dtx}{package}} } % %\endbatchfile @@ -78,11 +78,11 @@ and the derived files penrose.ins \fi % %<*driver> -\documentclass[full]{l3doc} +\documentclass{l3doc} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage{tikz} -\usepackage{trace} +%\usepackage{trace} \usetikzlibrary{penrose} %\traceoff %\usepackage[numbered]{hypdoc} @@ -139,6 +139,8 @@ and the derived files penrose.ins % % % \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 % { @@ -149,39 +151,50 @@ and the derived files penrose.ins % \endcsname, % }% % +% % \providecommand*{\url}{\texttt} +% \GetFileInfo{tikzlibrarypenrose.code.tex} % \title{The \textsf{Penrose} package} % \author{Andrew Stacey\texorpdfstring{\\ \url{loopspace@mathforge.org}}{}} -% \date{1.0 from 2018/07/10} +% \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 user documentation, see the \Verb+penrose.pdf+ file. +% For full user documentation, see the \Verb+penrose.pdf+ file. % -% \StopEventually{} % -% \section{Implementation} +% \end{documentation} % -% \iffalse -%<*library> -% \fi -% \subsection{Initialisation} +% \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} @@ -189,50 +202,75 @@ and the derived files penrose.ins % \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} +% 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__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 +\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]{\penrose_normalise_path:n} +% \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 \penrose_normalise_path:n #1 +\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} - \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} + \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. % @@ -245,71 +283,80 @@ and the derived files penrose.ins % \] % % \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} + \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__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} + \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__penrose_tmpb_tl + \tl_set:Nx \l_@@_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} + {\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_get:nnN {#1} {initial point} \l__penrose_tmpa_tl + \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__penrose_tmpa_fp + \fp_set:Nn \l_@@_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 + (-1) * \l_@@_tmpa_fp * \tl_head:N \l_@@_tmpa_tl + + (-1) * \l_@@_tmpb_fp * \tl_tail:N \l_@@_tmpa_tl } - \fp_set:Nn \l__penrose_tmpb_fp + \fp_set:Nn \l_@@_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 + (-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__penrose_tmpb_tl { - {\fp_to_dim:N \l__penrose_tmpa_fp} - {\fp_to_dim:N \l__penrose_tmpb_fp} + \tl_put_right:Nx \l_@@_tmpb_tl { + {\fp_to_dim:N \l_@@_tmpa_fp} + {\fp_to_dim:N \l_@@_tmpb_fp} } - \spath_transform:nV {#1} \l__penrose_tmpb_tl + \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{macro}[internal]{\SetPenrosePath} +% \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__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} + \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{macro} +% \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. @@ -322,32 +369,32 @@ and the derived files penrose.ins % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\penrose_make_tile:nnn} +% \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 \penrose_make_tile:nnn #1#2#3 +\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} - \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 + \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} } - \spath_clear_new:n {Penrose path tile #1} - \spath_put:nnV {Penrose path tile #1} {path} \l__penrose_tmpa_tl + \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__penrose_tmpa_tl {#3} - \tl_put_right:Nx \l__penrose_tmpa_tl {{\tl_head:N \l__penrose_tmpa_tl}} + \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} @@ -355,66 +402,72 @@ and the derived files penrose.ins % \end{macrocode} % Clone the path for this side. % \begin{macrocode} - \spath_clone:nn {Penrose path ##1} {Penrose path tmpa} + \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__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 + \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__penrose_tmpa_fp { \pgf@x } - \fp_set:Nn \l__penrose_tmpb_fp { \pgf@y } + \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__penrose_tmpb_tl {\tl_head:N \l__penrose_tmpa_tl} - \tikz_scan_point:V \l__penrose_tmpb_tl + \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__penrose_tmpa_fp {\pgf@x - \l__penrose_tmpa_fp} - \fp_set:Nn \l__penrose_tmpb_fp {\pgf@y - \l__penrose_tmpb_fp} + \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__penrose_tmpc_fp {-\l__penrose_tmpb_fp} - \tl_set:Nx \l__penrose_tmpb_tl + \fp_set:Nn \l_@@_tmpc_fp {-\l_@@_tmpb_fp} + \tl_set:Nx \l_@@_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} + {\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 {Penrose path tmpa} \l__penrose_tmpb_tl + \spath_transform:NV \l_@@_tmpd_tl \l_@@_tmpb_tl % \end{macrocode} % And this is welded to the tile path. % \begin{macrocode} - \spath_weld:nn {Penrose path tile #1} {Penrose path tmpa} + \spath_weld:NV \l_@@_tmp_tile_path_tl \l_@@_tmpd_tl } % \end{macrocode} % At the end we close the path. % \begin{macrocode} - \spath_close_path:n {Penrose path tile #1} + \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]{\penrose_make_tile:nn} +% \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 \penrose_make_tile:nn #1#2 +\cs_new_nopar:Npn \@@_make_tile:nn #1#2 { - \penrose_make_tile:nnn {#1} #2 + \@@_make_tile:nnn {#1} #2 } -\cs_generate_variant:Nn \penrose_make_tile:nn {nV} +\cs_generate_variant:Nn \@@_make_tile:nn {nV} % \end{macrocode} % \end{macro} % @@ -422,21 +475,28 @@ and the derived files penrose.ins % % The tile specifications are contained in a \Verb+prop+. % \begin{macrocode} -\prop_new:N \g__penrose_tiles_prop +\prop_new:N \g_@@_tiles_prop % \end{macrocode} % -% \begin{macro}[internal]{\tl_add_coordinate:Nnn} +% \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 \tl_add_coordinate:Nnn #1#2#3 { - \fp_set:Nn \l__penrose_tmpa_fp{#2} - \fp_set:Nn \l__penrose_tmpb_fp{#3} +\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__penrose_tmpa_fp, \fp_use:N \l__penrose_tmpb_fp)} + {(\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. @@ -446,182 +506,186 @@ and the derived files penrose.ins % \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)} +\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__penrose_tiles_prop {thin~ rhombus} -{{a A B b} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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)} +\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__penrose_tiles_prop {thick~ rhombus} -{{B a A b} {\tl_use:N \l__penrose_tmpa_tl}} +\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__penrose_tmpa_tl -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {0}{0} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +\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)} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {2*sind(18)}{0} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +\@@_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__penrose_tiles_prop {dart} -{{c a A C} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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)} +\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__penrose_tiles_prop {kite} -{{a c C A} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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)} +\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__penrose_tiles_prop {golden~ triangle} -{{a c b} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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)} +\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__penrose_tiles_prop {reverse~ golden~ triangle} -{{B C A} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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_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__penrose_tiles_prop {golden~ gnomon} -{{C b A} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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}} +\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__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 +\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)} -\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}} +\@@_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__penrose_tiles_prop {pentagon~ 3} -{{A b a a b} {\tl_use:N \l__penrose_tmpa_tl}} +\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__penrose_tiles_prop {pentagon~ 2} -{{d A c c A} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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 +\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)} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl {cosd(108)}{-sind(108)} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +\@@_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)} -\tl_add_coordinate:Nnn \l__penrose_tmpa_tl +\@@_add_coordinate:Nnn \l_@@_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}} +\@@_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__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 +\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__penrose_tiles_prop {boat} -{{C C C C B D B} {\tl_use:N \l__penrose_tmpa_tl}} +\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__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}} +\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{macro}[internal]{\MakePenroseTile} +% \begin{function}{\BakePenroseTile} % This is the user wrapper around the tile creation macros. % \begin{macrocode} -\NewDocumentCommand \MakePenroseTile {m} +\NewDocumentCommand \BakePenroseTile {m} { - \prop_get:NnN \g__penrose_tiles_prop {#1} \l__penrose_tmpa_tl - \penrose_make_tile:nV {#1} \l__penrose_tmpa_tl + \prop_get:NnN \g_@@_tiles_prop {#1} \l_@@_tmpa_tl + \@@_make_tile:nV {#1} \l_@@_tmpa_tl } % \end{macrocode} -% \end{macro} +% For backwards compatibility. +% \begin{macrocode} +\cs_set_eq:NN \MakePenroseTile \BakePenroseTile +% \end{macrocode} +% \end{function} % -% \begin{macro}[internal]{\UsePenroseTile} +% \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} @@ -631,36 +695,36 @@ and the derived files penrose.ins % 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} + \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__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 + \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 {Penrose path tmpa} \l__penrose_tmpb_tl - \spath_protocol_path:n {Penrose path tmpa} - \spath_tikz_path:nn {#1}{Penrose path tmpa} + \spath_transform:NV \l_@@_tmp_tile_path_tl \l_@@_tmpa_tl + \spath_tikz_path:nV {#1} \l_@@_tmp_tile_path_tl } % \end{macrocode} -% \end{macro} +% \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} @@ -670,60 +734,395 @@ and the derived files penrose.ins % \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 + \pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl % \end{macrocode} -% Normalise the path. +% Normalise the path and save. % \begin{macrocode} - \penrose_normalise_path:n {Penrose path #1} + \@@_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} - \tex_uppercase:D {\tl_set:Nx \l__penrose_tmpa_tl {#1}} + \tl_set:Nx \l_@@_tmpb_tl {\str_uppercase:n {#1}} % \end{macrocode} -% Clone the path. +% Reverse the path, and relocate to the interval \([0,1]\). % \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} + \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} -\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} +\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} % @@ -735,32 +1134,32 @@ and the derived files penrose.ins % % 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]} +\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__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]} +\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__penrose_pentagon_lms_rule_prop -\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {P} +\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_put:Nnn \g__penrose_pentagon_lms_rule_prop {Q} +\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_put:Nnn \g__penrose_pentagon_lms_rule_prop {R} +\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_put:Nnn \g__penrose_pentagon_lms_rule_prop {G} +\prop_gput:Nnn \g_@@_pentagon_lms_rule_prop {G} { [s>G] [se[>d+R][e1B]] @@ -769,103 +1168,103 @@ and the derived files penrose.ins [*se[>d+R][e1B]] [_se[>d+R][e1B]] } % pentagram -\prop_put:Nnn \g__penrose_pentagon_lms_rule_prop {B} +\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_put:Nnn \g__penrose_pentagon_lms_rule_prop {D} +\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_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 +\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__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 +\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__penrose_step_dim -\dim_set:Nn \l__penrose_step_dim {1cm} +\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_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} +\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_put:Nnn \g__penrose_rhombus_lms_action_prop {+} +\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {+} {\pgftransformrotate{144}} -\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {*} +\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {*} {\pgftransformrotate{108}} -\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {-} +\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {-} {\pgftransformrotate{216}} -\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {_} +\prop_gput:Nnn \g_@@_rhombus_lms_action_prop {_} {\pgftransformrotate{252}} -\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {>} +\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_set_eq:NN \g__penrose_rtriangle_lms_action_prop -\g__penrose_rhombus_lms_action_prop +\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_put:Nnn \g__penrose_rhombus_lms_action_prop {T} { +\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 \l__penrose_tile_int + \int_gincr:N \g_@@_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} + \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__penrose_tmpc_tl + \tl_set:Nx \l_@@_tmpc_tl { - {\int_use:N \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + Penrose~ tile~ \int_use:N \g_@@_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl ]{thin~rhombus} \group_end: } @@ -873,21 +1272,21 @@ and the derived files penrose.ins % % Same for the thick rhombus. % \begin{macrocode} -\prop_put:Nnn \g__penrose_rhombus_lms_action_prop {G} { +\prop_gput:Nnn \g_@@_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_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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + Penrose~ tile~ \int_use:N \g_@@_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl ]{thick~rhombus} \group_end: } @@ -895,59 +1294,59 @@ and the derived files penrose.ins % % 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 {_} +\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_put:Nnn \g__penrose_kite_lms_action_prop {>} {\pgftransformrotate{180}} +\prop_gput:Nnn \g_@@_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 +\prop_gset_eq:NN \g_@@_ktriangle_lms_action_prop +\g_@@_kite_lms_action_prop % \end{macrocode} % % \begin{macrocode} -\prop_put:Nnn \g__penrose_kite_lms_action_prop {T} { +\prop_gput:Nnn \g_@@_kite_lms_action_prop {T} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_kite_lms_action_prop {g} { +\prop_gput:Nnn \g_@@_kite_lms_action_prop {g} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + Penrose~ tile~ \int_use:N \g_@@_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl ]{dart} \group_end: } @@ -955,185 +1354,185 @@ and the derived files penrose.ins % % Now we set up the actions for the triangle variations. % \begin{macrocode} -\prop_put:Nnn \g__penrose_rtriangle_lms_action_prop {T} { +\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {T} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_rtriangle_lms_action_prop {t} { +\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {t} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\int_use:N \g_@@_tile_int} + {\int_use:N \g_@@_tiles_int} } - \tl_set:Nx \l__penrose_tmpc_tl + \tl_set:Nx \l_@@_tmpc_tl { - {\int_use:N \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_rtriangle_lms_action_prop {G} { +\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {G} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_rtriangle_lms_action_prop {g} { +\prop_gput:Nnn \g_@@_rtriangle_lms_action_prop {g} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_ktriangle_lms_action_prop {T} { +\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {T} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_ktriangle_lms_action_prop {t} { +\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {t} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_ktriangle_lms_action_prop {G} { +\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {G} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_ktriangle_lms_action_prop {g} { +\prop_gput:Nnn \g_@@_ktriangle_lms_action_prop {g} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + Penrose~ tile~ \int_use:N \g_@@_tile_int/.try, + Penrose~ tile/.try/.expand~ once=\l_@@_tmpc_tl ]{golden~ gnomon} \group_end: } @@ -1143,239 +1542,239 @@ and the derived files penrose.ins % % 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} +\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_put:Nnn \g__penrose_pentagon_lms_action_prop {+} +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {+} {\pgftransformrotate{72}} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {*} +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {*} {\pgftransformrotate{144}} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {-} +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {-} {\pgftransformrotate{288}} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {_} +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {_} {\pgftransformrotate{216}} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {>} +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {>} {\pgftransformrotate{180}} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {|} +\prop_gput:Nnn \g_@@_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 +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {s} { + \fp_set:Nn \l_@@_tmpa_fp { - 1/(2 + 2 * cosd(72) ) * \l__penrose_step_dim + 1/(2 + 2 * cosd(72) ) * \l_@@_step_dim } - \dim_set:Nn \l__penrose_step_dim {\fp_to_dim:N \l__penrose_tmpa_fp} + \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_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_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_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_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_put:Nnn \g__penrose_pentagon_lms_action_prop {d} { - \fp_set:Nn \l__penrose_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__penrose_step_dim + (tand(54)/2 - tand(72)/2 + sind(36) ) * \l_@@_step_dim } - \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp} } -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {e} { - \fp_set:Nn \l__penrose_tmpa_fp +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {e} { + \fp_set:Nn \l_@@_tmpa_fp { - tand(54) * cosd(36) * \l__penrose_step_dim + tand(54) * cosd(36) * \l_@@_step_dim } - \pgftransformyshift{\fp_to_dim:N \l__penrose_tmpa_fp} + \pgftransformyshift{\fp_to_dim:N \l_@@_tmpa_fp} } % \end{macrocode} % % \begin{macrocode} -\prop_put:Nnn \g__penrose_pentagon_lms_action_prop {P} { +\prop_gput:Nnn \g_@@_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_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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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__penrose_pentagon_parity_seq - {\l__penrose_pentagon_parity_int} + \seq_item:Nn \l_@@_pentagon_parity_seq + {\l_@@_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 + 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_put:Nnn \g__penrose_pentagon_lms_action_prop {Q} { +\prop_gput:Nnn \g_@@_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_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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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__penrose_pentagon_parity_seq - {\l__penrose_pentagon_parity_int} + \seq_item:Nn \l_@@_pentagon_parity_seq + {\l_@@_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 + 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_put:Nnn \g__penrose_pentagon_lms_action_prop {R} { +\prop_gput:Nnn \g_@@_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_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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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__penrose_pentagon_parity_seq - {\l__penrose_pentagon_parity_int} + \seq_item:Nn \l_@@_pentagon_parity_seq + {\l_@@_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 + 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_put:Nnn \g__penrose_pentagon_lms_action_prop {G} { +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {G} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_pentagon_lms_action_prop {B} { +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {B} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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_put:Nnn \g__penrose_pentagon_lms_action_prop {D} { +\prop_gput:Nnn \g_@@_pentagon_lms_action_prop {D} { \group_begin: - \int_gincr:N \l__penrose_tile_int + \int_gincr:N \g_@@_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 + \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 \l__penrose_tile_int} - {\int_use:N \l__penrose_tiles_int} + {\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 \l__penrose_tile_int/.try, - Penrose~ tile/.try/.expand~ once=\l__penrose_tmpc_tl + 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]{\penrose_make_lms:Nnnn} +% \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 \penrose_make_lms:Nnnn #1#2#3#4 +\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__penrose_tmpb_tl {#4} + \tl_set:Nn \l_@@_tmpb_tl {#4} % \end{macrocode} % We repeat the specified number of times. % \begin{macrocode} @@ -1383,50 +1782,50 @@ and the derived files penrose.ins % \end{macrocode} % Duplicate the current state. % \begin{macrocode} - \tl_set_eq:NN \l__penrose_tmpa_tl \l__penrose_tmpb_tl + \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmpb_tl % \end{macrocode} % Clear the receiving token list. % \begin{macrocode} - \tl_clear:N \l__penrose_tmpb_tl + \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__penrose_tmpa_tl + \tl_map_inline:Nn \l_@@_tmpa_tl { % \end{macrocode} % If a rule exists, copy that. % \begin{macrocode} - \prop_if_in:cnTF {g__penrose_#2_lms_rule_prop} {##1} + \prop_if_in:cnTF {g_@@_#2_lms_rule_prop} {##1} { - \tl_put_right:Nx \l__penrose_tmpb_tl - {\prop_item:cn {g__penrose_#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__penrose_tmpb_tl {##1} + \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__penrose_tmpa_tl { + \tl_set:Nn \l_@@_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 + \tl_put_right:Nx \l_@@_tmpa_tl {{\tl_use:N \l_@@_tmpb_tl}} + \tl_use:N \l_@@_tmpa_tl } -\cs_generate_variant:Nn \penrose_make_lms:Nnnn {Nnnx} +\cs_generate_variant:Nn \@@_make_lms:Nnnn {Nnnx} % \end{macrocode} % \end{macro} % -% \begin{macro}[internal]{\penrose_invoke_lms:Nn} +% \begin{macro}[internal]{\@@_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 +\cs_new_nopar:Npn \@@_invoke_lms:Nn #1#2 { \group_begin: % \end{macrocode} @@ -1435,14 +1834,14 @@ and the derived files penrose.ins % Otherwise, just do nothing. % \begin{macrocode} \tl_map_inline:Nn #1 { - \prop_if_in:cnTF {g__penrose_#2_lms_action_prop} {##1} + \prop_if_in:cnTF {g_@@_#2_lms_action_prop} {##1} { - \prop_item:cn {g__penrose_#2_lms_action_prop} {##1} + \prop_item:cn {g_@@_#2_lms_action_prop} {##1} } { - \prop_if_in:cnT {g__penrose_default_lms_action_prop} {##1} + \prop_if_in:cnT {g_@@_default_lms_action_prop} {##1} { - \prop_item:cn {g__penrose_default_lms_action_prop} {##1} + \prop_item:cn {g_@@_default_lms_action_prop} {##1} } } } @@ -1453,11 +1852,11 @@ and the derived files penrose.ins % % We keep track of the number of tiles. % \begin{macrocode} -\int_new:N \l__penrose_tile_int -\int_new:N \l__penrose_tiles_int +\int_new:N \g_@@_tile_int +\int_new:N \g_@@_tiles_int % \end{macrocode} % -% \begin{macro}[internal]{\PenroseDecomposition} +% \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} @@ -1465,39 +1864,39 @@ and the derived files penrose.ins { \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} + \@@_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{macro} +% \end{function} % -% \begin{macro}[internal]{\penrose_count_lms:N} +% \begin{macro}[internal]{\@@_count_lms:N} % This counts the number of tiles in the string. % \begin{macrocode} -\cs_new_nopar:Npn \penrose_count_lms:N #1 +\cs_new_nopar:Npn \@@_count_lms:N #1 { - \int_gzero:N \l__penrose_tiles_int + \int_gzero:N \g_@@_tiles_int \tl_map_inline:Nn #1 { \tl_if_eq:nnT {##1} {T} { - \int_incr:N \l__penrose_tiles_int + \int_gincr:N \g_@@_tiles_int } \tl_if_eq:nnT {##1} {t} { - \int_incr:N \l__penrose_tiles_int + \int_gincr:N \g_@@_tiles_int } \tl_if_eq:nnT {##1} {G} { - \int_incr:N \l__penrose_tiles_int + \int_gincr:N \g_@@_tiles_int } \tl_if_eq:nnT {##1} {g} { - \int_incr:N \l__penrose_tiles_int + \int_gincr:N \g_@@_tiles_int } } } @@ -1508,7 +1907,7 @@ and the derived files penrose.ins % \begin{macrocode} \tikzset{ Penrose~ step/.code={ - \dim_set:Nn \l__penrose_step_dim {#1} + \dim_set:Nn \l_@@_step_dim {#1} } } % \end{macrocode} @@ -2717,8 +3116,11 @@ and the derived files penrose.ins } % \end{macrocode} % -% \iffalse -% -% \fi +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% %\Finale \endinput diff --git a/graphics/pgf/contrib/penrose/penrose_code.pdf b/graphics/pgf/contrib/penrose/penrose_code.pdf index b30a2d3442..59579b2524 100644 Binary files a/graphics/pgf/contrib/penrose/penrose_code.pdf and b/graphics/pgf/contrib/penrose/penrose_code.pdf differ diff --git a/graphics/pgf/contrib/spath3/README b/graphics/pgf/contrib/spath3/README index a9d1fe6210..dad3e28a92 100644 --- a/graphics/pgf/contrib/spath3/README +++ b/graphics/pgf/contrib/spath3/README @@ -1,6 +1,6 @@ ---------------------------------------------------------------- spath3 --- LaTeX3 functions for manipulating PGF soft paths -E-mail: stacey@math.ntnu.no +E-mail: loopspace@mathforge.org Released under the LaTeX Project Public License v1.3c or later See http://www.latex-project.org/lppl.txt ---------------------------------------------------------------- diff --git a/graphics/pgf/contrib/spath3/calligraphy.pdf b/graphics/pgf/contrib/spath3/calligraphy.pdf new file mode 100644 index 0000000000..f2852f4d1b Binary files /dev/null and b/graphics/pgf/contrib/spath3/calligraphy.pdf differ diff --git a/graphics/pgf/contrib/spath3/calligraphy.tex b/graphics/pgf/contrib/spath3/calligraphy.tex new file mode 100644 index 0000000000..7690e5c5b7 --- /dev/null +++ b/graphics/pgf/contrib/spath3/calligraphy.tex @@ -0,0 +1,271 @@ +\immediate\write18{tex spath3_doc.dtx} +\documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{trace} +\usepackage{lmodern} +\usepackage{morefloats} +\usepackage{tikz} +\usetikzlibrary{decorations.pathreplacing,calligraphy,matrix} +\usepackage[numbered]{hypdoc} +\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} + +\usepackage{listings} +\lstloadlanguages{[LaTeX]TeX} +\lstset{ + breakatwhitespace=true, + breaklines=true, + language=[LaTeX]TeX, + basicstyle=\small\ttfamily, + keepspaces=true, + columns=fullflexible +} + +\usepackage{fancyvrb} + +\newenvironment{example} + {\VerbatimEnvironment + \begin{VerbatimOut}{example.out}} + {\end{VerbatimOut} + \begin{center} + \setlength{\parindent}{0pt} + \fbox{\begin{minipage}{.9\linewidth} + \lstinputlisting[]{example.out} + \end{minipage}} + + \fbox{\begin{minipage}{.9\linewidth} + \input{example.out} + \end{minipage}} +\end{center} +} + +\providecommand*{\url}{\texttt} +\GetFileInfo{spath3.sty} + +\title{The \textsf{calligraphy} Package: Documentation} +\author{Andrew Stacey \\ \url{loopspace@mathforge.org}} +\date{\fileversion~from \filedate} + +\begin{document} + +\maketitle + + \section{Pre-Introduction} + This library is built on top of a package for manipulating PGF's \emph{soft paths} called \texttt{spath3}. + Version 2.0 of \texttt{spath3} involved considerable reorganisation of the code. + I tried to ensure that this didn't affect this library but it is extremely likely that I wasn't fully successful. + If something that used to work no longer does, please do let me know either by opening an issue on github (\url{https://github.com/loopspace/spath3}) or at the above email. + + \section{Introduction} +The \Verb+calligraphy+ TikZ library is designed to enable calligraphic style drawings in TikZ. +The idea is to be able to ``stroke'' a line with a ``pen''. +As a simple example, compare the two lines in the following picture. + +\begin{example} +\begin{center} +\begin{tikzpicture} +\pen (-135:.25) -- (45:.25); +\draw[line width=.5cm] (0,0) .. controls +(45:1) and +(-135:1) .. ++(3,0); +\calligraphy (0,-1) .. controls +(45:1) and +(-135:1) .. ++(3,0); +\end{tikzpicture} +\end{center} +\end{example} + +The paths are identical in definition but the first is drawn using the standard TikZ path with a line width of .5cm. +The second is ``stroked'' with a calligraphic pen of width .5cm angled at 45 degrees. +\section{How It Works} +To know how to use this library, it is worth knowing a little about how it works. +A ``pen'' is a path, as is the line that is the template for the pen stroke. +The two paths are joined together to form a region which is filled. +Thus in constructing the example given in the introduction, the following path is built. +\begin{center} +\begin{tikzpicture} +\draw (0,-1) .. controls +(45:1) and +(-135:1) .. node (op) {} ++(3,0) -- node (pp) {} ++(45:.5) .. controls +(-135:1) and +(45:1) .. node (opr) {} ++(-3,0) -- node (ppr) {} (0,-1); +\draw[<-] (op) -- ++(0,-.5) node[anchor=north] {original path}; +\draw[<-] (pp) -- ++(.5,0) node[anchor=west] {pen path}; +\draw[<-] (opr) -- ++(0,.5) node[anchor=south] {original path reversed}; +\draw[<-] (ppr) -- ++(-.5,0) node[anchor=east] {pen path reversed}; +\end{tikzpicture} +\end{center} +What is important to note about this is that the ``pen'' isn't \emph{actually} dragged along the path, it is merely a simulation. +This can be shown with the following simple example. +The first is a continuous path that goes past the angle of the pen and thus the upstroke would involve pushing the pen. +The second is how it is meant to be done, the second line is drawn from top to bottom. +However, as the direction of the path isn't important, the same effect can be obtained by ``lifting the nib'' between the lines. +\begin{example} +\begin{center} +\begin{tikzpicture} +\pen (-135:.125) -- (45:.125); +\calligraphy (0,0) -- (1,0) -- (1,1); +\calligraphy (2,0) -- (3,0) (3,1) -- (3,0); +\calligraphy (4,0) -- (5,0) +(0,0) -- (5,1); +\end{tikzpicture} +\end{center} +\end{example} +It should work as expected providing the following golden rule is not violated: +\begin{quotation} +Never \emph{push} a calligraphic pen. +\end{quotation} +This is good advice for ordinary calligraphy as well, so a path that is realisable as an honest calligraphic path should be fine with this library. +Actually since, as remarked above, the direction of the path isn't important, a more accurate golden rule would be that one should never swap from pushing to pulling or vice versa without lifting the pen off the paper; but that isn't as succinct. +The paths for both pens and templates can be reasonably complicated. +They can contain gaps, but should not contain closed paths, nor rectangles. +The implementation works by breaking a path into its constituent pieces (broken up by ``move to''s) and working bit by bit. +\begin{example} +\begin{center} +\begin{tikzpicture} +\pen (-135:.25) -- (-135:.125) (45:.125) -- (45:.25); +\calligraphy (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-4) (0,-4) .. controls +(45:1) and +(-135:1) .. +(3,0); +\end{tikzpicture} +\end{center} +\end{example} +\section{Copperplate} +Copperplate pens are somewhat special. +They are ``thin'' so don't need the same treatment as a ``thick'' pen, but one should be able to vary the pressure with a copperplate pen to get a variation of thickness. +Specifying a copperplate pen is straightforward: it is a pen with no thickness. +\begin{example} +\begin{center} +\begin{tikzpicture}[line width=2pt] +\pen (0,0); +\calligraphy[heavy] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); +\calligraphy[light] (4,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (4,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); +\end{tikzpicture} +\end{center} +\end{example} +With a copperplate pen, the segments of a path are tapered. +Copperplate and normal pens can be mixed. +Any part of the pen specification that has no length is treated as a copperplate pen. +\begin{example} +\begin{center} +\begin{tikzpicture}[line width=1pt] +\pen (-135:.125) -- (0,0) (45:.125); +\calligraphy (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); +\end{tikzpicture} +\end{center} +\end{example} +%% \section{Annotations} +%% As an addition, calligraphic paths can be annotated to show how they were constructed. +%% A path with an arrow is drawn at a set offset from the last part of the path. +%% \begin{example} +%% \begin{center} +%% \begin{tikzpicture}[line width=1pt] +%% \pen (-135:.125) -- (0,0) (45:.125); +%% \calligraphy[annotate] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); +%% \end{tikzpicture} +%% \end{center} +%% \end{example} +\section{Style Options} +There are plenty of options for styling the paths and pens. +\subsection{Definition Options} +Internally, making a pen is a two-step process. +First a pen has to be \emph{defined} and then \emph{processed}. +To define a pen, the user has to specify a path. +That path is stored in a global macro and so can be accessed in throughout the document. +However, before being used, the pen has to be processed. +At this stage, the pen is converted from a macro in to a special object. +These special objects are local and cannot (at present) be made global. +Thus whilst a pen can be \emph{defined} inside a group, the \emph{processing} stage has to happen in the outermost group in which the pen is going to be used. +There is a shortcut command that (via a bit of suspicious hackery) does all this within a \Verb+tikzpicture+ group. +However, if a pen is to be used in several different pictures, it must be processed outside the group in which it is defined. +The following macros and keys are used to set up and use a pen. +%All the keys are in the \Verb+/pgf/calligraphy+ family. +\begin{itemize} +\item \DescribeMacro{define pen}If the \Verb+define pen+ key is specified on a path then that path will be used to define a pen. +It can take one option which will be the pen name, if not specified then \Verb+default+ is assumed. +The resulting path will not be counted for bounding box considerations. +When the pen is used, the origin will correspond to the path along which it is dragged. +\item \DescribeMacro{pen name}The key \Verb+pen name=name+ sets the name for the current pen. +This can be used either when defining or using a pen. +\item \DescribeMacro{\pen}\DescribeMacro{\definepen}The macros \Verb+\pen+ and \Verb+\definepen+ are analogous to the TikZ commands \Verb+\draw+ or \Verb+\fill+ in that they act like a path command but store the path as a pen. +The difference between them is that \Verb+\definepen+ is to be used outside a TikZ picture (it contains its own \Verb+\tikz+ command) and \Verb+\pen+ inside. +%% These macros also change the ``key family'' to \Verb+/pgf/calligraphy+ so that any further options do not need their full path. +%% \item \DescribeMacro{\processpen}The macro \Verb+\processpen+ processes a pen so that it is set up for using later on. +%% As remarked earlier, it has to be given at least at the outermost grouping of where it will be used. +%% It takes an optional argument which is the pen name. +%% This is only needed if the pen will be used in a group other than the one in which it is defined (or if the hackery that means this isn't needed with the \Verb+\pen+ command fails for some unknown reason). +\item \DescribeMacro{use pen}The key \Verb+use pen=name+ on a path means that that path should be ``stroked'' with the pen (\Verb+default+ if no name is given, or none specified via the \Verb+pen name+ key). +%% \item \DescribeMacro{\calligraphy}The macro \Verb+\calligraphy+ is a shortcut for specifying a path with the key \Verb+use pen+ already set. +%% This macro also changes the ``key family'' to \Verb+/pgf/calligraphy+ so that any further options do not need their full path. +\end{itemize} +\subsection{Style Options} +There are various options available for styling the calligraphic paths. +%% All of these are in the \Verb+/pgf/calligraphy+ key family, but the \Verb+\calligraphy+ command automatically switches to that family so the key path is not needed. +%% Any unknown keys are processed as follows: +%% \begin{enumerate} +%% \item A check is made to see if a pen of that name has been defined. +%% If so, that pen is used. +%% This is similar to the \Verb+\node[shape]+ syntax +%% \item A check is made to see if the unknown key corresponds to a colour. +%% If so, that colour is installed as the pen colour. +%% This is similar to the colour handling of TikZ paths. +%% (In fact, it uses the same code.) +%% \item All other unknown options are passed on to TikZ. +%% \end{enumerate} +The style options are as follows. +\begin{itemize} +\item \DescribeMacro{pen colour}The \Verb+pen colour+ style defines the default colour to be used. +Since calligraphic paths are sometimes filled and sometimes stroked, this ensures that the colour is used correctly. +\item \DescribeMacro{nib style}It is possible to style particular ``nibs'' (i.e., segments of the pen path) separately. +This is the \Verb+nib style+ option, which takes two arguments. +The first is the index of the part of the nib and the second is the style options to be applied. +\item \DescribeMacro{stroke style}It is also possible to style particular parts of the template path. +One way to do this is to use the \Verb+stroke style+ key, which takes two arguments. +The first is the index of the part of the stroke and the second is the style options to be applied. +\item \DescribeMacro{this stroke style}It is also possible to style particular parts of the template path as the path is constructed. +This is done by putting \Verb+[this stroke style={}]+ in the template path at the relevant part. +The style is saved and applied to that segment of the template path. +\item \DescribeMacro{taper}The tapering of copperplate paths can be controled by the \Verb+taper+ option. +It takes arguments \Verb+none+, \Verb+both+, \Verb+start+, and \Verb+end+. +\item \DescribeMacro{weight}\DescribeMacro{heavy}\DescribeMacro{light}Copperplate paths come in two ``weights'': \emph{heavy} and \emph{light}. +The weight also affects the tapering: by default a light path is tapered to nothing whilst a heavy path is tapered to the width of a light path. +Weights can be specified by either \Verb+weight=weight+ or just \Verb+heavy+ and \Verb+light+. +It is possible to change the weight for different components of a path using the \Verb+stroke style+ key. +With tapering, this means that one can easily vary from a light stroke to a heavy one. +The relevant widths are controlled by the keys \DescribeMacro{heavy line width}\Verb+heavy line width+ and the \DescribeMacro{light line width}\Verb+light line width+. +The \DescribeMacro{taper line width}\Verb+taper line width+, is set automatically by the weight but can be altered afterwards using the \Verb+taper line width+ key. +%% \item \DescribeMacro{annotate}The key \Verb+annotate+ switches on annotations. +%% The style of the annotations is controlled by the keys \DescribeMacro{annotation style}\Verb+annotation style+, \DescribeMacro{annotation shift}\Verb+annotation shift+ which controls how the annotation path is shifted from the final component of the calligraphic path, \DescribeMacro{annotation nodes style}\Verb+annotation nodes style+ for global style of the nodes, \DescribeMacro{annotation node style}\Verb+annotation node style+ for styling of particular nodes. +%% This latter takes two options: the node number and the style to be applied. +%% The annotation path and annotation node styles take ordinary TikZ styling options. +\end{itemize} +\begin{example} +\begin{center} +\begin{tikzpicture} +\calligraphy[pen colour=green,nib style={2}{color=red}] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); +\calligraphy[line width=1pt] (0,-4) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-7) .. controls +(45:1) and +(-135:1) .. +(3,0); +\end{tikzpicture} +\end{center} +\end{example} +\section{Decorations} +If a TikZ/PGF decorations library is loaded prior to this library, then the \Verb+calligraphy+ library defines some decorations that use the calligraphic paths, specifically with the copperplate nib. +The current decorations are: +\begin{itemize} +\item \DescribeMacro{calligraphic brace}\Verb+calligraphic brace+ for a brace. +\item \DescribeMacro{calligraphic straight parenthesis}\Verb+calligraphic straight parenthesis+ for a parenthesis with straight middle component. +\item \DescribeMacro{calligraphic curved parenthesis}\Verb+calligraphic curved parenthesis+ for a parenthesis with a curved middle component. +\end{itemize} +All the above use the \Verb+amplitude+ option to specify their size. +The following is an example of their use, together with the standard \Verb+brace+ and the \Verb+delimiter+ key from the \Verb+matrix+ library for comparison. +\begin{example} +\begin{center} +\begin{tikzpicture} +\draw[decorate,decoration={calligraphic brace,amplitude=4mm},ultra thick] (0,0) -- (0,8); +\draw[line width=2pt,decorate,decoration={brace,amplitude=10},line cap=round] (1,0) -- ++(0,8); +\node[anchor=south west,minimum height=8cm,outer sep=0pt,left delimiter=\{] (a) at (2,0) {}; +\draw[decorate,decoration={calligraphic straight parenthesis,amplitude=4mm},ultra thick] (3,0) -- ++(0,8); +\draw[decorate,decoration={calligraphic curved parenthesis,amplitude=4mm},ultra thick] (4,0) -- ++(0,8); +\node[anchor=south west,minimum height=8cm,outer sep=0pt,left delimiter=(] (a) at (5,0) {}; +\end{tikzpicture} +\end{center} +\end{example} +\section{Pre-Defined Pens} +The following pens are predefined: +\begin{itemize} +\item \DescribeMacro{copperplate}\Verb+copperplate+: +\begin{example} +\begin{center} +\tikz \calligraphy[copperplate] (0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={light,taper=start}] +(0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={heavy}] +(0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={light,taper=end}]; +\end{center} +\end{example} +\end{itemize} + +\end{document} diff --git a/graphics/pgf/contrib/spath3/calligraphy_doc.pdf b/graphics/pgf/contrib/spath3/calligraphy_doc.pdf deleted file mode 100644 index 12a0313d8a..0000000000 Binary files a/graphics/pgf/contrib/spath3/calligraphy_doc.pdf and /dev/null differ diff --git a/graphics/pgf/contrib/spath3/calligraphy_doc.tex b/graphics/pgf/contrib/spath3/calligraphy_doc.tex deleted file mode 100644 index c1b88c9e8e..0000000000 --- a/graphics/pgf/contrib/spath3/calligraphy_doc.tex +++ /dev/null @@ -1,258 +0,0 @@ -\immediate\write18{tex spath3.dtx} -\documentclass{ltxdoc} -\usepackage[T1]{fontenc} -\usepackage{trace} -\usepackage{lmodern} -\usepackage{morefloats} -\usepackage{tikz} -\usetikzlibrary{decorations.pathreplacing,calligraphy,matrix} -\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}{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} -} - -\providecommand*{\url}{\texttt} -\GetFileInfo{spath3.sty} - -\title{The \textsf{calligraphy} Package: Documentation} -\author{Andrew Stacey \\ \url{stacey@math.ntnu.no}} -\date{\fileversion~from \filedate} - -\begin{document} - -\maketitle -% \section{Introduction} -The \Verb+calligraphy+ TikZ library is designed to enable calligraphic style drawings in TikZ. -The idea is to be able to ``stroke'' a line with a ``pen''. -As a simple example, compare the two lines in the following picture. - -\begin{example} -\begin{center} -\begin{tikzpicture} -\pen (-135:.25) -- (45:.25); -\draw[line width=.5cm] (0,0) .. controls +(45:1) and +(-135:1) .. ++(3,0); -\calligraphy (0,-1) .. controls +(45:1) and +(-135:1) .. ++(3,0); -\end{tikzpicture} -\end{center} -\end{example} - -The paths are identical in definition but the first is drawn using the standard TikZ path with a line width of .5cm. -The second is ``stroked'' with a calligraphic pen of width .5cm angled at 45 degrees. -\section{How It Works} -To know how to use this library, it is worth knowing a little about how it works. -A ``pen'' is a path, as is the line that is the template for the pen stroke. -The two paths are joined together to form a region which is filled. -Thus in constructing the example given in the introduction, the following path is built. -\begin{center} -\begin{tikzpicture} -\draw (0,-1) .. controls +(45:1) and +(-135:1) .. node (op) {} ++(3,0) -- node (pp) {} ++(45:.5) .. controls +(-135:1) and +(45:1) .. node (opr) {} ++(-3,0) -- node (ppr) {} (0,-1); -\draw[<-] (op) -- ++(0,-.5) node[anchor=north] {original path}; -\draw[<-] (pp) -- ++(.5,0) node[anchor=west] {pen path}; -\draw[<-] (opr) -- ++(0,.5) node[anchor=south] {original path reversed}; -\draw[<-] (ppr) -- ++(-.5,0) node[anchor=east] {pen path reversed}; -\end{tikzpicture} -\end{center} -What is important to note about this is that the ``pen'' isn't \emph{actually} dragged along the path, it is merely a simulation. -This can be shown with the following simple example. -The first is a continuous path that goes past the angle of the pen and thus the upstroke would involve pushing the pen. -The second is how it is meant to be done, the second line is drawn from top to bottom. -However, as the direction of the path isn't important, the same effect can be obtained by ``lifting the nib'' between the lines. -\begin{example} -\begin{center} -\begin{tikzpicture} -\pen (-135:.125) -- (45:.125); -\calligraphy (0,0) -- (1,0) -- (1,1); -\calligraphy (2,0) -- (3,0) (3,1) -- (3,0); -\calligraphy (4,0) -- (5,0) +(0,0) -- (5,1); -\end{tikzpicture} -\end{center} -\end{example} -It should work as expected providing the following golden rule is not violated: -\begin{quotation} -Never \emph{push} a calligraphic pen. -\end{quotation} -This is good advice for ordinary calligraphy as well, so a path that is realisable as an honest calligraphic path should be fine with this library. -Actually since, as remarked above, the direction of the path isn't important, a more accurate golden rule would be that one should never swap from pushing to pulling or vice versa without lifting the pen off the paper; but that isn't as succinct. -The paths for both pens and templates can be reasonably complicated. -They can contain gaps, but should not contain closed paths, nor rectangles. -The implementation works by breaking a path into its constituent pieces (broken up by ``move to''s) and working bit by bit. -\begin{example} -\begin{center} -\begin{tikzpicture} -\pen (-135:.25) -- (-135:.125) (45:.125) -- (45:.25); -\calligraphy (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-4) (0,-4) .. controls +(45:1) and +(-135:1) .. +(3,0); -\end{tikzpicture} -\end{center} -\end{example} -\section{Copperplate} -Copperplate pens are somewhat special. -They are ``thin'' so don't need the same treatment as a ``thick'' pen, but one should be able to vary the pressure with a copperplate pen to get a variation of thickness. -Specifying a copperplate pen is straightforward: it is a pen with no thickness. -\begin{example} -\begin{center} -\begin{tikzpicture}[line width=2pt] -\pen (0,0); -\calligraphy[heavy] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); -\calligraphy[light] (4,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (4,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); -\end{tikzpicture} -\end{center} -\end{example} -With a copperplate pen, the segments of a path are tapered. -Copperplate and normal pens can be mixed. -Any part of the pen specification that has no length is treated as a copperplate pen. -\begin{example} -\begin{center} -\begin{tikzpicture}[line width=1pt] -\pen (-135:.125) -- (0,0) (45:.125); -\calligraphy (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); -\end{tikzpicture} -\end{center} -\end{example} -%% \section{Annotations} -%% As an addition, calligraphic paths can be annotated to show how they were constructed. -%% A path with an arrow is drawn at a set offset from the last part of the path. -%% \begin{example} -%% \begin{center} -%% \begin{tikzpicture}[line width=1pt] -%% \pen (-135:.125) -- (0,0) (45:.125); -%% \calligraphy[annotate] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); -%% \end{tikzpicture} -%% \end{center} -%% \end{example} -\section{Style Options} -There are plenty of options for styling the paths and pens. -\subsection{Definition Options} -Internally, making a pen is a two-step process. -First a pen has to be \emph{defined} and then \emph{processed}. -To define a pen, the user has to specify a path. -That path is stored in a global macro and so can be accessed in throughout the document. -However, before being used, the pen has to be processed. -At this stage, the pen is converted from a macro in to a special object. -These special objects are local and cannot (at present) be made global. -Thus whilst a pen can be \emph{defined} inside a group, the \emph{processing} stage has to happen in the outermost group in which the pen is going to be used. -There is a shortcut command that (via a bit of suspicious hackery) does all this within a \Verb+tikzpicture+ group. -However, if a pen is to be used in several different pictures, it must be processed outside the group in which it is defined. -The following macros and keys are used to set up and use a pen. -%All the keys are in the \Verb+/pgf/calligraphy+ family. -\begin{itemize} -\item \DescribeMacro{define pen}If the \Verb+define pen+ key is specified on a path then that path will be used to define a pen. -It can take one option which will be the pen name, if not specified then \Verb+default+ is assumed. -The resulting path will not be counted for bounding box considerations. -When the pen is used, the origin will correspond to the path along which it is dragged. -\item \DescribeMacro{pen name}The key \Verb+pen name=name+ sets the name for the current pen. -This can be used either when defining or using a pen. -\item \DescribeMacro{\pen}\DescribeMacro{\definepen}The macros \Verb+\pen+ and \Verb+\definepen+ are analogous to the TikZ commands \Verb+\draw+ or \Verb+\fill+ in that they act like a path command but store the path as a pen. -The difference between them is that \Verb+\definepen+ is to be used outside a TikZ picture (it contains its own \Verb+\tikz+ command) and \Verb+\pen+ inside. -%% These macros also change the ``key family'' to \Verb+/pgf/calligraphy+ so that any further options do not need their full path. -%% \item \DescribeMacro{\processpen}The macro \Verb+\processpen+ processes a pen so that it is set up for using later on. -%% As remarked earlier, it has to be given at least at the outermost grouping of where it will be used. -%% It takes an optional argument which is the pen name. -%% This is only needed if the pen will be used in a group other than the one in which it is defined (or if the hackery that means this isn't needed with the \Verb+\pen+ command fails for some unknown reason). -\item \DescribeMacro{use pen}The key \Verb+use pen=name+ on a path means that that path should be ``stroked'' with the pen (\Verb+default+ if no name is given, or none specified via the \Verb+pen name+ key). -%% \item \DescribeMacro{\calligraphy}The macro \Verb+\calligraphy+ is a shortcut for specifying a path with the key \Verb+use pen+ already set. -%% This macro also changes the ``key family'' to \Verb+/pgf/calligraphy+ so that any further options do not need their full path. -\end{itemize} -\subsection{Style Options} -There are various options available for styling the calligraphic paths. -%% All of these are in the \Verb+/pgf/calligraphy+ key family, but the \Verb+\calligraphy+ command automatically switches to that family so the key path is not needed. -%% Any unknown keys are processed as follows: -%% \begin{enumerate} -%% \item A check is made to see if a pen of that name has been defined. -%% If so, that pen is used. -%% This is similar to the \Verb+\node[shape]+ syntax -%% \item A check is made to see if the unknown key corresponds to a colour. -%% If so, that colour is installed as the pen colour. -%% This is similar to the colour handling of TikZ paths. -%% (In fact, it uses the same code.) -%% \item All other unknown options are passed on to TikZ. -%% \end{enumerate} -The style options are as follows. -\begin{itemize} -\item \DescribeMacro{pen colour}The \Verb+pen colour+ style defines the default colour to be used. -Since calligraphic paths are sometimes filled and sometimes stroked, this ensures that the colour is used correctly. -\item \DescribeMacro{nib style}It is possible to style particular ``nibs'' (i.e., segments of the pen path) separately. -This is the \Verb+nib style+ option, which takes two arguments. -The first is the index of the part of the nib and the second is the style options to be applied. -\item \DescribeMacro{stroke style}It is also possible to style particular parts of the template path. -One way to do this is to use the \Verb+stroke style+ key, which takes two arguments. -The first is the index of the part of the stroke and the second is the style options to be applied. -\item \DescribeMacro{this stroke style}It is also possible to style particular parts of the template path as the path is constructed. -This is done by putting \Verb+[this stroke style={}]+ in the template path at the relevant part. -The style is saved and applied to that segment of the template path. -\item \DescribeMacro{taper}The tapering of copperplate paths can be controled by the \Verb+taper+ option. -It takes arguments \Verb+none+, \Verb+both+, \Verb+start+, and \Verb+end+. -\item \DescribeMacro{weight}\DescribeMacro{heavy}\DescribeMacro{light}Copperplate paths come in two ``weights'': \emph{heavy} and \emph{light}. -The weight also affects the tapering: by default a light path is tapered to nothing whilst a heavy path is tapered to the width of a light path. -Weights can be specified by either \Verb+weight=weight+ or just \Verb+heavy+ and \Verb+light+. -It is possible to change the weight for different components of a path using the \Verb+stroke style+ key. -With tapering, this means that one can easily vary from a light stroke to a heavy one. -The relevant widths are controlled by the keys \DescribeMacro{heavy line width}\Verb+heavy line width+ and the \DescribeMacro{light line width}\Verb+light line width+. -The \DescribeMacro{taper line width}\Verb+taper line width+, is set automatically by the weight but can be altered afterwards using the \Verb+taper line width+ key. -%% \item \DescribeMacro{annotate}The key \Verb+annotate+ switches on annotations. -%% The style of the annotations is controlled by the keys \DescribeMacro{annotation style}\Verb+annotation style+, \DescribeMacro{annotation shift}\Verb+annotation shift+ which controls how the annotation path is shifted from the final component of the calligraphic path, \DescribeMacro{annotation nodes style}\Verb+annotation nodes style+ for global style of the nodes, \DescribeMacro{annotation node style}\Verb+annotation node style+ for styling of particular nodes. -%% This latter takes two options: the node number and the style to be applied. -%% The annotation path and annotation node styles take ordinary TikZ styling options. -\end{itemize} -\begin{example} -\begin{center} -\begin{tikzpicture} -\calligraphy[pen colour=green,nib style={2}{color=red}] (0,0) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-3) .. controls +(45:1) and +(-135:1) .. +(3,0); -\calligraphy[line width=1pt] (0,-4) .. controls +(45:1) and +(-135:1) .. +(3,0) ++(1.5,0) .. controls +(-135:2) and +(45:2) .. +(0,-3) (0,-7) .. controls +(45:1) and +(-135:1) .. +(3,0); -\end{tikzpicture} -\end{center} -\end{example} -\section{Decorations} -If a TikZ/PGF decorations library is loaded prior to this library, then the \Verb+calligraphy+ library defines some decorations that use the calligraphic paths, specifically with the copperplate nib. -The current decorations are: -\begin{itemize} -\item \DescribeMacro{calligraphic brace}\Verb+calligraphic brace+ for a brace. -\item \DescribeMacro{calligraphic straight parenthesis}\Verb+calligraphic straight parenthesis+ for a parenthesis with straight middle component. -\item \DescribeMacro{calligraphic curved parenthesis}\Verb+calligraphic curved parenthesis+ for a parenthesis with a curved middle component. -\end{itemize} -All the above use the \Verb+amplitude+ option to specify their size. -The following is an example of their use, together with the standard \Verb+brace+ and the \Verb+delimiter+ key from the \Verb+matrix+ library for comparison. -\begin{example} -\begin{center} -\begin{tikzpicture} -\draw[decorate,decoration={calligraphic brace,amplitude=4mm},ultra thick] (0,0) -- (0,8); -\draw[line width=2pt,decorate,decoration={brace,amplitude=10},line cap=round] (1,0) -- ++(0,8); -\node[anchor=south west,minimum height=8cm,outer sep=0pt,left delimiter=\{] (a) at (2,0) {}; -\draw[decorate,decoration={calligraphic straight parenthesis,amplitude=4mm},ultra thick] (3,0) -- ++(0,8); -\draw[decorate,decoration={calligraphic curved parenthesis,amplitude=4mm},ultra thick] (4,0) -- ++(0,8); -\node[anchor=south west,minimum height=8cm,outer sep=0pt,left delimiter=(] (a) at (5,0) {}; -\end{tikzpicture} -\end{center} -\end{example} -\section{Pre-Defined Pens} -The following pens are predefined: -\begin{itemize} -\item \DescribeMacro{copperplate}\Verb+copperplate+: -\begin{example} -\begin{center} -\tikz \calligraphy[copperplate] (0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={light,taper=start}] +(0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={heavy}] +(0,0) .. controls +(1,-1) and +(-1,1) .. ++(3,0) [this stroke style={light,taper=end}]; -\end{center} -\end{example} -\end{itemize} - -\end{document} \ No newline at end of file diff --git a/graphics/pgf/contrib/spath3/knots.pdf b/graphics/pgf/contrib/spath3/knots.pdf new file mode 100644 index 0000000000..b1962a3c4c Binary files /dev/null and b/graphics/pgf/contrib/spath3/knots.pdf differ diff --git a/graphics/pgf/contrib/spath3/knots.tex b/graphics/pgf/contrib/spath3/knots.tex new file mode 100644 index 0000000000..20859a1d4e --- /dev/null +++ b/graphics/pgf/contrib/spath3/knots.tex @@ -0,0 +1,516 @@ +\immediate\write18{tex spath3_code.dtx} +\documentclass{ltxdoc} +\usepackage[T1]{fontenc} +\usepackage{trace} +\usepackage{lmodern} +\usepackage{morefloats} +\usepackage{tikz} +\usetikzlibrary{knots,spath3,hobby} +\usepackage[numbered]{hypdoc} +\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} + +\usepackage{listings} +\lstloadlanguages{[LaTeX]TeX} +\lstset{ + breakatwhitespace=true, + breaklines=true, + language=[LaTeX]TeX, + basicstyle=\small\ttfamily, + keepspaces=true, + columns=fullflexible +} + +\usepackage{fancyvrb} + +\newenvironment{example} + {\VerbatimEnvironment + \begin{VerbatimOut}{example.out}} + {\end{VerbatimOut} + \begin{center} + \setlength{\parindent}{0pt} + \fbox{\begin{minipage}{.9\linewidth} + \lstinputlisting[]{example.out} + \end{minipage}} + + \fbox{\begin{minipage}{.9\linewidth} + \centering + \input{example.out} + \end{minipage}} +\end{center} +} + +\providecommand*{\url}{\texttt} +\GetFileInfo{spath3.sty} + +\title{The \textsf{knots} Package: Documentation} +\author{Andrew Stacey \\ \url{loopspace@mathforge.org}} +\date{\fileversion~from \filedate} + +\begin{document} + +\maketitle + +\section{Pre-Introduction} + +This library is built on top of a package for manipulating PGF's \emph{soft paths} called \texttt{spath3}. + Version 2.0 of \texttt{spath3} involved considerable reorganisation of the code. + I tried to ensure that this didn't affect this library but it is extremely likely that I wasn't fully successful. + If something that used to work no longer does, please do let me know either by opening an issue on github (\url{https://github.com/loopspace/spath3}) or at the above email. + + That version of \texttt{spath3} also introduced an alternative way of drawing knots which involves breaking the paths at their crossing points and introducing actual gaps. + This makes it easier to do things like have the knots on non-uniform backgrounds, and to style different parts of the knot differently such as illustrating a \(3\)--colouring. + To see how that works, look at the documentation of the \texttt{spath3} TikZ library. + Here's an example of how to draw a knot with that library. + + \begin{example} +\begin{tikzpicture}[ + use Hobby shortcut, + every trefoil component/.style={ultra thick, draw}, + trefoil component 1/.style={red}, + trefoil component 2/.style={blue}, + trefoil component 3/.style={green}, +] +\path[spath/save=trefoil] ([closed]90:2) foreach \k in {1,...,3} { .. (-30+\k*240:.5) .. (90+\k*240:2) } (90:2); +\tikzset{spath/knot={trefoil}{8pt}{1,3,5}} +\end{tikzpicture} +\end{example} + + +\section{Introduction} + +The \Verb+knots+ package is a TikZ library for drawing knot (and similar) diagrams. +It provides a few useful styles and node shapes but its main contribution is the \Verb+knot+ environment. +The \Verb+knot+ environment allows you to draw some strands of a knot (or braid or tangle or whatever -- we shall use the imprecise term ``knot'' to refer to any similar diagram) and then to modify the crossings via a simple interface. + +The main part of this package was developed in response to a question on the \href{http://tex.stackexchange.com}{TeX-SX} site by Jamie Vicary. +The original question was \href{http://tex.stackexchange.com/q/32125/86}{Braid diagrams in TikZ}. +Jamie's comment (quoted below) was the inspiration for the mechanism of the \Verb+knot+ environment. + +\begin{quotation} +[It] would be really cool if it was possible to draw the curves, let TikZ calculate all the intersection points automatically, and then tell it to redraw the intersections according to an under/over specification... do you think this is in the realm of plausibility? +\end{quotation} + +\section{Examples} + +Let us begin with an example. +To use the library, simply load the \Verb+tikz+ package and add \Verb+knots+ to the list of TikZ libraries that you load. +For example, the following in your preamble would work: + +\begin{verbatim} +\usepackage{tikz} +\usetikzlibrary{knots} +\end{verbatim} + +Let's draw a simple tangle (actually a braid). + +\begin{example} +\begin{tikzpicture} +\draw[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\draw[blue,ultra thick] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{tikzpicture} +\end{example} + +Now a common way to draw crossings for knots is to draw a gap in the under strand through which the over strand passes. +One way to achieve this in TikZ is to draw the over strand twice, the first time with a thicker line width and the colour of the background. +We'll draw it twice, once with background a different colour to illustrate this. + +\begin{example} +\begin{tikzpicture} +\draw[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\draw[pink,double=blue,ultra thick,double distance=1.6pt] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\draw[xshift=5cm,red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\draw[xshift=5cm,white,double=blue,ultra thick,double distance=1.6pt] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{tikzpicture} +\end{example} + +Now the problem with this method is that there is no way to draw the red and blue paths so that the blue is the over strand at the first crossing and the red at the second. +Either the blue path is always on top (as shown) or the red. +One way to resolve this is to split the paths and draw one of them in segments: + +\begin{example} +\begin{tikzpicture} +\draw[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1); +\draw[white,double=blue,ultra thick,double distance=1.6pt] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\draw[white,double=red,double distance=1.6pt,ultra thick] (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\end{tikzpicture} +\end{example} + +Another method (employed by the \Verb+braids+ package) is to break the under path either side of the crossing and not draw it there. +This means that the order of drawing doesn't matter. + +Both of these methods have their drawbacks (particularly for general knots as opposed to the more structured braids) in that they require a detailed knowledge of the pieces of the paths and the positions of the crossings. +As pointed out by Jamie Vicary in the above-{}quoted comment, TikZ should be able to compute these itself. + +That's what this package does. + +Let's do the above example using this package. +The main changes to the drawing are that we use the command \Verb+\strand+ rather than \Verb+\draw+ and we enclose it in the \Verb+knot+ environment. +When initially drawing the strands it is useful to provide the option \Verb+draft mode=strands+. +That's because the detailed computation can take a little time and so it is best only to do it when necessary. +So on first run through we get the following. + +\begin{example} +\begin{tikzpicture} +\begin{knot}[ + draft mode=strands +] +\strand[red,thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\strand[blue,thick] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{knot} +\end{tikzpicture} +\end{example} + +Once we're happy with the positioning of the strands, we change the option \Verb+draft mode=strands+ to \Verb+draft mode=crossings+. + +\begin{example} +\begin{tikzpicture} +\path (2,1.5) (2,-.5); +\begin{knot}[ + draft mode=crossings, + clip width=5, +] +\strand[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\strand[blue,ultra thick] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{knot} +\end{tikzpicture} +\end{example} + +The \Verb+\path (2,1.5) (2,-.5);+ is to extend the bounding box of the picture a little upwards. +The extra pieces are not used when computing the bounding box of the picture so that it doesn't change position on the page. + +The extra information is that the strands and the crossings have been numbered. +The crossings have also been rendered (the \Verb+clip width+ option enlarges the crossing gap to make it more obvious). +Unfortunately, for both crossings the red path is on top. +We need to flip one of these crossings (the first). +To do this, we either use the command \Verb+flipcrossings+ or the \Verb+flip crossing+ key. + +\begin{example} +\begin{tikzpicture} +\path (2,1.5) (2,-.5); +\begin{knot}[ + draft mode=crossings, + clip width=5, + flip crossing=1, +] +\strand[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\strand[blue,ultra thick] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{knot} +\end{tikzpicture} +\end{example} + +Once we're happy with it, we remove the \Verb+draft mode+ option to render it in its final form. + +\begin{example} +\begin{tikzpicture} +\begin{knot}[ + clip width=5, + flip crossing=1, +] +\strand[red,ultra thick] (0,0) .. controls +(1,0) and +(-1,0) .. (2,1) .. controls +(1,0) and +(-1,0) .. (4,0); +\strand[blue,ultra thick] (0,1) .. controls +(1,0) and +(-1,0) .. (2,0) .. controls +(1,0) and +(-1,0) .. (4,1); +\end{knot} +\end{tikzpicture} +\end{example} + +Here's a more complicated example. + +\begin{example} +\begin{tikzpicture} +\node (A) at (0,4) [draw,minimum width=30pt,minimum height=10pt,thick] {}; +\begin{knot}[ + clip width=5, + clip radius=8pt, +] +\strand [thick,only when rendering/.style={dashed}] (0,0) +to [out=up, in=down] (-1,1) +to [out=up, in=down] (0,2) +to [out=up, in=down] (-1.2,4) +to [out=up, in=down, looseness=0.7] (0,5.5) +to [out=up, in=down] (-2,7); +\strand [thick] (-1,0) +to [out=up, in=down] (1,2) +to [out=up, in=down] (A.south); +\strand [thick,blue] (1,0) +to [out=up, in=down] (-1,2) +to [out=up, in=down] (1.5,4) +to [out=up, in=right] (0,5.5)to [out=left, in=up] (-2,4) +to [out=down, in=up] (-2,0); +\strand [thick] (A.150) +to [out=up, in=down] (0.7,5.5) +to [out=up, in=down] (0,7); +\strand [thick] (A.30) +to [out=up, in=down] (-1,6) +to [out=up, in=down] (2,7); +\flipcrossings{6,2,9,5,11} +\end{knot} +\end{tikzpicture} +\end{example} + +One feature about this example is the \Verb+only when rendering+ key. +The gaps are made by drawing the strand again with extra thickness in the background colour. +If the \Verb+dashed+ option were always in play for that strand, the gap would be dashed which would spoil the effect. +So the \Verb+only when rendering+ key gathers those options (such as a dash pattern) which should only be applied to the rendered strand and not to the redraw that creates the gap. + +Here's another example. + +\begin{example} +\newcommand{\motif}[1]{ + to ++(180+#1:0.50) arc (270+#1:150+#1:0.15) + to ++( 60+#1:0.50) arc (-30+#1:150+#1:0.15) + to ++(240+#1:0.25) arc (150+#1:330+#1:0.25) + to ++( 60+#1:0.55) arc (150+#1: 30+#1:0.20) +} +\newcommand{\celticknot}{\motif{0}\motif{120}\motif{240}} +\begin{tikzpicture} +\begin{knot}[ + line width=2pt, + line join=round, + clip width=2, + scale=5, + consider self intersections, + ignore endpoint intersections=false, + background color=white, + only when rendering/.style={ + draw=red, + double=white, + double distance=6pt, + line cap=round, + } +] +\strand (0,0) \celticknot; +\flipcrossings{1,3,6,8,10} +\end{knot} +\end{tikzpicture} +\end{example} + +In this case the strand is a single path. +In the standard case crossings are only considered between separate strands (since the algorithm used by TikZ means that a strand intersects itself infinitely often). +The key \Verb+consider self intersections+ gets round this by ``exploding'' the strand into segments and considering each as a separate path with regard to finding the intersections. + +A path consists of a series of lines and B\'ezier cubics. +The ``explosion'' of a path uses this decomposition. +Unfortunately, even that is not always enough as it is possible for a B\'ezier cubic to self-intersect. +The \Verb+consider self intersections+ also splits these B\'ezier curves in two to ensure that this doesn't happen\footnote{Computing when this is strictly necessary is difficult so it splits more than it needs to to ensure that enough are done.}. +To disable this, use the \Verb+consider self intersections=no splits+ option. +This is the recommended option. + +\begin{example} +\begin{tikzpicture} +\begin{knot}[ + consider self intersections, + draft mode=crossings, +] +\strand (0,0) .. controls +(3,1) and +(-3,1) .. (1,0); +\end{knot} +\begin{knot}[ + xshift=3cm, + consider self intersections=no splits, + draft mode=crossings, +] +\strand (0,0) .. controls +(3,1) and +(-3,1) .. (1,0); +\end{knot} +\end{tikzpicture} +\end{example} + +Finally, given that TikZ has to do some heavy computation to find the intersections, it is worth considering using the \Verb+external+ library of TikZ to avoid having to do this on every run. + +\section{Usage} + +\subsection{The \texttt{knot} Environment} + +\DescribeMacro{knot} +\DescribeMacro{\strand} +This package provides a \Verb+knot+ environment for including in a \Verb+tikzpicture+ to render a knot. +This takes an optional argument which is passed to \Verb+\tikzset+ and can be used to configure the knot. +Within that environment, specific strands are defined using the \Verb+\strand+ command (in place of a \Verb+\path+ or \Verb+\draw+). +Further keys can be specified on the strands. + +\DescribeMacro{flip crossing} +\DescribeMacro{\flipcrossings} +Specifying the crossings to be flipped can be done either using the key \Verb+flip crossing+ or the macro \Verb+\flipcrossings+. +The latter can take a comma separated list of crossings to flip. +The former takes a single crossing but can be extended to a comma separated list using the \Verb+.list+ handler as in \Verb+flip crossing/.list={1,2,3}+ (this is what \Verb+\flipcrossings+ does internally). + +\DescribeMacro{\redraw} +There is also a macro \Verb+\redraw+ which redraws a strand in the neighbourhood of a point. +This is effectively what happens for the crossings and can be used to fix something that wasn't done correctly by the main algorithm. +It takes two arguments, the strand number and the point at which to render the strand, as in \Verb+\redraw{2}{(1,1)}+. + +\subsection{Keys} + +The various keys are as follows. +The majority of the keys are in the \Verb+/tikz/knot diagram+ family, but it does its best to pass unknown keys down to \Verb+/tikz/+. +The keys processed by the \Verb+knot+ environment are automatically in this family but the keys processed by the \Verb+\strand+ command are not. +If a standard key (in the option to the \Verb+knot+ environment) doesn't work, try prefixing it with \Verb+/tikz/+ or \Verb+/pgf/+. + +\begin{itemize} +\item \DescribeMacro{every knot diagram} +The style \Verb+every knot diagram+ is executed at the start of the \Verb+knot+ environment. + +Note that it is inside the \Verb+knot diagram+ family so if setting it outside (say, in the preamble) use \Verb+\tikzset{knot diagram/every knot diagram}+. + +\item \DescribeMacro{name} +The crossings of a knot are given coordinates of the form \Verb+ +. +The default name is \Verb+knot+. +The \Verb+name+ key renames it. + +\item \DescribeMacro{every strand} +The contents of \Verb+every strand+ are applied to every strand. +By default this contains the \Verb+draw+ key so if resetting it you should probably ensure that it still has the \Verb+draw+ key. + +Note that it is inside the \Verb+knot diagram+ family so if setting it outside (say, in the preamble) use \Verb+\tikzset{knot diagram/every knot diagram}+. + +\item \DescribeMacro{only when rendering} +The key \Verb+only when rendering={