Current File : //usr/share/texlive/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex |
% Copyright 2018 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.
\newdimen\pgflsystemstep
\newcount\c@pgf@lsystem@iteration
\newif\ifpgf@lsystem@randomize@step
\newif\ifpgf@lsystem@randomize@angle
\pgfkeys{/pgf/lindenmayer system/.cd,%
step/.code={\pgfmathsetlength\pgflsystemstep{#1}},%
randomize step percent/.code={%
\pgfmathparse{#1}%
\let\pgflsystemrandomizesteppercent=\pgfmathresult%
\ifdim\pgfmathresult pt=0pt\relax%
\pgf@lsystem@randomize@stepfalse%
\else%
\pgf@lsystem@randomize@steptrue%
\fi%
},%
left angle/.code={\pgfmathparse{#1}\let\pgflsystemleftangle=\pgfmathresult},%
right angle/.code={\pgfmathparse{#1}\let\pgflsystemrightangle=\pgfmathresult},%
angle/.style={/pgf/lindenmayer system/left angle=#1, /pgf/lindenmayer system/right angle=#1},%
randomize angle percent/.code={%
\pgfmathparse{#1}%
\let\pgflsystemrandomizeanglepercent=\pgfmathresult%
\ifdim\pgfmathresult pt=0pt\relax%
\pgf@lsystem@randomize@anglefalse%
\else%
\pgf@lsystem@randomize@angletrue%
\fi%
}%
}%
\pgfkeys{/pgf/lindenmayer system/.cd,
step=5pt,%
randomize step percent=0,%
angle=90,%
randomize angle percent=0%
}%
\long\def\pgfdeclarelindenmayersystem#1#2{%
\pgfutil@ifundefined{pgf@lsystem@#1}%
{%
\begingroup%
\edef\pgf@lsystem@name{#1}%
\expandafter\global\expandafter\let\csname pgf@lsystem@#1\endcsname=\pgf@lsystem@name%
\let\symbol=\pgf@lsystem@symbol%
\let\rule=\pgf@lsystem@rule%
#2%
\endgroup%
}%
{\pgferror{Lindenmayer system `#1' is already defined}}%
}%
\def\pgf@lsystem@symbol#1#2{%
\expandafter\gdef\csname pgf@lsystem@\pgf@lsystem@name @symbol@#1\endcsname{#2}%
}%
\def\pgf@lsystem@rule#1{\expandafter\pgf@lsystem@rule@#1\pgf@stop}%
\def\pgf@lsystem@rule@#1{\def\pgf@lsystem@rule@head{#1}\pgf@lsystem@rule@@}%
\def\pgf@lsystem@rule@@#1->{% Now some `fooling around' to deal with unwanted spaces.
\let\pgf@lsystem@rule@body=\pgfutil@empty%
\pgfutil@ifnextchar x{\pgf@lsystem@rule@@@}{\pgf@lsystem@rule@@@}}%
\def\pgf@lsystem@rule@@@#1{%
\ifx#1\pgf@stop%
\expandafter\global\expandafter\let%
\csname pgf@lsystem@\pgf@lsystem@name @rule@\pgf@lsystem@rule@head\endcsname=\pgf@lsystem@rule@body%
\else%
\edef\pgf@lsystem@rule@body{\pgf@lsystem@rule@body#1}%
\expandafter\pgf@lsystem@rule@@@%
\fi%
}%
\def\pgflindenmayersystem#1#2#3{%
\begingroup%
\edef\pgf@lsystem@name{#1}%
\edef\pgf@lsystem@axiom{#2}%
\pgfmathtruncatemacro\pgf@lsystem@order{#3}%
%
\let\pgf@lsystem@current@symbol=\relax%
%
\c@pgf@lsystem@iteration=0\relax%
%
\ifnum\pgf@lsystem@order=0\relax%
\expandafter\pgf@lsystem@draw\pgf@lsystem@axiom\pgf@stop
\let\pgf@lsystem@next=\pgf@lsystem@end%
\else%
\let\pgf@lsystem@next=\pgf@lsystem@run%
\fi%
\expandafter\pgf@lsystem@next\pgf@lsystem@axiom\pgf@lsystem@stop%
}%
\def\pgf@lsystem@run#1{%
\ifx#1\pgf@lsystem@stop%
\def\pgf@lsystem@token{\pgf@lsystem@stop}%
\let\pgf@lsystem@next=\pgf@lsystem@end%
\else%
\ifx#1\pgf@stop%
\advance\c@pgf@lsystem@iteration by-1\relax%
\let\pgf@system@token=\pgfutil@empty%
\let\pgf@lsystem@next=\pgf@lsystem@run%
\else%
% Does #1 appear on the RHS of a rule...?
\expandafter\let\expandafter\pgf@lsystem@token\expandafter=%
\csname pgf@lsystem@\pgf@lsystem@name @rule@#1\endcsname%
\ifx\pgf@lsystem@token\relax%
% ...nope. So draw it straight away.
\pgf@lsystem@draw#1\pgf@stop%
\let\pgf@lsystem@token=\pgfutil@empty%
\else%
% ...yep. So, if the order has been reached draw the LHS
% immediately. Otherwise add the LHS to the token stream
% and continue.
\advance\c@pgf@lsystem@iteration by1\relax%
\ifnum\c@pgf@lsystem@iteration=\pgf@lsystem@order%
\expandafter\pgf@lsystem@draw\pgf@lsystem@token \pgf@stop%
\advance\c@pgf@lsystem@iteration by-1\relax%
\let\pgf@lsystem@token=\pgfutil@empty%
\else%
\expandafter\def\expandafter\pgf@lsystem@token\expandafter{\pgf@lsystem@token \pgf@stop}%
\fi%
\fi%
\let\pgf@lsystem@next=\pgf@lsystem@run%
\fi%
\fi%
\expandafter\pgf@lsystem@next\pgf@lsystem@token}%
\def\pgf@lsystem@end#1\pgf@lsystem@stop{\endgroup}%
\def\pgf@lsystem@draw#1{%
\ifx#1\pgf@stop%
\let\pgf@lsystem@next=\relax%
\else%
\expandafter\let\expandafter\pgf@lsystem@current@symbol\expandafter=%
\csname pgf@lsystem@\pgf@lsystem@name @symbol@#1\endcsname%
\ifx\pgf@lsystem@current@symbol\relax% Try a default symbol.
\expandafter\let\expandafter\pgf@lsystem@current@symbol\expandafter=%
\csname pgf@lsystem@symbol@default@#1\endcsname%
\fi%
\let\pgf@lsystem@next=\pgf@lsystem@@draw%
\fi%
\pgf@lsystem@next}%
\def\pgf@lsystem@@draw{%
\edef\pgflsystemcurrentstep{\the\pgflsystemstep}%
\let\pgflsystemcurrentrightangle=\pgflsystemrightangle%
\let\pgflsystemcurrentrightangle=\pgflsystemleftangle%
\pgf@lsystem@current@symbol%
\pgf@lsystem@draw}%
\expandafter\def\csname
pgf@lsystem@symbol@default@F\endcsname{\pgflsystemdrawforward}%
\expandafter\def\csname
pgf@lsystem@symbol@default@f\endcsname{\pgflsystemmoveforward}%
\expandafter\def\csname
pgf@lsystem@symbol@default@+\endcsname{\pgflsystemturnleft}%
\expandafter\def\csname
pgf@lsystem@symbol@default@-\endcsname{\pgflsystemturnright}%
\expandafter\def\csname
pgf@lsystem@symbol@default@[\endcsname{\pgflsystemsavestate}%
\expandafter\def\csname
pgf@lsystem@symbol@default@]\endcsname{\pgflsystemrestorestate}%
\def\pgflsystemradonmizestep{%
\ifpgf@lsystem@randomize@step%
\pgfmathrand%
\pgf@x=\pgflsystemrandomizesteppercent pt\relax%
\pgf@x=\pgfmathresult\pgf@x%
\divide\pgf@x by20\relax%
\advance\pgf@x by\pgflsystemstep\relax%
\edef\pgflsystemcurrentstep{\the\pgf@x}%
\else%
\edef\pgflsystemcurrentstep{\the\pgflsystemstep}%
\fi%
}%
\def\pgflsystemdrawforward{%
\pgflsystemradonmizestep
\pgftransformxshift{+\pgflsystemcurrentstep}%
\pgfpathlineto{\pgfpointorigin}}%
\def\pgflsystemmoveforward{%
\pgflsystemradonmizestep
\pgftransformxshift{+\pgflsystemcurrentstep}%
\pgfpathmoveto{\pgfpointorigin}}%
\def\pgflsystemranomizerightangle{%
\ifpgf@lsystem@randomize@angle%
\pgf@x=\pgflsystemrandomizeanglepercent pt\relax%
\divide\pgf@x by20\relax%
\pgfmathrand%
\pgf@x=\pgfmathresult\pgf@x%
\advance\pgf@x by\pgflsystemrightangle pt\relax%
\edef\pgflsystemcurrentrightangle{\pgfmath@tonumber{\pgf@x}}%
\else%
\let\pgflsystemcurrentrightangle=\pgflsystemrightangle%
\fi%
}%
\def\pgflsystemranomizeleftangle{%
\ifpgf@lsystem@randomize@angle%
\pgf@x=\pgflsystemrandomizeanglepercent pt\relax%
\divide\pgf@x by20\relax%
\pgfmathrand%
\pgf@x=\pgfmathresult\pgf@x%
\advance\pgf@x by\pgflsystemleftangle pt\relax%
\edef\pgflsystemcurrentleftangle{\pgfmath@tonumber{\pgf@x}}%
\else%
\let\pgflsystemcurrentleftangle=\pgflsystemleftangle%
\fi%
}%
\def\pgflsystemturnright{%
\pgflsystemranomizerightangle
\pgftransformrotate{-\pgflsystemcurrentrightangle}}%
\def\pgflsystemturnleft{%
\pgflsystemranomizeleftangle
\pgftransformrotate{\pgflsystemcurrentleftangle}}%
\def\pgflsystemsavestate{\begingroup}%
\def\pgflsystemrestorestate{\endgroup\pgfpathmoveto{\pgfpointorigin}}%