% 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}}%