4

Essentially what I am trying to achieve is a grid of 12 circles with three rows and four columns. All I would like is for the two middle columns to be red while the other two columns are black. Here is my current attempt, which gives me all red circles no matter what I do.

\begin{tikzpicture}

\foreach \x in {0,...,3}{
    \foreach \y in {0,...,2}{
        \ifthenelse{\x in {1,2}}{
            \draw[red,fill=red] (\x,\y) circle (0.4);
        }{
            \draw (\x,\y) circle (0.4);
        }
    }
}

\end{tikzpicture}

Current Result with Above TikZ Code:

enter image description here

  • 2
    Welcome to TeX.SX! There's no “in” test for \ifthenelse. – egreg Nov 13 at 15:34
  • Code has been edited, now I am attempting only the second columng or x=1, still getting the same result ``` \begin{tikzpicture} \foreach \x in {0,...,3}{ \foreach \y in {0,...,2}{ \ifthenelse{\x = 1}{ \draw[red,fill=red] (\x,\y) circle (0.4); }{ \draw (\x,\y) circle (0.4); } } } \end{tikzpicture} ``` – user201313 Nov 13 at 15:41
  • ...as @egreg said, there is no in test for ifthenelse. Try \ifthenelse{\x < 3} or similar. – Rmano Nov 13 at 15:44
  • 1
    Welcome to TeX.SX! Please make your code compilable (if possible), or at least complete it with \documentclass{...}, the required \usepackage's, \begin{document}, and \end{document}. That may seem tedious to you, but think of the extra work it represents for TeX.SX users willing to give you a hand. Help them help you: remove that one hurdle between you and a solution to your problem. – Rmano Nov 13 at 15:46
5

You already know matrix dimensions, only twelve nodes. They are easy to manage. Then you can use a matrix and forget foreach and ifthenelse problems ;-)

\documentclass[border=1mm, tikz]{standalone}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes, nodes in empty cells, 
    row sep=2mm, column sep=2mm,
    nodes={circle, draw, minimum width=8mm},
    column 2/.style={nodes={red, fill=red}},
    column 3/.style={nodes={red, fill=red}},
    ]
    { &&&\\&&&\\&&&\\};
\end{tikzpicture}
\end{document}

enter image description here

4

As said by @greg in the comment, there is no such a thing as a \x in {1,2} test for ifthenelse.

After reading the documentation for the package xifthen, you can:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usepackage{xifthen}
\begin{document}
\begin{tikzpicture}
\foreach \x in {0,...,3}{
    \foreach \y in {0,...,2}{
        \ifthenelse{\x > 0 \AND \x < 3}{
            \draw[red,fill=red] (\x,\y) circle (0.4);
        }{
            \draw (\x,\y) circle (0.4);
        }
    }
}
\end{tikzpicture}
\end{document}

which results in: white and red discs

2

Just for the pleasure of using the modulo function.

screenshot

\documentclass[tikz,border=5mm]{standalone}
\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}

\foreach \x in {0,...,3}{
    \foreach \y [evaluate =\x as \coloring using {int(Mod(\x,3))}]in {0,...,2}{
     \ifthenelse{\coloring = 0}{
            \draw (\x,\y) circle (0.4);
        }{
            \draw[red,fill=red] (\x,\y) circle (0.4);
        }
    }
}

\end{tikzpicture}
\end{document}
2

I wouldn't use ifthen. A pgf membership test can be used to implement your condition \x in {1,2},

\documentclass[tikz,border=3mm]{standalone}
\makeatletter
\pgfmathdeclarefunction{memberQ}{2}{%
  \begingroup%
    \edef\pgfutil@tmpb{0}%
    \edef\pgfutil@tmpa{#2}%
    \expandafter\pgfmath@member@i\pgfutil@firstofone#1\pgfmath@token@stop
    \edef\pgfmathresult{\pgfutil@tmpb}%
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup}
\def\pgfmath@member@i#1{%
    \ifx\pgfmath@token@stop#1%
    \else
      \ifnum#1=\pgfutil@tmpa\relax%
      \gdef\pgfutil@tmpb{1}%
      %\typeout{#1=\pgfutil@tmpa}
      \fi%
      \expandafter\pgfmath@member@i
    \fi}
\makeatother
\begin{document}
\begin{tikzpicture}

\foreach \x [evaluate=\x as \isMember using {int(memberQ({1,2},\x))}] in {0,...,3}{
    \foreach \y in {0,...,2}{
        \draw \ifnum\isMember=1
        [red,fill=red]
        \fi (\x,\y) circle[radius=0.4cm];
    }
}
\end{tikzpicture}
\end{document}

This membership test works unless the last entry of the list has a substructure. Similar limitations apply to the dim function, which is built in pgf, but not mentioned in the manual, presumably for that reason. However, as long as you have ordinary lists, both memberQ and dim do work properly. (Proposed alternatives with a much more extensive codes also have drawbacks, sometimes even more severe, and I wish that those who propose them would mention them, too.)

As you can see, an ordinary \ifnum can be built into the path.

\draw \ifnum\itest=1
    [red,fill=red]
    \fi (\x,\y) circle[radius=0.4cm];

You then only have to draw one path. You can also use the conventional ifthenelse instead of the memberQ function.

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

\begin{document}
\begin{tikzpicture}

\foreach \x [evaluate=\x as \itest using {int(ifthenelse(\x>0 && \x <3,1,0))}] in {0,...,3}{
    \foreach \y in {0,...,2}{
        \draw \ifnum\itest=1
        [red,fill=red]
        \fi (\x,\y) circle[radius=0.4cm];
    }
}
\end{tikzpicture}
\end{document}

In this case you do not even have to use evaluate, you can simply use the fact that \numexpr truncates the result,

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

\begin{document}
\begin{tikzpicture}

\foreach \x  in {0,...,3}{
    \foreach \y in {0,...,2}{
        \draw \ifnum\the\numexpr\x/2\relax=1
        [red,fill=red]
        \fi (\x,\y) circle[radius=0.4cm];
    }
}
\end{tikzpicture}
\end{document}

enter image description here

1

There is no such test for \ifthenelse. However, you can use a different implementation, see https://tex.stackexchange.com/a/467527/4427

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz} % for the application

\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifthenelse}{mmm}
 {
  \bool_if:nTF { #1 } { #2 } { #3 }
 }

\cs_new_eq:NN \numtest     \int_compare_p:n
\cs_new_eq:NN \oddtest     \int_if_odd_p:n
\cs_new_eq:NN \fptest      \fp_compare_p:n
\cs_new_eq:NN \dimtest     \dim_compare_p:n
\cs_new_eq:NN \deftest     \cs_if_exist_p:N
\cs_new_eq:NN \namedeftest \cs_if_exist_p:c
\cs_new_eq:NN \eqdeftest   \token_if_eq_meaning_p:NN
\cs_new_eq:NN \streqtest   \str_if_eq_p:ee
\cs_new_eq:NN \emptytest   \tl_if_blank_p:n
\prg_new_conditional:Nnn \xxifthen_legacy_conditional:n { p,T,F,TF }
 {
  \use:c { if#1 } \prg_return_true: \else: \prg_return_false: \fi:
 }
\cs_new_eq:NN \boolean \xxifthen_legacy_conditional_p:n
\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}

\foreach \x in {0,...,3}{
    \foreach \y in {0,...,2}{
        \xifthenelse{\numtest{1 <= \x <= 2}}{
            \draw[red,fill=red] (\x,\y) circle (0.4);
        }{
            \draw (\x,\y) circle (0.4);
        }
    }
}

\end{tikzpicture}

\end{document}

enter image description here

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.