5

Good evening,

I am trying to understand how the TikZ library lindenmayersystems works, more precisely I have some problems with the following code, that I tried to make as clear as possible :

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{lindenmayersystems}

\begin{document}

\begin{tikzpicture}
  % I just store the initial length
  \newlength\initialstep
  \setlength\initialstep\pgflsystemstep

  % Computation of an angle
  \pgfmathparse{180-180/5} % will be less trivial at the end
  \pgfmathsetmacro\angle\pgfmathresult

  % Computation of a ratio
  \pgfmathparse{2*0.5/(1-0.5)} % this seems trivial but this is just a particular case
  \pgfmathsetmacro\scaling\pgfmathresult

  \pgfdeclarelindenmayersystem{KochC}{
    % d does a turn around
    \symbol{d}{
    \pgflsystemleftangle=180
    \pgflsystemturnleft
    \pgflsystemleftangle=\angle
    }

    % move on a certain portion
    \symbol{c}{
    \pgflsystemstep=\scaling*\initialstep
    \pgflsystemdrawforward
    \pgflsystemstep=\initialstep
    }

    % new measures
    \symbol{n}{
    \pgflsystemstep=\scaling*\initialstep
    }

    \rule{A->A[cA]nd-A-A-A-A}
  }
  \draw[blue,line cap=round] [lindenmayer system={KochC,axiom=A,order=1}] lindenmayer system;
\end{tikzpicture}

\end{document}

The error I have is ! Illegal unit of measure (pt inserted)., which does not seem very relevant, unless I am completely mistaken.

The purpose of this code is to draw a line segment, with some centered portion of it replaced by a n-gone, here n is 5. Another problem I have is to make this n be any natural number, and can't seem to find a way but this is another question.

I would really appreciate any help.

Thank you,

Pierre

PS: the reason why I store pgflsystemstep at the beggining is because this code will actully be used in some context where it makes sense. I kept this line, if maybe there is a problem with it.

4

Welcome to TeX-SE! The errors come from the stars you have before \initialstep. You define \initalstep as length by saying \newlength\initialstep, so you do not want to use *s. The following, where I shortened the \pgmathsetmacro stuff a bit, works. I am using your code from the comment below (with minor modifications) because the result looks great.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{lindenmayersystems}

\begin{document}

%\newcommand{kochC}[1]
%{

  \begin{tikzpicture}
    % je stocke pfgsystemstep dans une nouvelle variable initialstep : c'est la longueur du premier segment
    \newlength\initialstep

    % je calcule l'angle dont il faut tourner pour faire un polygône réglier à n côtés
    \pgfmathsetmacro\angle{360/5} % changer 5 en le nombre de côtés qu'on veut

    % je calcule le facteur de scaling
    \pgfmathsetmacro\scaling{2*0.33/(1-0.33)} %\pgfmathparse{2*#1/(1-#1)}

    \pgfdeclarelindenmayersystem{KochC}{
      % s initialise les données
      \symbol{s}{
       \def\pgflsystemleftangle{-\angle}
       \def\pgflsystemrightangle{180-\angle}
       \setlength\initialstep\pgflsystemstep
     }

      % avancer sur une portion de longueur c sans tracer
      \symbol{c}{
       \pgflsystemstep=\scaling\initialstep
       \pgflsystemmoveforward
       \pgflsystemstep=\initialstep
     }

      % nouvelles mesures
      \symbol{n}{
       \pgflsystemstep=\scaling\pgflsystemstep
     }

     \rule{F->sF[cF]n-F+F+F+F}
   }
   \draw[blue,line cap=round] [lindenmayer system={KochC,axiom=F,order=1}] lindenmayer system;
 \end{tikzpicture}
%}

%\kochC[0.5]

\end{document}

enter image description here

Note:

  • If you deal with lengths, you cannot use * (unless you use something like \pgfmathsetlengthmacro but this is not necessary here) and you cannot set lengths with \def but with \setlength or just <new length>=<factor><other length>, where <factor> is a number. (Notice that = is sometimes safer because I believe to remember that some package redefines \setlength but this is not important here.)
  • If you redefine macros, you could use \renewcommand or here \pgfmathsetmacro or \def. However, the latter two do not warn you if the macro didn't exist beforehand.
| improve this answer | |
  • Thank you very much ! It would be so nice if you could also give me a clue on why the result is a simple line segment instead of what I am expecting, i.e. a line segment with a pentagone around its center. Thanks again – elidiot Jun 3 '19 at 23:56
  • 1
    I don't have enough reputation to start a chat so : here pastebin.com/5QAvjM3c is my current code. I figured out that several things were incorrect : I was redefining variables with "=" instead of \def for example. The current code doesn't compile but I feel like we're almost there – elidiot Jun 4 '19 at 0:42
  • 1
    @elidiot Indeed. All you need to do is to replace \def\pgflsystemstep{\scaling\initialstep} by \setlength\pgflsystemstep{\scaling\initialstep} or \pgflsystemstep=\scaling\pgflsystemstep (twice) and your code works. (I should have caught the = but I thought they were counters... ). So the upshot is that you can redefine lengths with either = or \setlength and macros with \def (sometimes dangerous), \renewcommand or in this context with \pgfmathsetmacro. – user121799 Jun 4 '19 at 0:48
  • 1
    Great, thank you so much for everything. Here is the final example pastebin.com/nxg7wcu7 which gives exactly what I wanted. – elidiot Jun 4 '19 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.