4

Sorry to ask an extremely "entry-level" question, but after googling to get a description of how to do conditional logic in TikZ, I don't see a straight and simple answer. I see a bunch of very complicated examples where the point is not to explain the use of conditional logic, but to accomplish some specific task, and I can't quite sort through what is strictly necessary to get a basic if-then-else.

I am trying to do a double-loop over some floats, and want to skip the particular case where both \i and \j are zero. Here is a very pared down example:

\foreach \i in {-3,...,3} {
  \foreach \j in {-3,...,3} {
    \node at (\i,\j) {\i+\j};
  }
}

I have seen examples of using \ifnum but none of them involve performing a boolean computation. Here I need something like

\foreach \i in {-3,...,3} {
  \foreach \j in {-3,...,3} {
    \ifnum {\i!=0 \AND \j!=0} {\node at (\i,\j) {\i+\j};};
  }
}

But I can't find documentation on the correct way to write negations, conjunctions, and so on. More generally, if anyone knows a reference for this sort of intro-level documentation for programming in TikZ, I'd appreciate it!


If it's valuable, here is a more complete example of what I'm trying to do. The following code throws an error, presumably because of the case when \i and \j are both zero.

\begin{tikzpicture}
        \foreach \i in {-3,-2.5,...,3} {
          \foreach \j in {-3,-2.5,...,3} {
            \pgfmathsetmacro \d {2*sqrt((\i)^2+(\j)^2)};
            \draw[->] ({\i},{\j}) -- ({\i - \i/\d}, {\j-\j/\d});
          };
        };
    \end{tikzpicture}
Addem
  • 867
  • Can we see the full picture? It looks like you're already on a path (node and not \node). With lowlevel \ifnum a logical AND isn't trivial. But there are other ways. – Qrrbrbirlbel Jun 27 '23 at 16:47
  • @Qrrbrbirlbel I added a fuller example of what I'm actually doing -- thanks! – Addem Jun 27 '23 at 16:52
  • I see, that's a very different problem than the original. Since \d is now a floating point number, the low-level solution would be to \unless\ifdim\d pt=0pt \draw … ; \fi. (No ; after the body of a loop, by the way.) – Qrrbrbirlbel Jun 27 '23 at 16:53
  • @Qrrbrbirlbel True -- I was trying to keep the "toy" example very simple. I mostly just wanted to ask "how do you do conditional logic and basic programming in TikZ" and only included a specific example because people usually want one. :) – Addem Jun 27 '23 at 16:58
  • @Qrrbrbirlbel By the way your \unless ... code worked, so if you make that the answer, I can accept it! – Addem Jun 27 '23 at 17:00

2 Answers2

8

The first diagram uses low-level \ifdim which does not evaluate \d further (in this case no problem because it already contains just a value).

Without using other packages or LaTeX3 tools that support conditionals you could use the math library which is shown in the second diagram. (The \d doesn't need to evaluated inside \tikzmath.)

But then you could do everything in math actually (3rd diagram).

All these approaches only support numbers in the range of 16 thousand (and since you use \d inside of the path you'd run into trouble there anyway) since it uses PGFMath but for “real” floating point math you will need to check out other solutions like the one posted by Ulrike Fischer.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
\foreach \i in {-3,-2.5,...,3} {
  \foreach \j in {-3,-2.5,...,3} {
    \pgfmathsetmacro \d {2*sqrt((\i)^2+(\j)^2)};
    \unless\ifdim\d pt=0pt
      \draw[->] ({\i},{\j}) -- ({\i - \i/\d}, {\j-\j/\d});
    \fi
  }
}
\end{tikzpicture}
\begin{tikzpicture}
\foreach \i in {-3,-2.5,...,3} {
  \foreach \j in {-3,-2.5,...,3} {
    \tikzmath{
      \d = 2*sqrt((\i)^2+(\j)^2);
      if \d != 0 then {
        { \draw[->] ({\i},{\j}) -- ({\i - \i/\d}, {\j-\j/\d}); };
      };
    }
  }
}
\end{tikzpicture}
\begin{tikzpicture}
\tikzmath{
  for \i in {-3,-2.5,...,3} {
    for \j in {-3,-2.5,...,3} {
      \d = 2*sqrt((\i)^2+(\j)^2);
      if \d != 0 then {
        { \draw[->] ({\i},{\j}) -- ({\i - \i/\d}, {\j-\j/\d}); };
      };
    };
  };
}
\end{tikzpicture}
\end{document}
Qrrbrbirlbel
  • 119,821
  • Interesting -- I had never heard of LaTeX3. Will look into it -- and thanks for the solution! – Addem Jun 27 '23 at 17:08
  • @Addem Ulrike's answer uses it. It has its advantages but as long as it is not easily available on the top level (at least with a package) I usually don't bother with it unless I really need it. – Qrrbrbirlbel Jun 27 '23 at 17:11
6
\documentclass[tikz]{standalone}
\ExplSyntaxOn
\cs_set_eq:NN\fpcompareTF\fp_compare:nNnTF
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
        \foreach \i in {-3,-2.5,...,3} {
          \foreach \j in {-3,-2.5,...,3} {
            \pgfmathsetmacro \d {2*sqrt((\i)^2+(\j)^2)}
            \fpcompareTF{\d}={0}{}
            {
              \draw[->] ({\i},{\j}) -- ({\i - \i/\d}, {\j-\j/\d});
            }
          }
        }
    \end{tikzpicture}
\end{document}

enter image description here

Ulrike Fischer
  • 327,261