我想知道如何使用 绘制递归关系foreach
,这需要在循环内更新变量。为了在不复制大量代码的情况下使其具体化,请考虑这个现有的例子,它使用复制/粘贴而不是foreach
。是否可以将此示例更改为在foreach
循环中更新变量,而无需在文档范围内引入定义。如果不行,为什么不行?
另一个具体的例子是,这个答案使用foreach
但引入了全局定义(参见 行\newcommand{\x}{.1}
)。我不想在文档范围内引入任何定义。这肯定是使用 TikZ 寄存器的某种方法吧?如果不是,你能说说为什么不行吗?
从抽象上讲,该问题涉及初始条件、函数迭代产生的序列以及序列中每个相邻对产生的坐标的绘制。例如,给定 x0,然后 x1=f(x0),在 (x0,x1) 处绘制一个点。然后,给定 x2=f(x1),在 (x1,x2) 处绘制一个点。依此类推,根据需要多次进行。
答案1
你可以进行浮点计算(比 Ti 更准确)钾Z) 使用expl3
。
\documentclass{article}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz,fullpage}
\usetikzlibrary{arrows}
\usepackage{xfp}
\ExplSyntaxOn
\NewDocumentCommand{\xforeach}{mmm}
{
\int_step_inline:nnn { #1 } { #2 } { #3 }
}
\NewDocumentCommand{\setfpvar}{mm}
{
\fp_zero_new:c { l__alan_fpvar_#1_fp }
\fp_set:cn { l__alan_fpvar_#1_fp } { #2 }
}
\NewExpandableDocumentCommand{\usefpvar}{m}
{
\fp_use:c { l__alan_fpvar_#1_fp }
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}[scale=10,>=latex']
\draw[color=blue,samples at={0,0.01,...,1.07}] plot (\x,{cos(\x r)});
\draw[color=green](0,0)--(1,1);
\draw[->](0,0)--(0,1) node[above]{$y$};
\draw[->](0,0)--(1,0) node[right]{$x$};
% initialize “x”
\setfpvar{x}{.2}
% the main loop
\xforeach{1}{7}{%
\setfpvar{y}{cos(\usefpvar{x})}
\draw[color=magenta](\usefpvar{x},\usefpvar{x})--
(\usefpvar{x},\usefpvar{y})--
(\usefpvar{y},\usefpvar{y});
\draw[color=orange,dotted,line width=0.8pt]
(\usefpvar{x},\usefpvar{x})--(\usefpvar{x},0) node[below=8pt]{$u_{#1}$};
\draw[color=blue,dotted,line width=0.8pt]%
(\usefpvar{x},\usefpvar{y})--(0,\usefpvar{y}) node[left=8pt] {$u_{\inteval{#1+1}}$};
% in the next cycle “x” will take the current value of “y”
\setfpvar{x}{\usefpvar{y}}
}
\end{tikzpicture}
\end{document}
无需全局声明,因为循环不需要分组运行。循环变量表示为#1
。的参数\xforeach
是起点、终点和要运行的代码。
实际上变量名称是全局声明的,但这不是问题,因为它们位于自己的命名空间中。
答案2
以下复制了蛛网图这个答案@egreg 的代码也是如此(见上文)。我认为我提出的答案更简单,更接近我的问题,除非我错过了什么,因为它只使用了包fp
。但是,它确实利用了remember
选项\foreach
,我无法从文档中推断出来,所以希望我使用的是有意为之的功能,而不是实现细节。(有人可以证实吗?)关键技巧是在循环结束时重新定义循环变量,以便新定义成为“记住的”值。参见循环体中的最后一行。
\begin{tikzpicture}[scale=10,>=latex']
\draw[color=blue,samples at={0,0.01,...,1.07}] plot (\x,{cos(\x r)});
\draw[color=green!50](0,0)--(1,1);
\draw[<->](0,1) node[above]{$y$} |- (1,0) node[right]{$x$};
\foreach \i [remember=\i as \x (initially 0.2)] in {1,...,7}{%
\FPeval\y{cos \x}
\draw[color=magenta](\x,\x)--(\x,\y)--(\y,\y);
\draw[color=orange,dotted,line width=0.8pt]%
(\x,\x)--(\x,0) node[below=8pt]{$u_\i$};
\draw[color=blue,dotted,line width=0.8pt] (\x,\y)--(0,\y) node[left=8pt]
{$u_{\pgfmathparse{int(\i+1)}\pgfmathresult}$};
\FPeval\i{\y}
}
\end{tikzpicture}
顺便说一句,我在探索过程中发现的一件事是数学解析必须接近\pgfmathresult
,因为这还保存了 TikZ 正在进行的其他计算的结果。