还有其他方法可以避免嵌套多项式中的名称冲突吗?

还有其他方法可以避免嵌套多项式中的名称冲突吗?

约束

  • 我想对内循环和外循环使用相同的名称。
  • 我不愿意附加@并使用\makeatletter...\makeatother

是否有任何名称间距构造可供使用?

平均能量损失

由于两者发生冲突,因此以下代码不会产生正确的结果\i

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\def\Triangle(#1)#2{{\rput(#1){\multido{\i=0+1}{#2}{\multips(\i,0)(!.5 3 sqrt 2 div){\numexpr#2-\i\relax}{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}


\usepackage[nomessages]{fp}
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
    \multido{\i=1+1}{\N}{\Triangle(!\i\space 1 sub \i\space 2 add mul 2 div 0){\i}}
\end{pspicture}
\end{document}

正确的输出如下。

在此处输入图片描述

答案1

通过在循环中为每个标识符使用唯一名称可以避免名称冲突。但是,在这种情况下,将参数直接传递给内部\multido意味着它们在使用之前不会展开,此时也需要设置它们。“预展开”(声明包含参数展开版本的宏)有助于避免这种情况:

在此处输入图片描述

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}% http://ctan.org/pkg/multido
\SpecialCoor
\def\Triangle(#1)#2{%
  \edef\firstarg{#1}\edef\secondarg{#2}% pre-expand #1 and #2
  \rput(\firstarg){\multido{\i=0+1}{\secondarg}{\multips(\i,0)(!.5 3 sqrt 2 div){\numexpr\secondarg-\i\relax}{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}

\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
  \multido{\i=1+1}{\N}{\Triangle(!\i\space 1 sub \i\space 2 add mul 2 div 0){\i}}
\end{pspicture}
\end{document}

答案2

您可以使用\xintFor包中的循环新工具. 人们不必担心迭代变量所使用的名称。

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{xinttools}
\SpecialCoor

% inside a macro, the # for an \xintFor must be doubled
%
\def\Triangle(#1)#2{{\rput(#1)%
                    {\xintFor* ##1 in {\xintSeq {0}{#2-1}}\do
                     {\multips(##1,0)(!.5 3 sqrt 2 div)%
                         {\numexpr#2-##1\relax}%
                         {\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}


\usepackage[nomessages]{fp}
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
    \xintFor* #1 in {\xintSeq{1}{\N}} \do
    {\Triangle(!#1 1 sub #1 2 add mul 2 div 0){#1}}
\end{pspicture}
\end{document}

三角形

\Width\Height可以实时计算xintexpr

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{xintexpr}% loads xinttools automatically
\SpecialCoor

% inside a macro, the # for an \xintFor must be doubled
%
\def\Triangle(#1)#2{{\rput(#1)%
                    {\xintFor* ##1 in {\xintSeq {0}{#2-1}}\do
                     {\multips(##1,0)(!.5 3 sqrt 2 div)%
                         {\numexpr#2-##1\relax}%
                         {\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}

\providecommand\firstofone [1]{#1}

\begin{document}
\def\N {4}
%
% we use \xintthenumexpr for the width as it guarantees 
% integer format on output
%
% we use \firstofone to hide parentheses and other things from pspicture
% 
\begin{pspicture}(\firstofone{\xintthenumexpr (\N-1)*(\N+2)/2+\N\relax},%
                  \firstofone{\xinttheexpr round(sqrt(3)*\N/2,6)\relax})
    \xintFor* #1 in {\xintSeq{1}{\N}} \do
    {\Triangle(!#1 1 sub #1 2 add mul 2 div 0){#1}}
\end{pspicture}
\end{document}

\firstofone必须使用技巧来隐藏括号。出于某种原因,将整个 -essions 放在括号xintexpr内不起作用pspicture。括号里面 \xintexpr .. \relax具有特殊含义,例如可以\xintthenumexpr{\xinttheexpr..\relax}\relax对宽度这样做,但这确实很复杂。

相关内容