2

I would like to draw some circles and some squares and I would like to put in into a loop. But that does not seem to work. Any help would be great.

\documentclass[tikz]{standalone}

\usepackage{xfp} % floating point unit f\"ur fpeval

\usepackage{tikz}
\usetikzlibrary{quotes}

\begin{document}
   \begin{tikzpicture}
      \edef\r{1.0}

         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};

         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};

         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};

         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};

         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};

      \foreach \I in {1, ..., 5}{
         \draw circle (\r);
         \draw (-1.0*\r,\r) to (\r,\r); % oben
         \draw (-1.0*\r,-1.0*\r) to (1.0*\r,-1.0*\r); % unten
         \draw (-1.0*\r,0) to ["\fpeval{\r}"] (-1.0*\r,1.0*\r); % Mitte
         \draw (-1.0*\r,-1.0*\r) to (-1.0*\r,1.0*\r); % links
         \draw (1.0*\r,-1.0*\r) to (1.0*\r,1.0*\r); % rechts
         \pgfmathparse{sqrt(\r^2 + \r^2)}\edef\r{\pgfmathresult};
      }
   \end{tikzpicture}
\end{document}
3
  • Assignments in the body of the \foreach loop are local. You'll need \xdef (which is \global\edef) or use the evaluate and the remember option of \foreach. Commented Aug 29, 2022 at 9:04
  • That sounds good. But to be honest, this is my first try with tikz. What do I have to do with evaluate and remember?
    – Andreas
    Commented Aug 29, 2022 at 9:09
  • I just changed from edef to xdef. That seems to work. (Great) But does it also work with more similar figures?
    – Andreas
    Commented Aug 29, 2022 at 9:12

2 Answers 2

4

With use of the \pgfmathsetmacro, nodes and labels above nodes (concept is quite similar to nice @Qrrbrbirlbel answer: +1):

\documentclass[margin=3mm, tikz]{standalone}

\usepackage{xfp} % floating point unit f\"ur fpeval

\usepackage{tikz}
\usetikzlibrary{quotes}
\usepackage{pgfmath}

\begin{document}
   \begin{tikzpicture}[
every label/.style = {font=\footnotesize}
                        ]
      \edef\r{1.0}
\foreach \i in {0,1,...,4}
{
   \pgfmathsetmacro{\R}{+sqrt(2)^\i*\r} %
\node[draw, minimum size=2*\R cm, label=\R] {};
\node[circle, draw, minimum size=2*\R cm] {};
}
   \end{tikzpicture}
\end{document}

enter image description here

1
  • Thanks al lot for your helpful hints.
    – Andreas
    Commented Aug 30, 2022 at 16:12
8

Assignments in the body of a \foreach loop are local. You can use make them global by using \global\edef/\xdef

\pgfmathparse{sqrt(\r^2 + \r^2)}\xdef\r{\pgfmathresult}

however this will destroy the original definition of \r (putting a diacritic ring on a letter). Even if you don't need that, I'd advise against it.

The \foreach macro offers much better options:

In your case, you'll want something like this:

\foreach \I[
  evaluate={\nextR = \r * sqrt 2;},
  remember=\nextR as \r (initially 1)
] in {1, ..., 5}{

For every instance \foreach will evaluate \r * sqrt 2 (equivalnt to your original sqrt(\r^2+\r^2)) and store it in \nextR, as if you've done

\pgfmathsetmacro\nextR{\r * sqrt 2}

and this evaluated \nextR will be the \r of the next loop, except for the first time where \r will be 1 (declared by using (initially 1)).

I've taken the liberty to draw the square using the rectangle path operation (alternative link) and using the modern syntax for specifying the radius of a circle (radius=… instead of (…)).

Code

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \i[
  evaluate={\nextR = \r * sqrt 2;},
  remember=\nextR as \r (initially 1)
] in {1,...,10} {
\draw circle[radius=\r]
  (-\r, -\r) rectangle (\r,\r)
  node[left] at (-\r,.5*\r) {\pgfmathprintnumber{\r}}
  ;
}
\end{tikzpicture}
\end{document}

Output

enter image description here

2
  • Off-topic: With the through and the fit library we can do \node[draw,circle through=(0:1)](c){};\node[draw,fit=(c),inner sep=0pt](r){};\foreach\i in{1,...,10}{\node[draw,circle through=(r.north east)](c){};\node[draw,fit=(c),inner sep=0pt](r){};} Commented Aug 29, 2022 at 9:40
  • Thanks al lot for your helpful hints.
    – Andreas
    Commented Aug 30, 2022 at 16:12

You must log in to answer this question.

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