在 \edef 中使用 tikz \foreach

在 \edef 中使用 tikz \foreach

我想\foreach在里面使用\edef,例如定义一组随机点,如下所示:

\edef\mypoints{%
  \foreach \x in {0,.1,...,1}
           {\pgfmathparse{rand} (\x,\pgfmathresult)}}

不幸的是,上面的代码导致了一个错误 Undefined control sequence \pgffor@remember@once@code

我的问题是为什么这不起作用,以及保存\foreach循环结果的最简单的解决方法是什么。

答案1

另一个答案提供了一个可行的解决方案,但其缺点是使用全局定义,除非真正必要,否则应该避免使用全局定义。pgf 附带了/.list密钥处理程序,可以避免使用全局定义。

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[add point/.code={\pgfmathparse{rand}%
    \edef\mypoints{\mypoints(#1,\pgfmathresult)}}]
    \def\mypoints{} % initialize
    \tikzset{add point/.list={0,0.2,...,5}}% loop without global definitions
    \draw plot coordinates {\mypoints};
\end{tikzpicture}    
\end{document}

答案2

您必须在外面进行循环\edef

\gdef\mypoints{} % initialize
\foreach\x in {0,0.1,...,1} {%
  \pgfmathparse{rand}%
  \xdef\mypoints{\mypoints(\x,\pgfmathresult)}%
}

因此在每个循环中你都会附加新的点。


使用上面的代码,我们可能会得到类似

(0,-0.5593)(0.1,0.51411)(0.20001,0.55302)
(0.30002,0.51347)(0.40002,-0.54858)(0.50003,-0.64978)
(0.60004,0.61548)(0.70004,-0.32903(0.80005,0.2993)
(0.90005,-0.38226)

(为了清晰起见,换行了)。嗯,这确实不是我们所期望的。

我们可以避免这种情况以及全局声明。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\fpforeach}{mmmm}
 {% #1 = start, #2 = step, #3 = end, #4 = template
  \fp_step_inline:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\NewDocumentCommand{\clearlist}{m}
 {
  \tl_clear_new:c { l_egreg_list_#1_tl }
 }
\NewDocumentCommand{\addtolist}{smm}
 {
  \IfBooleanTF{#1}{\tl_put_right:cx}{\tl_put_right:cn} { l_egreg_list_#2_tl } { #3 }
 }
\NewExpandableDocumentCommand{\uselist}{m}
 {
  \tl_use:c { l_egreg_list_#1_tl }
 }

\ExplSyntaxOff
  
\clearlist{points} % initialize
\fpforeach{0}{0.1}{1}{%
  \addtolist*{points}{(#1,\fpeval{round(2*rand()-1,4)}) }
}

\begin{document}

\raggedright
\uselist{points}

\end{document}

由于rand()仅返回 0 到 1 之间的数字,但pgfmath函数rand返回从 -1 到 1 的数字,因此我使用2*rand()-1

可能的输出是

在此处输入图片描述

尾随空格仅用于排版目的。在的第四个参数中\fpforeach#1代表循环中的当前值。

\addtolist命令只是简单地添加,但*也会进行完全扩展。

请注意,x 坐标确实是从 0 到 1,因为l3fp使用浮点十进制数(而不是像 那样将固定精度的二进制转换成十进制pgfmath)。

相关内容