
У меня есть индексированная переменная, и я не знаю, как выполнять простые математические операции с индексом, например x{\a-1}
.
Я использую \tikzmath
много, поэтому мой MWE включает это:
\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}
решение1
Макрос \x
не выполняет арифметические действия над своим аргументом, но вы можете заставить его это сделать.
\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}
Объяснение
Когда вы это сделаете \tikzmath{\x<argument>=<expression>}
, TikZ определит макрос \x
, а также внутренний макрос.
\tikz@math@var@indexed@x@<argument>
что в свою очередь расширяется до (вычисляемого) выражения. Макрос \x
по сути определен для просмотра своего аргумента и составления из него внутреннего имени макроса. <argument>
Не обязательно должно быть математическим выражением, и поэтому не делается никаких попыток его оценки.
Таким образом, вам нужно выполнить оценку (предполагая, что в «индексе» участвуют только целые числа) до того, как \x
будет развернуто. Это задача, выполняемая \usevar
, которая откладывает \x
, расширяет \the\numexpr#2\relax
, которая возвращает целое число, а затем возвращается к \x
(своему первому аргументу, в общем), который теперь «видит» вычисленный аргумент.
решение2
Небольшое дополнение к исправлению @egreg:
Если мы хотим оценить только выражения, похожие на {2*\ind+5}
решение @egreg, то оно будет выглядеть так:
\newcommand{\useevalof}[1]{%
\the\numexpr#1\relax%
}
Пример: Рассмотрим $A_{\ind-4}$
. Если \ind
имеет значение 6, $A_{\useevalof{\ind-4}}$
даст$A_2$
Это действительно полезно для меня. Я разрабатываю библиотеку Tikz для строительной механики для инженеров-строителей. Посмотрите на картинки ниже. Уровни полностью автоматизированы.
Отмечено: удалено \expandafter
после примечания @egreg.