我想在 tikz 命令中使用简单的宏,但 tikz 似乎没有按照我期望的方式扩展它们。
例如,代码
\pgfpointcurveattime{.25}{\pgfpoint{0cm}{0cm}}{\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}
很好地返回了这四个点指定的贝塞尔曲线四分之一处的点。然而代码
\newcommand{\bcurve}{{\pgfpoint{0cm}{0cm}}{\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}}
\pgfpointcurveattime{.25}\bcurve
给出错误,即使它扩展为相同的字符串。在 \bcurve 两边加上括号也没有用。
这个问题的原因是什么?更一般地说,在 tikz 中,在这种情况下如何使用宏?
答案1
我对 TeX 扩展的了解相当有限,但我认为问题不在于 PGF,而在于 TeX 本身。它\pgfpoincurveattime
首先尝试扩展,并在扩展 之前查找其参数\bcurve
。因此\bcurve
被视为 的参数之一\pgfpointcurveattime
,而 TeX 会在随后的文本中查找其他参数。
因此,您要做的就是\bcurve
先扩展(一次)。要更改扩展顺序,可以使用\expandafter
:\expandafter\a\b
扩展\b
并在之后添加结果\a
,然后继续处理\a
。这里的问题是您想跳过五个标记({.25}
),这将需要很多\expandafter
s:
\expandafter\pgfpointcurveattime\expandafter{\expandafter.\expandafter2\expandafter5\expandafter}\bcurve
执行完 s 之后\expandafter
,TeX 将
\pgfpointcurveattime{.25}{\pgfpoint{0cm}{0cm}}{\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}
节省输入所有这些内容\expandafters
并获得更易读的代码的一个可能的解决方案是将其保存.25
到可以一步跳过的宏中:
\newcommand*\pos{.25}
\expandafter\pgfpointcurveattime\expandafter\pos\bcurve
执行完 s 之后\expandafter
,TeX 将
\pgfpointcurveattime\pos{\pgfpoint{0cm}{0cm}}{\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}
答案2
您可以定义这样的辅助宏:
\def \mycurve #1{
\pgfpointcurveattime{.25}#1
}
\newcommand{\bcurve}{{\pgfpoint{0cm}{0cm}}{\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}}
然后
\expandafter \mycurve \expandafter {\bcurve}
或者
\edef \marshal{\noexpand \mycurve{\bcurve}}
\marshal