diff options
author | Norbert Preining <norbert@preining.info> | 2023-01-16 03:03:27 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2023-01-16 03:03:27 +0000 |
commit | 6f9e1680085e7bb4d258f6f8116369d122e196e1 (patch) | |
tree | 9ac0ecb239240d1d672b188f29c1479de215074b /graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex | |
parent | b8345f39630408bb198e7636381ce4240154ca9b (diff) |
CTAN sync 202301160303
Diffstat (limited to 'graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex')
-rw-r--r-- | graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex b/graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex deleted file mode 100644 index 07abbb441b..0000000000 --- a/graphics/pgf/base/doc/text-en/pgfmanual-en-library-lsystems.tex +++ /dev/null @@ -1,390 +0,0 @@ -% Copyright 2019 by Mark Wibrow -% -% This file may be distributed and/or modified -% -% 1. under the LaTeX Project Public License and/or -% 2. under the GNU Public License. -% -% See the file doc/generic/pgf/licenses/LICENSE for more details. - - -\section{Lindenmayer System Drawing Library} - -\subsection{Overview} - -Lindenmayer systems (also commonly known as ``L-systems''), were originally -developed by Aristid Lindenmayer as a theory of algae growth patterns and then -subsequently used to model branching patterns in plants and produce fractal -patterns. Typically, an L-system consists of a set of symbols, each of which is -associated with some graphical action (such as ``turn left'' or ``move -forward'') and a set of rules (``production'' or ``rewrite'' rules). Given a -string of symbols, the rewrite rules are applied several times and the when -resulting string is processed the action associated with each symbol is -executed. - -In \pgfname, L-systems can be used to create simple 2-dimensional fractal -patterns\ldots -% -\begin{codeexample}[ - preamble={\usetikzlibrary{lindenmayersystems}}, - pre={\expandafter\let\csname pgf@lsystem@Koch curve\endcsname=\relax}, -] -\begin{tikzpicture} -\pgfdeclarelindenmayersystem{Koch curve}{ - \rule{F -> F-F++F-F} -} - -\shadedraw [top color=white, bottom color=blue!50, draw=blue!50!black] - [l-system={Koch curve, step=2pt, angle=60, axiom=F++F++F, order=3}] - lindenmayer system -- cycle; -\end{tikzpicture} -\end{codeexample} -% -\noindent\ldots and ``plant like'' patterns\ldots -% -\begin{codeexample}[preamble={\usetikzlibrary{lindenmayersystems}}] -\begin{tikzpicture} -\draw [green!50!black, rotate=90] - [l-system={rule set={F -> FF-[-F+F]+[+F-F]}, axiom=F, order=4, step=2pt, - randomize step percent=25, angle=30, randomize angle percent=5}] - lindenmayer system; -\end{tikzpicture} -\end{codeexample} -% -\noindent \ldots but it is important to bear in mind that even moderately -complex L-systems can exceed the available memory of \TeX, and can be very -slow. If possible, you are advised to increase the main memory and save stack -to their maximum possible values for your particular \TeX{} distribution. -However, even by doing this you may find you still run out of memory quite -quickly. - -For an excellent introduction to L-systems (containing some ``really cool'' -pictures -- many of which are sadly not possible in \pgfname) see \emph{The -Algorithmic Beauty of Plants} by Przemyslaw Prusinkiewicz and Aristid -Lindenmayer (which is freely available via the internet). - -\begin{pgflibrary}{lindenmayersystems} - This \pgfname-library provides basic commands for defining and using simple - L-systems. The \tikzname-library provides, furthermore, a front end for - using L-systems in \tikzname. -\end{pgflibrary} - - -\subsubsection{Declaring L-systems} - -Before an L-system can be used, it must be declared using the following -command: - -\begin{command}{\pgfdeclarelindenmayersystem\marg{name}\marg{specification}} - This command declares a Lindenmayer system called \meta{name}. The - \meta{specification} argument contains a description of the L-system's - symbols and rules. Two commands |\symbol| and |\rule| are only defined when - the \meta{specification} argument is executed. - - \begin{command}{\symbol\marg{name}\marg{code}} - This defines a symbol called \meta{name} for a specific L-system, - and associates it with \meta{code}. - - A symbol should consist of a single alpha-numeric character (i.e., - |A|-|Z|, |a|-|z| or |0|-|9|). The symbols |F|, |f|, |+|, |-|, |[| and - |]| are available by default so do not need to be defined for each - L-system. However, if you are feeling adventurous, they can be - redefined for specific L-systems if required. The L-system treats the - default symbols as follows (the commands they execute are described - below): - % - \begin{itemize} - \item |F| move forward a certain distance, drawing a line. Uses - |\pgflsystemdrawforward|. - \item |f| move forward a certain distance, without drawing a line. - Uses |\pgflsystemmoveforward|. - \item |+| turn left by some angle. Uses |\pgflsystemturnleft|. - \item |-| turn right by some angle. Uses |\pgflsystemturnright|. - \item |[| save the current state (i.e., the position and - direction). Uses |\pgflsystemsavestate|. - \item |]| restore the last saved state. Uses - |\pgflsystemrestorestate|. - \end{itemize} - - The symbols |[| and |]| act like a stack: |[| pushes the state of the - L-system on to the stack, and |]| pops a state off the stack. - - When \meta{code} is executed, the transformation matrix is set up so - that the origin is at the current position and the positive x-axis - ``points forward'', so |\pgfpathlineto{\pgfpoint{1cm}{0cm}}| draws a - line 1cm forward. - - The following keys can alter the production of an L-system. However, - they do not store values in themselves. - - \begin{key}{/pgf/lindenmayer system/step=\meta{length} (initially 5pt)} - How far the L-system moves forward if required. This key sets the - \TeX{} dimension |\pgflsystemstep|. - \end{key} - - \begin{key}{/pgf/lindenmayer system/randomize step percent=\meta{percentage} (initially 0)} - If the step is to be randomized, this key specifies by how much. - The value is stored in the \TeX{} macro - |\pgflsystemrandomizesteppercent|. - \end{key} - - \begin{key}{/pgf/lindenmayer system/left angle=\meta{angle} (initially 90)} - This key sets the angle through which the L-system turns when it - turns left. The value is stored in the \TeX{} macro - |\pgflsystemrleftangle|. - \end{key} - - \begin{key}{/pgf/lindenmayer system/right angle=\meta{angle} (initially 90)} - This key sets the angle through which the L-system turns when it - turns right. The value is stored in the \TeX{} macro - |\pgflsystemrrightangle|. - \end{key} - - \begin{key}{/pgf/lindenmayer system/randomize angle percent=\meta{percentage} (initially 0)} - If the angles are to be randomized, this key specifies by how much. - The value is stored in the \TeX{} macro - |\pgflsystemrandomizeanglepercent|. - \end{key} - - For speed and convenience, when the code for a symbol is executed, the - following commands are available. - - \begin{command}{\pgflsystemcurrentstep} - The current ``step'' of the L-system (i.e., how far the system - will move forward if required). This is initially set to the - value in the \TeX-dimensions |\pgflsystemstep|, but the actual - value may be changed if |\pgflsystemrandomizestep| is used - (see below). - \end{command} - - \begin{command}{\pgflsystemcurrentleftangle} - The angle the L-system will turn when it turns left. - The value stored in this macro may be changed if - |\pgflsystemrandomizeleftangle| is used. - \end{command} - - \begin{command}{\pgflsystemcurrentrightangle} - The angle the L-system will turn when it turns right. - The value stored in this macro may be changed if - |\pgflsystemrandomizerightangle| is used. - \end{command} - - The following commands may be useful if you wish to define your own - symbols. - - \begin{command}{\pgflsystemrandomizestep} - Randomizes the value in |\pgflsystemcurrentstep| according to the - current value of the key |randomize step percent|. - \end{command} - - \begin{command}{\pgflsystemrandomizeleftangle} - Randomizes the value in |\pgflsystemcurrentleftangle| according to - the value of the |randomize angle percent| key. - \end{command} - - \begin{command}{\pgflsystemrandomizerightangle} - Randomizes the value in |\pgflsystemcurrentrightangle| according - to the value of the |randomize angle| key. - \end{command} - - \begin{command}{\pgflsystemdrawforward} - Move forward in the current direction, by |\pgflsystemcurrentstep|, - drawing a line in the process. This macro calls - |\pgflsystemrandomizestep|. Internally, \pgfname{} simply shifts - the transformation matrix in the positive direction of the current - (transformed) x-axis by |\pgflsystemstep| and then executes a - line-to to the (newly transformed) origin. - \end{command} - - \begin{command}{\pgflsystemmoveforward} - Move forward in the current direction, by |\pgflsystemcurrentstep|, - without drawing a line. This macro calls - |\pgflsystemrandomizestep|. \pgfname{} executes a transformation as - above, but executes a move-to to the (newly transformed) origin. - \end{command} - - \begin{command}{\pgflsystemturnleft} - Turn left by |\pgflsystemcurrentleftangle|. Internally, \pgfname{} - simply rotates the transformation matrix. This macro calls - |\pgflsystemrandomizeleftangle|. - \end{command} - - \begin{command}{\pgflsystemturnright} - Turn right by |\pgflsystemcurrentrightangle|. Internally, - \pgfname{} simply rotates the transformation matrix. This macro - calls |\pgflsystemrandomizerightangle|. - \end{command} - - \begin{command}{\pgflsystemsavestate} - Save the current position and orientation. Internally, \pgfname{} - simply starts a new \TeX-group. - \end{command} - - \begin{command}{\pgflsystemrestorestate} - Restore the last saved position and orientation. Internally, - \pgfname{} closes a \TeX-group, restoring the transformation matrix - of the outer scope, and a move-to command is executed to the - (transformed) origin. - \end{command} - \end{command} - - \begin{command}{\rule{\ttfamily\char`\{}\meta{head}{\ttfamily->}\meta{body}{\ttfamily\char`\}}} - Declare a rule. \meta{head} should consist of a single symbol, which - need not have been declared using |\symbol| or exist as a default - symbol (in fact, the more interesting L-systems depend on using symbols - with no corresponding code, to control the ``growth'' of the system). - \meta{body} consists of a string of symbols, which again need not - necessarily have any code associated with them. - \end{command} - - As an example, the following shows an L-system that uses some of these - commands. This example illustrates the point that some symbols, in this - case |A| and |B|, do not have to have code associated with them. They - simply control the growth of the system. - % -\begin{codeexample}[ - preamble={\usetikzlibrary{lindenmayersystems}}, - pre={\nullfont\expandafter\let\csname pgf@lsystem@Hilbert curve\endcsname=\relax}, -] -\pgfdeclarelindenmayersystem{Hilbert curve}{ - \symbol{X}{\pgflsystemdrawforward} - \symbol{+}{\pgflsystemturnright} % Explicitly define + and - symbols. - \symbol{-}{\pgflsystemturnleft} - \rule{A -> +BX-AXA-XB+} - \rule{B -> -AX+BXB+XA-} -} -\tikz\draw[lindenmayer system={Hilbert curve, axiom=A, order=4, angle=90}] - lindenmayer system; -\end{codeexample} - % -\end{command} - - -\subsection{Using Lindenmayer Systems} - -\subsubsection{Using L-Systems in PGF} - -The following command is used to run an L-system in \pgfname: -% -\begin{command}{\pgflindenmayersystem\marg{name}\marg{axiom}\marg{order}} - Runs the L-system called \meta{name} using the input string \meta{axiom} - for \meta{order} iterations. In general, prior to calling this command, the - transformation matrix should be set appropriately for shifting and - rotating, and a move-to to the (transformed) origin should be executed. - This origin will be where the L-system starts. In addition, the relevant - keys should be set appropriately. - % -\begin{codeexample}[preamble={\usetikzlibrary{lindenmayersystems}}] -\begin{tikzpicture} - \draw [help lines] grid (3,2); - \pgfset{lindenmayer system/.cd, angle=60, step=2pt} - \foreach \x/\y in {0cm/1cm, 1.5cm/1.5cm, 2.5cm/0.5cm, 1cm/0cm}{ - \pgftransformshift{\pgfqpoint{\x}{\y}} - \pgfpathmoveto{\pgfpointorigin} - \pgflindenmayersystem{Koch curve}{F++F++F}{2} - \pgfusepath{stroke} - } -\end{tikzpicture} -\end{codeexample} - - Note that it is perfectly feasible for an L-system to define special - symbols which perform the move-to and use-path operations. - % -\end{command} - - -\subsubsection{Using L-Systems in Ti\emph{k}Z} - -In \tikzname, an L-system is created using a path operation. However, -\tikzname{} is more flexible regarding the positioning of the L-system and also -provides keys to create L-systems ``on-line''. - -\begin{pathoperation}{lindenmayer system}{ \opt{|[|\meta{keys}|]|}} - This will run an L-system according to the parameters specified in - \meta{keys} (which can also contain normal \tikz{} keys such as |draw| or - |thin|). The syntax is flexible regarding the L-system parameters and the - following all do the same thing: - % -\begin{codeexample}[code only] -\draw lindenmayer system [lindenmayer system={Hilbert curve, axiom=4, order=3}]; -\end{codeexample} - -\begin{codeexample}[code only] -\draw [lindenmayer system={Hilbert curve, axiom=4, order=3}] lindenmayer system; -\end{codeexample} - -\begin{codeexample}[code only] -\tikzset{lindenmayer system={Hilbert curve, axiom=4, order=3}} -\draw lindenmayer system; -\end{codeexample} - % -\end{pathoperation} - -\begin{pathoperation}{l-system}{ \opt{|[|\meta{keys}|]|}} - A more compact version of the |lindenmayer system| path command. -\end{pathoperation} - -This library adds some additional keys for specifying L-systems. These keys -only work in \tikzname{} and all have the same path, namely, |/pgf/lindenmayer| -|system|, but the following keys are provided for convenience, so that you do -not have to keep repeating this path: - -\begin{stylekey}{/pgf/lindenmayer system=\marg{keys}} -\keyalias{tikz} - This key changes the key path to |/pgf/lindenmayer systems| and executes - \meta{keys}. -\end{stylekey} - -\begin{stylekey}{/pgf/l-system=\marg{keys}} -\keyalias{tikz} - A more compact version of the previous key. -\end{stylekey} - -\begin{key}{/pgf/lindenmayer system/name=\marg{name}} - Sets the name for the L-system. -\end{key} - -\begin{key}{/pgf/lindenmayer system/axiom=\marg{string}} - Sets the axiom (or input string) for the L-system. -\end{key} - -\begin{key}{/pgf/lindenmayer system/order=\marg{integer}} - Sets the number of iterations the L-system will perform. -\end{key} - -\begin{key}{/pgf/lindenmayer system/rule set=\marg{list}} - This key allows an (anonymous) L-system to be declared ``on-line''. There - is, however, a restriction that only the default symbols can be used for - drawing (empty symbols can still be used to control the growth of the - system). The rules in \meta{list} should be separated by commas. - % -\begin{codeexample}[preamble={\usetikzlibrary{lindenmayersystems}}] -\tikz[rotate=65]\draw [green!60!black] l-system - [l-system={rule set={F -> F[+F]F[-F]}, axiom=F, order=4, angle=25,step=3pt}]; -\end{codeexample} - % -\end{key} - -\begin{key}{/pgf/lindenmayer system/anchor=\meta{anchor}} - Be default, when this key is not used, the L-system will start from the - last specified coordinate. By using this key, the L-system will be placed - inside a special (rectangle) node which can be positioned using - \meta{anchor}. - % -\begin{codeexample}[preamble={\usetikzlibrary{lindenmayersystems}}] -\begin{tikzpicture}[l-system={step=1.75pt, order=5, angle=60}] - \pgfdeclarelindenmayersystem{Sierpinski triangle}{ - \symbol{X}{\pgflsystemdrawforward} - \symbol{Y}{\pgflsystemdrawforward} - \rule{X -> Y-X-Y} - \rule{Y -> X+Y+X} - } - \draw [help lines] grid (3,2); - \draw [red] (0,0) l-system - [l-system={Sierpinski triangle, axiom=+++X, anchor=south west}]; - \draw [blue] (3,2) l-system - [l-system={Sierpinski triangle, axiom=X, anchor=north east}]; -\end{tikzpicture} -\end{codeexample} - % -\end{key} |