# Drawing in Tikz with conditional options on floats

I am currently trying to create an image of randomly distributed points in a unit-square. I would like to draw these points in a given color if they are inside the inscribed circle, or in another, otherwise.

Here is what I have, without the condition set up.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}
\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle (1);
\draw[very thick] (0,0) -- (0,2) -- (2,2) -- (2,0) -- cycle;
\foreach \i in {1,...,50}{
\tikzmath{\xa=rand;}
\tikzmath{\ya=rand;}
\tikzmath{\eval=int(\xa^2+\ya^2 - 1.0);}
\fill[red!60!white](\xa+1, \ya+1) circle(1.5pt);
}
\end{tikzpicture}
\end{document}


I would like to have the fill/circle instruction have a color option that is dependent on the value of \eval, defined just above. For example: If \eval > 0 use [red!60!white], Otherwise, use [blue!60!white]

I tried using \ifthenelse, but am facing errors due (I think?) to the fact I am putting a condition on a float, and ifthenelse is limited to integers.

I also tried putting the fill/circle instruction inside a tikzmath environment, and having the condition set inside, but this did not work either, I believe because draw instructions cannot be called from inside that environment.

This would look like the following:

\foreach \i in {1,...,50}{
\tikzmath{\xa=rand;}
\tikzmath{\ya=rand;}
\tikzmath{\eval=int(\xa^2+\ya^2 - 1.0);}
\tikzmath{
if \eval < 0 then {
\fill[CERNblue!80!white](\xa+1, \ya+1) circle(1.5pt);
} else {
\fill[red!60!white](\xa+1, \ya+) circle(1.5pt);
}
}
}


Would anyone know how to go around these limitations?

• Your last code example would work if you put braces around the TikZ statements, e.g. {\fill … ;};. See the last example in the manual. Sep 16 at 12:07

The following code colors dots conditionally. Note that I had to brace \x and \y in (\x)^2+(\y)^2 because if they are negative (say, -0.5 and -0,5) then the initial expression expands into -0.5^2+-0.5^2 which is likely not what you expect. Also, the code uses let to assign strings to variable \c.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}
\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle (1);
\draw[very thick] (0,0) -- (0,2) -- (2,2) -- (2,0) -- cycle;
\foreach \i in {1,...,50}{
\tikzmath{
\xa = rand;
\ya = rand;
\eval = (\xa)^2+(\ya)^2 - 1.0;
if \eval<0 then {
let \c = blue!80!white;
} else {
let \c = red!60!white;
};
}
\fill[\c](\xa+1, \ya+1) circle(1.5pt);
}
\end{tikzpicture}
\end{document}


The result:

You were really close with your last code example, you just need to enclose the TikZ statements in another pair of {} and add another ;:

if \eval < 0 then {
} else {
{ \fill[red!60!white] (\xa+1, \ya+1) circle[radius=1.5pt]; };
};


You can just do math with text, say

\col = \eval ? "blue!60!white" : "red!60!white";
% or
\col = ifthenelse(\eval, "blue!60!white", "red!60!white")


Of course, you can also do this with if:

if \eval < 0 then {
\col = "blue!60!white";% or let \col = blue!60!white;
} else {
\col = "red!60!white"; % or let \col = red!60!white;
};


Assignments in the form of \<var> = <stuff> are evaluating <stuff> but you can also do let \<var> = <stuff> which does not evaluate <stuff>, that way you can drop the ".

Either way, now you can say

\fill[\col](\xa+1, \ya+1) circle[radius=1.5pt];


Since \eval is a simple integer number, you could have also used TeX primitives, say

\fill[\ifnum\eval<0 blue\else red\fi !60!white](\xa+1, \ya+1) circle[radius=1.5pt];


but that's not very nice.

Since you have only two outcomes depending on \eval you could define my fill 0/.style=red!60!white

and then use

\fill[blue!60!white, my fill \eval/.try](\xa+1, \ya+1) circle[radius=1.5pt];


where blue!60!white acts as a default and the /.try will only try my fill \eval and won't complain when the style is not defined.

I always like to have an if key available that evaluates a statement and applies different styles depending on the value. That way, you can even say

\fill[/utils/if={ int(\xa^2+\ya^2 - 1.0)<0 }% conditional
{ blue!60!white }           % if true
{ red!60!white  }           % if false


By the way, the \foreach macro allows to do math for every loop without the need for \tikzmath:

\foreach[
evaluate={
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
}] \i in {1,...,50}{


## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{math}

\makeatletter
\pgfkeys{% always useful
/utils/if/.code n args={3}{%
\pgfmathparse{#1}\ifdim\pgfmathresult pt=0pt\relax
\expandafter\pgfutil@firstoftwo
\else\expandafter\pgfutil@secondoftwo\fi
{\pgfkeysalso{#3}}{\pgfkeysalso{#2}}}}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
\col = \eval ? "blue!60!white" : "red!60!white";
}
}
\end{tikzpicture}

\begin{tikzpicture}
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
if \eval < 0 then {
\col = "blue!60!white";% or let \col = blue!60!white;
} else {
\col = "red!60!white"; % or let \col = red!60!white;
};
}
}
\end{tikzpicture}

\begin{tikzpicture}
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
if \eval < 0 then {
} else {
};
}
}
\end{tikzpicture}

\begin{tikzpicture}
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
}
\fill[\ifnum\eval<0 blue\else red\fi !60!white](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}[my fill 0/.style=red!60!white]
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
}
\fill[blue!60!white, my fill \eval/.try](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
\tikzmath{
\xa=rand;
\ya=rand;
\eval=int(\xa^2+\ya^2 - 1.0);
}
\fill[/utils/if={ int(\xa^2+\ya^2 - 1.0)<0 }% conditional
{ blue!60!white }           % if true
{ red!60!white  }           % if false