使用 Tikz pgfmathtruncatemacro 分配数值变量

使用 Tikz pgfmathtruncatemacro 分配数值变量

我正在努力使用 Tikz 进行一些基本计算,并且在为本地范围内的变量分配值时遇到了问题。

考虑以下 MVCE:

\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}

\newcommand{\mycommand}
{
    \def\myvar{0};
    \def\myresult{3};
    \ifnum\myvar=0
    {
        \def\myresult{4};
        \draw (0,1) node {Test is true!};
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{document}
\begin{tikzpicture}
\mycommand
\end{tikzpicture}
\end{document}

这样写的话,将会打印“测试为真!”,但是的值myresult仍为 3。

因此,我假设第二条\def命令创建了一个新变量,其范围仅限于块if。经过一番搜索,似乎我可以通过使用以下\global命令将变量定义为“全局”来解决问题:

\newcommand{\mycommand}
{
    \def\myvar{0};
    \global\def\myresult{3};
    \ifnum\myvar=0
    {
        \global\def\myresult{4};
        \draw (0,1) node {Test is true!};
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

这样,它就可以工作了,尽管我不确定这是否是最佳的(\global似乎是一个 TeX 命令,并且我已经多次读过在 LaTeX 源中使用低级 TeX 命令是个坏主意......)

但是现在,我的实际代码有点复杂,在“if”块中,它实际上是一个\pgfmathtruncatemacro。比如说:

\newcommand{\mycommand}
{
    \def\myvar{0};
    \global\def\myresult{3};
    \ifnum\myvar=0
    {
        \pgfmathtruncatemacro{\myresult}{4}
    }
    \fi;
    \draw (0,0) node {myresult=\myresult !!!};
}

然后我遇到了与上面相同的问题:\pgfmathtruncatemacro似乎声明了一个新变量,因为我保留该值3......

并且两者

\global\pgfmathtruncatemacro{\myresult}{4}

或者

\pgfmathtruncatemacro{\global\myresult}{4}

编译失败。

我怎样才能摆脱这个问题?

答案1

这是一种相当安全的“广播”结果的方法,即使得在群组之外使用。

  • 在这种情况下,您可以只使用\xdef\xdef危险吗?嗯,这取决于上下文。如果您注意不要重新定义已知的宏,则不会。\xdef我不知道是否有人曾经费心提供更万无一失的版本。如有疑问,当然应该检查\@ifdefined命令是否已定义。如果需要,我可以尝试按照这些思路编写一些东西,但其他人可以做得更好,所以你可能想就此提出一个单独的问题。
  • 如果你进行计算,\pgftruncatemacro你可以用类似的东西广播结果\pgfmathtruncatemacro{\myresult}{4}\xdef\myresult{\myresult}
  • 在某些情况下,例如使用 pgfkeys 时,您不能只使用\xdef。在这种情况下,您可以尝试使用\globaldefs。但是,我强调,除非你绝对确定自己在做什么,否则我不建议这样做。(我曾经在一个答案中使用过它,但当 OP 开始修改它时,它确实引起了问题,所以我非常不愿意走那条路。

这是一个 MWE。

\documentclass{article}
\usepackage{tikz}

\newcommand{\mycommand}
{
    \def\myvar{0}
    \def\myresult{3}
    \ifnum\myvar=0
    {
        \xdef\myresult{4}
        \draw (0,1) node {Test is true!};
    }
    \fi
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{document}

\begin{tikzpicture}
\mycommand
\end{tikzpicture}

\renewcommand{\mycommand}
{
    \def\myvar{0}
    \global\def\myresult{3}
    \ifnum\myvar=0
    {
        \pgfmathtruncatemacro{\myresult}{4}
        \xdef\myresult{\myresult}
    }
    \fi
    \draw (0,0) node {myresult=\myresult !!!};
}

\begin{tikzpicture}
\mycommand
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

在此处输入图片描述

您的初始代码几乎是正确的。问题是由太多不必要但有害的分列引起的。

请注意,最后的分列仅用于结束 TikZ 命令行。

\documentclass[11pt, border=1cm]{standalone}
\usepackage{ifthen}
\usepackage{tikz}

\newcommand{\mycommand}{%
  \def\myvar{0}
  \def\myresult{3}
  \ifnum\myvar=0 \def\myresult{4}{
    \draw (0,1) node {the test is {\color{blue}True}};
  }
  \fi
  {
    \draw (0,0) node {and \textit{myresult} is \myresult};
  }
}

\begin{document}

\begin{tikzpicture}
  \mycommand
\end{tikzpicture}

\end{document}

相关内容