8

I have an indexed variable and I do not know how to conduct simple math operations on the index such as x{\a-1}.

I am using \tikzmath alot; therefore, my MWE includes it:

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

\begin{document}

\begin{tikzpicture}
\tikzmath{
\x1 = 1;
\x2 = 3;
\x3 = 5;
\x4 = 7;
%Since units are not given in \tikzmat, they will be evaluated as cm in tikz enviroment below.
}

\draw (\x{1},0) -- (10cm,10cm) node[at start, below]{\x{1}}; %This works

%\draw (\x{2-1},0) -- (10cm,10cm) node[at start, below]{\x{2-1}}; %This does not work

%\foreach \ind in {2,...,4}
%\draw (\x{\ind},0) -- (10cm,10cm) node[at start, below]{\x{\ind}}; %This works

%\foreach \ind in {2,...,4}
%\draw (\x{\ind-1},0) -- (10cm,10cm) node[at start, below]{\x{\ind-1}}; %This does not work

\end{tikzpicture}
\end{document}
egreg
  • 1,121,712
berkus
  • 1,168

2 Answers2

8

The \x macro doesn't perform arithmetic on its argument, but you can make it do it.

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

\newcommand{\usevar}[2]{%
  \expandafter#1\expandafter{\the\numexpr#2\relax}%
}

\begin{document}

\begin{tikzpicture}
\tikzmath{
\x1 = 1;
\x2 = 3;
\x3 = 5;
\x4 = 7;
%Since units are not given in \tikzmat, they will be evaluated as cm in tikz enviroment below.
}

\draw (\x{1},0) -- (10,5) node[at start, below]{\x{1}};

\draw[red] (\usevar\x{2-1},0) -- (4,5) node[at start, below]{\usevar\x{2-1}};

\foreach \ind in {2,...,4}
\draw (\x{\ind},0) -- (10,10) node[at start, below]{\x{\ind}};

\foreach \ind in {2,...,4}
\draw[red] (\usevar\x{\ind-1},0) -- (5,5) node[at start, below]{\usevar\x{\ind-1}};

\end{tikzpicture}
\end{document}

enter image description here

Explanation

When you do \tikzmath{\x<argument>=<expression>}, TikZ defines the macro \x and also an internal macro

\tikz@math@var@indexed@x@<argument>

that in turn expands to the (computed) expression. The macro \x is essentially defined to look at its argument and to compose the internal macro name from it. The <argument> needn't be a math expression and therefore no attempt at evaluating it is done.

Thus you need to perform the evaluation (assuming only integers are involved in the “subscript”) before \x is expanded. This is the task performed by \usevar, which sets \x aside, expands \the\numexpr#2\relax, that returns an integer, and then goes back to \x (its first argument, in general) which now “sees” the computed argument.

egreg
  • 1,121,712
  • Wow! Thanks @egreg! Any other possible solutions? Is this more of a \TeX question than a Tikz question? Any resource you can suggest for reading, as I am new to both. – berkus Jul 01 '17 at 13:39
  • 1
    @BarisErkus Well, \expandafter is quite an esoteric topic. – egreg Jul 01 '17 at 13:55
  • Thanks @egreg. I am exploring the realms of \TeX nowadays. This is really helpful. I have been seeing these expressions in the other posts a lot but had difficulty to understand the process. I will read and research these now. – berkus Jul 01 '17 at 15:11
  • quick question: Expressions with @: What are these called? How should I search them in Google to learn more about them. – berkus Jul 01 '17 at 15:13
  • 1
    @BarisErkus They're commonly known as “internal macros”. – egreg Jul 01 '17 at 15:16
  • 1
    @BarisErkus For the LaTeX programming convention that macros containing @ are to be understood as internal, also see What do \makeatletter and \makeatother do? – marsupilam Jul 01 '17 at 15:39
  • @mars I have been encountring \makeatletter and \makeatother and catcodes, and related stuff lately alot. However, it is just very difficult to bring the pieces together and understand how, where and if we need to use them for the tasks we are intended to do. Anyhow, I think this is the point where I need the crack the code to move forward. – berkus Jul 01 '17 at 15:51
1

Minor addition to @egreg's fix:

If we would like to evaluate only the expressions similar to {2*\ind+5} @egreg's solution becomes:

\newcommand{\useevalof}[1]{%
  \the\numexpr#1\relax%
}

Example: Consider $A_{\ind-4}$. If \ind has a value of 6, $A_{\useevalof{\ind-4}}$ will give $A_2$

This is really useful for me. I am developing a Tikz library for structural mechanics for civil engineers. Look at the pictures below. Levels are fully automated.

Noted: removed \expandafter after @egreg note.

enter image description here

berkus
  • 1,168