无法通过 tikz 中由 \newcommand 构造的宏计算坐标值

无法通过 tikz 中由 \newcommand 构造的宏计算坐标值

我构造了一个名为\mycal(带有可选参数) 的宏来计算将在 中使用的坐标值\tikz\draw。我发现使用这个可选参数,代码无法编译。当可选参数变为强制参数时,代码可以正常工作。但我确实需要这个可选参数。为什么以及如何解决这个问题?

梅威瑟:

\documentclass{article}
\usepackage{tikz,picture}

\begin{document}
% The following part can not compile
% \newcommand{\mycal}[3][0pt]{\the\dimexpr #2 + #3 + #1}
% \newcommand\mydraw[3]{\tikz\draw(0,0)--(\mycal[#1]{#2}{#3},0);}
% \mydraw{1pt}{2cm}{3cm}

% The following part ok!
\newcommand{\mycal}[3]{\the\dimexpr #2 + #3 + #1}
\newcommand\mydraw[3]{\tikz\draw(0,0)--(\mycal{#1}{#2}{#3},0);}
\mydraw{1pt}{2cm}{3cm}
\end{document}

答案1

您的宏不起作用,因为带有可选参数的宏不可扩展,因此不能在路径构造的中间使用。Tex 必须执行一些赋值来确定可选参数是否存在。解决方案可能是使用\pgfextra允许您暂时中断路径构造并执行一些代码。您必须修改代码以将计算结果保存到某个寄存器,然后使用它。

\documentclass{article}

\usepackage{tikz}

\newdimen\mydimen
\newcommand\mycal[3][0cm]{\mydimen=\dimexpr #2 + #3 + #1\relax}
\newcommand\mydraw[3][0cm]{\tikz\draw(0cm,0cm) \pgfextra{\mycal[#1]{#2}{#3}} --(\mydimen,0cm);}

\begin{document}
\mydraw[1cm]{2cm}{3cm}

\mydraw{2cm}{3cm}
\end{document}

顺便说一句,在您的示例中,\mycal实际上并不需要采用可选参数\mydraw

\newcommand\mycal[3]{\dimexpr #2 + #3 + #1\relax}
\newcommand\mydraw[3][0cm]{\begin{tikzpicture}\draw(0cm,0cm)-- (\mycal{#1}{#2}{#3},0cm);

编辑:

如果你坚持要使用\mycal可选参数而不使用\pgfextra,那么你可以使用以下技巧。它定义了一个\mycalc带有可选参数的可扩展函数。

\documentclass{article}

\usepackage{tikz}

\makeatletter
\def\mycal#1{%
  \ifx[#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@mycal[}{\@mycal[0cm]{#1}}}
\def\@mycal[#1]#2#3{\dimexpr#1+#2+#3\relax}
\makeatother

\begin{document}
\tikz\draw(0cm,0cm)--(\mycal{2cm}{3cm},0cm);

\tikz\draw(0cm,0cm)--(\mycal[1cm]{2cm}{3cm},0cm);
\end{document}

新编辑:

要用\mycal{2cm,3cm}or\mycal[1cm]{2cm,3cm}代替\mycal{2cm}{3cm}or,\mycal[1cm]{2cm}{3cm}您可以定义\mycal如下

\documentclass{article}

\usepackage{tikz}

\makeatletter
\def\mycal#1{%
  \ifx[#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@mycal[}{\@mycal[0cm]{#1}}}
\def\@mycal[#1]#2{\@@mycal{#1}#2\@nil}
\def\@@mycal#1#2,#3\@nil{\dimexpr#1+#2+#3\relax}
\makeatother

\begin{document}
\tikz\draw(0cm,0cm)--(\mycal{2cm,3cm},0cm);

\tikz\draw(0cm,0cm)--(\mycal[1cm]{2cm,3cm},0cm);
\end{document}

相关内容