Tikzmath: use array
Accessing the array from inside \pgfmathsetmacro
, or \pgfmathparse
, seems to do what you want:
\documentclass{report}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\def\n{5}
\def\myarray{{42,1,0,1,1,0}}
\foreach \s in {1,...,\n}
{
\pgfmathsetmacro\ccolor{ifthenelse(\myarray[\s]==1, "green!30", "blue!30")}
\node[draw,circle,fill=\ccolor] at ({90+360/\n * (\s-1)}:2cm) {$\s$};
}
\end{tikzpicture}
\end{document}
Note that you don't need \usetikzlibrary{math}
.
The output is the same as in marmot's answer:
Inside \tikzmath
you cannot do assignments except of the allowed kind (that is, to local variables).
Here's a solution, with a reimplementation of arrays and a new keyword for \tikzmath
that allows executing code at the same level (not in a group). Beware of not doing assignments that change the \tikzmath
state; also no “tikzmath” is available inside it, so there must be an indirection as shown.
\documentclass{report}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{math}
% define a new keyword
\makeatletter
\def\tikz@math@process@keyword@assign{%
\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@assign}%
}
\def\tikz@math@process@keyword@@assign{%
\tikz@math@collected\tikz@math@parse
}
\makeatother
%% Let's reimplement TikZ arrays
\ExplSyntaxOn
\cs_new:Npn \shp #1 { \prop_show:c { l_tobias_array_#1_prop } }
\NewDocumentCommand{\definearray}{mO{}}
{% #1 = array name, #2 = items
\prop_clear_new:c { l_tobias_array_#1_prop }
\int_step_inline:nnnn { 0 } { 1 } { \clist_count:n { #2 } - 1 }
{
\prop_put:cnx { l_tobias_array_#1_prop } { ##1 } { \clist_item:nn { #2 } { ##1 + 1 } }
}
}
\NewDocumentCommand{\setarrayitem}{mmm}
{% #1 = array name, #2 = index, #3 = value
\prop_put:cff { l_tobias_array_#1_prop } { #2 } { #3 }
}
\NewExpandableDocumentCommand{\arrayitem}{mm}
{
\prop_item:cf { l_tobias_array_#1_prop } { #2 }
}
\cs_generate_variant:Nn \prop_put:Nnn { cff }
\cs_generate_variant:Nn \prop_item:Nn { cf }
\ExplSyntaxOff
\begin{document}
%%% FIRST METHOD
\begin{tikzpicture}
\definearray{myarray}
\tikzmath{
\n = 5;
% Works, but one problem: how to manually choose the values
% without using a loop?
int \i;
for \i in {1,...,\n}{
\tmp = mod(\i,2);
assign \setarrayitem{myarray}{\i}{\tmp};
};
% Display
for \i in {1,...,\n}{
if \arrayitem{myarray}{\i} == 1 then { \ccolor = "green!30";}
else { \ccolor = "blue!30"; };
{\node[draw,circle,fill=\ccolor] at ({90+360/\n * (\i-1)}:2cm) {$\i$};};
};
}
\end{tikzpicture}
%%% SECOND METHOD
\begin{tikzpicture}
\def\n{5}
\definearray{myarray}[42,1,0,1,1,0]
\foreach \s in {1,...,\n}
{
\tikzmath{ if \arrayitem{myarray}{\s} == 1 then { \ccolor = "green!30"; }
else { \ccolor = "blue!30";};
}
\node[draw,circle,fill=\ccolor] at ({90+360/\n * (\s-1)}:2cm) {$\s$};
}
\end{tikzpicture}
\end{document}
Now it's a bit more like an answer. I was using this answer. It is a bit odd that one needs to call \pgfmathparse
in an tikzmath environment.
\documentclass{report}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\def\myarray{{42,1,0,2,1,0}}
\begin{tikzpicture}
\tikzmath{
\n = 5;
% Works, but one problem: how to manually choose the values
% without using a loop?
int \i;
for \i in {1,...,\n}{{\pgfmathparse{\myarray[\i]}\xdef\mynum{\pgfmathresult}};
if \mynum == 1 then { \ccolor = "green!30";}
else { \ccolor = "blue!30"; };
{\node[draw,circle,fill=\ccolor] at ({90+360/\n * (\i-1)}:2cm) {$\i$};};
};
}
\end{tikzpicture}
\end{document}