10

In my question The Spiral of Roots in TikZ, the answer by Mark Wibrow caught my attention but while trying to edit the code I found myself struggling with an ifelse statement. What I am trying to achieve is just to put a 1 instead of the square root of one in the base of the first right triangle. I tried saying

if \n = 1 then {1} else {$\sqrt{\n}$}

but it does not work. I don't clearly understand the math library (page 652 of the pgfmanual) and how it works. I am pretty sure that where I have the ifelse statement is wrong; probably more outside of the declaration. I even tried

\p = (\n == \N && \N > 1) ? "$\sqrt{\n}$" : "1";

but no good. Any insight as to how to achieve the desired result.

\newcommand\sqrtspiral[2][]{%
\tikz[line cap=round, x=2cm,y=2cm, line join=round,#1]{%
\tikzmath{%
  int \n;
  \b = 0; \d = 1; \N = #2;
  for \n in {1,...,\N}{
    \l = (\n == \N && \N > 1) ? "red" : "black";
    \e = (\n == 1) ? " -- cycle" : "";
    {
      \path [rotate=\b, draw=\l] (0,0) -- (\d,1) -- (\d,0)
        node [\l, midway, anchor=\b+180] {1}
        \e (\d/2, 0)  node [fill=white] {if \n = 1 then {1} else {$\sqrt{\n}$}}; % edit here
      \path [draw=\l, rotate=\b] (\d-.1,0) |- ++(.1,.1);
    };
    \d = sqrt(1+(\d)^2); \b = \b + asin(1/\d);
  };
  {
    \path [rotate=\b, \l] (\d/2, 0) node [fill=white] {$\sqrt x$};
  };
}}}

Here is the link to the answer: link

A MWE follows (of course merely one):

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{math}
\begin{document}

\newcommand\sqrtspiral[2][]{%
\tikz[line cap=round, x=2cm,y=2cm, line join=round,#1]{%
\tikzmath{%
  int \n;
  \b = 0; \d = 1; \N = #2;
  for \n in {1,...,\N}{
    \l = (\n == \N && \N > 1) ? "red" : "black";
    \e = (\n == 1) ? " -- cycle" : "";
    {
      \path [rotate=\b, draw=\l] (0,0) -- (\d,1) -- (\d,0)
        node [\l, midway, anchor=\b+180] {1}
        \e (\d/2, 0)  node [fill=white] {%
            if \n = 1  then {1} else {$\sqrt{\n}$} %edit here
        };
      \path [draw=\l, rotate=\b] (\d-.1,0) |- ++(.1,.1);
    };
    \d = sqrt(1+(\d)^2); \b = \b + asin(1/\d);
  };
  {
    \path [rotate=\b, \l] (\d/2, 0) node [fill=white] {$\sqrt x$};
  };
}}}

\sqrtspiral{10}

\end{document}
  • I'm baffled as well. I can get it to work when choosing between 1 and 2 or even 1 and \n but it doesn't work when \sqrt is used. – Paul Gessler Jan 11 '15 at 23:49
  • Its new to me so I cant say much @PaulGessler but probably they way its written it only accepts letters and numbers but not stuff in math mode. I think. – azetina Jan 12 '15 at 0:12
13

First thing to know : everything inside { }; (with semicolon) is treated outside tikzmath. So you can't put if logic inside { }; (56.7 Executing Code Outside the Parser of the TikZ 3.0.0 manual, p.634).

Second thing to know : if \n = 1 then {1} else {2} has no print command, and the statements 1 and 2 are not valid evaluations in tikzmath, and we compare with ==.
So to correct this you have to do if \n == 1 then {print{1};} else {print{2};};.
And here print is optional if you use math mode $ $, but is mandatory if you want something like print{1}; or print{Some text here};(check this Mark Wibrow's answer).

So in your case the correct code to put in the node is :

\tikzmath{ 
  if \n == 1 then {
    {$1$};
  } else {
    {$\sqrt{\n}$};
  };
}

Here is the result:

enter image description here

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{math}

\newcommand\sqrtspiral[2][]{%
\tikz[line cap=round, x=2cm,y=2cm, line join=round,#1]{%
\tikzmath{%
  int \n;
  \b = 0; \d = 1; \N = #2;
  for \n in {1,...,\N}{
    \l = (\n == \N && \N > 1) ? "red" : "black";
    \e = (\n == 1) ? " -- cycle" : "";
    { % --------------------------------------------------- outside math library
      \path [rotate=\b, draw=\l] (0,0) -- (\d,1) -- (\d,0)
        node [\l, midway, anchor=\b+180] {1}
        \e (\d/2, 0)  node [fill=white] { \tikzmath{ % -- back in math library
            if \n == 1 then {
              {$1$}; % ------------------------- $1$ is outside math library
            } else {
              {$\sqrt{\n}$}; % --------- $\sqrt{\n}$ is outside math library
            };
          }% -------------------------------------------- outside math library
        };
      \path [draw=\l, rotate=\b] (\d-.1,0) |- ++(.1,.1);
    }; % -------------------------------------------------- back in math library
    \d = sqrt(1+(\d)^2); \b = \b + asin(1/\d);
  };
  { % ----------------------------------------------------- outside math library
    \path [rotate=\b, \l] (\d/2, 0) node [fill=white] {$\sqrt x$};
  }; % ---------------------------------------------------- back in math library
}}}

\begin{document}

\sqrtspiral{10}

\end{document}
| improve this answer | |
  • 1
    It seems that you know a lot about tikzmath. I also noticed it with your Cayley graph posting, and with your print question. Would you like to write an article on LaTeX-Community.org on explaining tikzmath with such nice images? I gladly return the favor with a 500 bounty, but more important is that readers there will like it for sure. You could contact me via stefan@texblog.net if you like. – Stefan Kottwitz Jan 28 '15 at 15:06
9

Since it's just typesetting the node contents not using it for computation you can use a normal tex if:

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{math}
\begin{document}

\newcommand\sqrtspiral[2][]{%
\tikz[line cap=round, x=2cm,y=2cm, line join=round,#1]{%
\tikzmath{%
  int \n;
  \b = 0; \d = 1; \N = #2;
  for \n in {1,...,\N}{
    \l = (\n == \N && \N > 1) ? "red" : "black";
    \e = (\n == 1) ? " -- cycle" : "";
    {
      \path [rotate=\b, draw=\l] (0,0) -- (\d,1) -- (\d,0)
        node [\l, midway, anchor=\b+180] {1}
        \e (\d/2, 0)  node [fill=white] {$\ifnum\n=1 1\else\sqrt{\n}\fi $};
      \path [draw=\l, rotate=\b] (\d-.1,0) |- ++(.1,.1);
    };
    \d = sqrt(1+(\d)^2); \b = \b + asin(1/\d);
  };
  {
    \path [rotate=\b, \l] (\d/2, 0) node [fill=white] {$\sqrt x$};
  };
}}}

\sqrtspiral{10}

\end{document}
| improve this answer | |
9

Description of "x" in the pgfmanual page 935:

These operators are used to quote x. However, as every expression is expanded with \edef before it is parsed, macros (e.g., font commands like \tt or \Huge) may need to be “protected” from this expansion (e.g., \noexpand\Huge).

You can define a new macro

\newcommand\mysqrt{$\sqrt{\n}$}

and then use

\p = (\n == 1) ? 1 : "\noexpand\mysqrt";

Code:

\documentclass[tikz,border=0.125cm]{standalone}
\usetikzlibrary{math}
\newcommand\mysqrt{$\sqrt{\n}$}

\begin{document}

\newcommand\sqrtspiral[2][]{%
\tikz[line cap=round, x=2cm,y=2cm, line join=round,#1]{%
\tikzmath{%
  int \n;
  \b = 0; \d = 1; \N = #2;
  for \n in {1,...,\N}{
    \l = (\n == \N && \N > 1) ? "red" : "black";
    \e = (\n == 1) ? " -- cycle" : "";
    \p = (\n == 1) ? 1 : "\noexpand\mysqrt";
    {
      \path [rotate=\b, draw=\l] (0,0) -- (\d,1) -- (\d,0)
        node [\l, midway, anchor=\b+180] {1}
        \e (\d/2, 0)  node [fill=white] {\p};
      \path [draw=\l, rotate=\b] (\d-.1,0) |- ++(.1,.1);
    };
    \d = sqrt(1+(\d)^2); \b = \b + asin(1/\d);
  };
  {
    \path [rotate=\b, \l] (\d/2, 0) node [fill=white] {$\sqrt x$};
  };
}}}

\sqrtspiral{10}

\end{document}
| improve this answer | |

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.