3

In the following code the last line in the loop (at the pretty end of the code)) seams not to do what it is supposed to do: to assign \angB to \angA:

\begin{tikzpicture}[scale=1]

  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (p1);
   \path (o)+(90:1.2) coordinate (p2);
  \draw[dotted] (p2) -- (p1);
   \path (o)+(270:1) coordinate (q1);
   \path (o)+(30:1) coordinate (q2);
   \path (o)+(150:1) coordinate (q3);
  \draw[] (q1) -- (q2);
  \draw[] (q2) -- (q3);
  \draw[] (q3) -- (q1);
   \path (q1)+(90:0.8) coordinate (z);
  \draw[->] (z) arc (90:60:0.8);
  \path[above right] (z) node{$\theta$};
  \path[below] (q1) node{$\theta=30^\circ$};
  
  \begin{scope}[shift={(3,0)}]

  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (q1);

  \pgfmathtruncatemacro{\angA}{270}
  \pgfmathtruncatemacro{\t}{25}
  \foreach \n in {0,...,100}
  {
    \pgfmathtruncatemacro{\angB}{\angA+180-2*\t}
    \path (o)+({\angA}:1) coordinate (q1);
    \path (o)+({\angB}:1) coordinate (q2);
    \draw[] (q1) -- (q2);
    \pgfmathtruncatemacro{\angA}{\angB}
  } 

  \path[below] (q1) node{$\theta=\t^\circ$};

  \end{scope}

\end{tikzpicture}

Result: the picture on the right should have much more lines: enter image description here

EDIT Is there some sort of "step variable scope"? I noticed that q1 keeps its value although there are a lot of redefinitions of it in the loop.

2 Answers 2

3

The usual problem: \foreach performs each cycle in a group, so the setting of \angA is forgotten.

Make it global (be sure to use a command name that will not interfere with anything else).

\documentclass{article}
\usepackage{tikz}

\newcommand{\pgfmathtruncategmacro}[2]{%
  \pgfmathtruncatemacro\pgfmathresult{#2}%
  \global\let#1\pgfmathresult
}

\begin{document}

\begin{tikzpicture}[scale=1]

  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (p1);
   \path (o)+(90:1.2) coordinate (p2);
  \draw[dotted] (p2) -- (p1);
   \path (o)+(270:1) coordinate (q1);
   \path (o)+(30:1) coordinate (q2);
   \path (o)+(150:1) coordinate (q3);
  \draw[] (q1) -- (q2);
  \draw[] (q2) -- (q3);
  \draw[] (q3) -- (q1);
   \path (q1)+(90:0.8) coordinate (z);
  \draw[->] (z) arc (90:60:0.8);
  \path[above right] (z) node{$\theta$};
  \path[below] (q1) node{$\theta=30^\circ$};
  
  \begin{scope}[shift={(3,0)}]

  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (q1);

  \pgfmathtruncategmacro{\angA}{270}
  \pgfmathtruncatemacro{\t}{25}
  \foreach \n [remember=\n as \prevn (initially -1)] in {0,...,100}
  {
    \pgfmathtruncatemacro{\angB}{\angA+180-2*\t}
    \path (o)+({\angA}:1) coordinate (q\prevn);
    \path (o)+({\angB}:1) coordinate (q\n);
    \draw[] (q\prevn) -- (q\n);
    \pgfmathtruncategmacro{\angA}{\angB}
  } 

  \path[below] (q-1) node{$\theta=\t^\circ$};

  \end{scope}

\end{tikzpicture}

\end{document}

enter image description here

3

There is no need for global macros. pgffor has the remember key for that purpose.

\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}[scale=1]
 \begin{scope}[local bounding box=L]
  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (p1);
   \path (o)+(90:1.2) coordinate (p2);
  \draw[dotted] (p2) -- (p1);
   \path (o)+(270:1) coordinate (q1);
   \path (o)+(30:1) coordinate (q2);
   \path (o)+(150:1) coordinate (q3);
  \draw[] (q1) -- (q2);
  \draw[] (q2) -- (q3);
  \draw[] (q3) -- (q1);
   \path (q1)+(90:0.8) coordinate (z);
  \draw[->] (z) arc (90:60:0.8);
  \path[above right] (z) node{$\theta$};
  \path (L.south) node[below]{$\theta=30^\circ$};
 \end{scope} 
 % 
 \begin{scope}[shift={(3,0)},local bounding box=R]
  \coordinate (o) at (0,0);
  \draw[thick] (o) circle(1);
   \path (o)+(270:1) coordinate (q1);

  \pgfmathtruncatemacro{\angA}{270}
  \pgfmathtruncatemacro{\t}{25}
  \foreach \n [remember=\angA as \angA] in {0,...,100}
  {
    \pgfmathtruncatemacro{\angB}{\angA+180-2*\t}
    \path (o)+({\angA}:1) coordinate (q1);
    \path (o)+({\angB}:1) coordinate (q2);
    \draw (q1) -- (q2);
    \pgfmathtruncatemacro{\angA}{\angB}
  } 

  \path (R.south) node[below]{$\theta=\t^\circ$};
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

4
  • thank you Lazy squirrel. Now I understand how remember works. At the end I noticed that in this particular case one can avoid completely to remember some variable: one can compute both angles using n and (n+1). Dec 8, 2020 at 16:10
  • @PeptideChain Yes, sure. I just would like to recommend not to use global macros unless it is really unavoidable. Especially not macros with simple names like \angA. This really opens a can of worms (and frankly I am a bit shocked that this has been suggested). pgf has meanwhile ("protected") tools for that: \pgfutil@pushmacro and \pgfutil@popmacro. They are protected because they can still cause harm, but not as much harm as a gobal \angA.
    – user230294
    Dec 8, 2020 at 16:37
  • is it possible to define a "scope" arround my tikz picture? the one who programmed foreach has defined some sort of scope for the loop-step, or not? Dec 8, 2020 at 17:02
  • 1
    @PeptideChain Global is global, if that's what you mean. Apart from the remember key there is also the pgfplots variant \pgfplotsforeachungrouped, which avoids the problem, too. All I can say is that if you use these global macros, especially with such names, it is highly likely that at some point this will backfire. Says someone who has seen this happen, and then it is really no fun to find what the error is, especially if you work on a file with collaborators.
    – user230294
    Dec 8, 2020 at 17:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .