如何在 tikz 宏中创建局部长度变量

如何在 tikz 宏中创建局部长度变量

我在做什么?我正在使用 tikz 定义排版宏。

\newcommand[3]{\mycustomtikzmacro}{
    \begin{tikzpicture}
        %commands based on the three inputs named #1, #2 and #3.
        %the number 3 here is arbitrary
    \end{tikzpicture}
}

我想要什么?为了防止宏的用户必须插入许多任意数字,我想要

  1. 从用户给出的宏输入中读取长度和大小,这样我可以使用它们来确定宏内的间距、大小和定位。
  2. 将此信息存储在当地的变量,以便宏可以被多次使用。
  3. 用读出的数据进行计算,包括创建新变量。我最好在一个专门的“地方”进行所有计算,以尽可能保持代码整洁。
  4. 将我收集的变量放入典型的 tikz 命令中使用。

什么样的答案最受欢迎?我更希望得到关于如何使用您展示的系统和命令的解释,而不是试图展示一些有效的东西(这很快就会让一切变得复杂)。我的目标是获得洞察力并学会将您的答案作为一种通用技巧,而不是为了解决我问这个问题的原因。

如果您想使用示例,请保持示例简单且具有说明性,并解释您所使用的语法和命令。


我为什么要问?我找到了各种答案,这些答案的清晰度和适用性各不相同。我的问题是,我没有找到一个能满足我要求的答案组合。我也不太了解代码在所有情况下的作用,例如“这个和那个配合得如何,是命令还是长度,命令和长度和坐标之间有区别吗”,所以我自己很难把事情拼凑起来。这就是我的问题。

我已发现了什么?我似乎无法让第 1 点和第 2 点一起工作。获取变量的一种方法是使用长度和函数\settowidth{}{},我已经成功了。

\newlength{\x} \settowidth{\x}{$#1$} %stores the width of first input in the new var \x

但是,根据我的经验,以这种方式创建的变量是全局的。这意味着会干扰可能使用相同变量名的其他命令,并且意味着两次使用我的宏会导致错误,因为长度被定义了两次。我发现解决这个问题的唯一方法是在每个文档的开头初始化变量(参见下面的代码)。但是这会在第一页留下痕迹,因此一切都需要围绕该页面作为虚拟页面来构建……这并不理想。

\newcommand{\initailisemycustomtikzmacrovariables}{
    \newlength{\x}%purpose of x
    %\setlength{\x}{whatever value I need} %if this length is a global constant
}
\newcommand[3]{\mycustomtikzmacro}{
    \begin{tikzpicture}
        \settowidth{\x}{$#1$}
        %the rest
    \end{tikzpicture}
}

tikzmath{}另一个选择是从 中创建对象内的变量\usetikzlibrary{math}。它允许我定义局部变量并用它们进行计算(第 3 点:检查),但\settowidth在这里不起作用(并且 \settoheight 可能不执行任何操作,有人可能会猜到)。

\tikzmath{
    \y = 0.5*\x;
    %slew of other local variables
}

有一个页面它会提示各种版本的\widthof{}命令。我还没有使用任何两种创建变量的解决方案来实现这一点。


编辑:冒着让这篇文章变得更长的风险,下面是哪些方法有效和哪些方法无效的概述。我尝试了下面简单的虚拟图片(应该生成 ($A$) )的变体,并使用了各种宽度函数。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
    \tikzmath{\width = width("$A$")/2;}
    \draw (-\width,0) node {(};
    \draw (0,0) node {$A$};
    \draw (\width,0) node {)};
\end{tikzpicture}
\end{document}
  1. \tikzmath{\width = \widthof{$A$}/2;}无法编译
  2. \tikzmath{\width = width("$A$")/2;}可以编译,但长度将大约增加 25 倍。
  3. \tikzmath{\width =0.5;} \setlength{\width}{\widthof{$A$}}无法编译,带有 的版本width("$A$")也无法编译,函数settowidth{}{}也无法编译,无论是否带有分号。将此命令放在环境之外tikzmath会使其抱怨缺少数字,并且在某些地方无法使用字符 0。
  4. 在环境之外尝试所有这些变体tikzmath使其能够编译通过该行,但在下一个 tikzpicture 时失败,因为段落在 tikz@math@doassignment 完成之前结束。
  5. \newlength{}{}\setlength{}{}确实有效,但会创建全局变量。我需要希望\width现在没有其他东西使用它们,并且我需要\newlength{}{}在单独的宏中运行命令,在我使用宏之前,我会在某处运行一次。我要么在文档开头手动执行此操作,要么在我第一次使用其中一个宏时自动执行此操作(我如何确保这一点)。此外,它仅在tikzmath我第一次在其中定义一个新变量(可能具有相同的名称)时才有效,即使这样,这次的大小也太大了(即使我使用了\widthof{$A$}width("$A$")也没有编译)。

到目前为止,第 2 点听起来最有希望。但是,将值除以 20 适用于$A$,但对 则不适用$AAAAAAAAAAAAA$,因此不一致。那里可能有其他替代方案吗?也许还有其他宽度函数。

相关内容