PGF 循环 - 如何在 pgfmathdeclare 函数中使用数组?

PGF 循环 - 如何在 pgfmathdeclare 函数中使用数组?

我想在循环中从数组中选取一个数字。第一个参数是“起始”值,该值基于第二个和第三个参数 ( \qa) 每次迭代递增 1。最大迭代次数可由第二个参数 ( ) 确定。\eval@limit另一个最大值可由第三个参数 ( ) 的值确定\arbitraryarrayvalue

我在使用数组时遇到了一些问题\pgfmathdeclarefunction。具体来说:第一种情况,最简单的情况,就是简单地说:

\pgfmathparse{\myarray[\arbitraryarrayvalue]}
\pgfmath@smuggleone\pgfmathresult

在关闭组之前。事实证明我无法查看数组内部:

Paragraph ended before \pgfflt@readlowlevelfloat was complete.
<to be read again> 
                   \par 

因此,查看现有问题后,我发现一个相关问题\pgfflt@readlowlevelfloat,位于如何使用 pgfmathdeclarefunction 来定义新的 pgf 函数?

我无法从该问题推断出我的答案。

第二种情况:如果我使用解决方案中的数组Expl3进行比较(您也可以在下面的代码中找到此解决方案),我会收到如下错误:

File ended while scanning use of \__fp_parse_after:ww.
Emergency stop.
==> Fatal error occurred, no output PDF file produced!

因此,从它们都指“文件在执行某项操作时结束”这一事实来看,我怀疑这些宏会继续读取并进一步扩展,直到文档结束,我通常用一个合适的位置来解决\relax。我试过在各处添加它(在比较中、在它之后、在数组中等等),但似乎无法摆脱错误。

可能不太相关,但可能是一个通用的解决方案外部 expl3是答案 (?) 不管怎样,我想看看这种打破循环的通用解决方案在外面是怎样的expl3。:-)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}

\usepackage{expl3}

\ExplSyntaxOn
\cs_new:Npn \breakloop #1 #2
  {
    \fp_compare:nNnT { #1 } > { #2 }
      { \breakforeach }
  }
\ExplSyntaxOff

\global\def\myarray{{5,10,15,20,25,30,35,40,45,50,55,60}}

\makeatletter
\pgfmathdeclarefunction{blah}{3}{%
  \begingroup
    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
    \pgfmathparse{#1} % starting value
    \edef\qa{\pgfmathresult}
    \pgfmathparse{#2} % maximum amount of loops
    \edef\eval@limit{\pgfmathresult}
    \pgfmathparse{#3+1} % maximum value of array
    \edef\arbitraryarrayvalue{\pgfmathresult}
    \foreach \i in {0,...,\eval@limit}
    {
      \pgfmathparse{\qa+1} % \qa += 1
      \global\edef\q@{\pgfmathresult} %
      \pgfmathparse{\q@} %
      \global\edef\qa{\pgfmathresult} %
      \breakloop{\qa}{\myarray[\arbitraryarrayvalue]}
    }
    \pgfmathparse{\qa}
    \pgfmath@smuggleone\pgfmathresult
  \endgroup
}
\makeatother
\begin{document}
\pgfmathparse{blah(1,1000,9)}\pgfmathresult    %

\pgfmathparse{\myarray[2]}\pgfmathresult
\end{document}

答案1

这个问题可以通过首先评估数组元素来解决。获取元素需要传递一个整数作为索引,而不是定点表示法中的数字。我已将数组元素的评估移到循环之外,因为它不会随迭代而变化。

示例输出

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fpu}

\usepackage{expl3}

\ExplSyntaxOn
\cs_new:Npn \breakloop #1 #2
  {
    \fp_compare:nNnT { #1 } > { #2 }
      { \breakforeach }
  }
\ExplSyntaxOff

\gdef\myarray{{5,10,15,20,25,30,35,40,45,50,55,60}}

\makeatletter
\pgfmathdeclarefunction{blah}{3}{%
  \begingroup
    \pgfmathparse{#1} % starting value
    \edef\qa{\pgfmathresult}
    \pgfmathparse{#2} % maximum amount of loops
    \edef\eval@limit{\pgfmathresult}
    \pgfmathparse{#3+1} % maximum value of array
    \edef\arbitraryarrayvalue{\pgfmathresult}
    \pgfmathparse{\myarray[\arbitraryarrayvalue]}
    \edef\qb{\pgfmathresult}
    \pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
    \foreach \i in {0,...,\eval@limit}
    {
      \pgfmathparse{\qa+1} % \qa += 1
      \xdef\q@{\pgfmathresult} %
      \pgfmathparse{\q@} %
      \xdef\qa{\pgfmathresult} %
      \breakloop{\qa}{\qb}
    }
    \pgfmathparse{\qa}
    \pgfmath@smuggleone\pgfmathresult
  \endgroup
}
\makeatother
\begin{document}
\pgfmathparse{blah(1,1000,9)}\pgfmathresult    %

\pgfmathparse{\myarray[4]}\pgfmathresult
\end{document}

相关内容