为什么在 TikZ 中要绘制的函数的独立变量必须是宏?

为什么在 TikZ 中要绘制的函数的独立变量必须是宏?

考虑以下代码(取自 Jake 的回答)并关注要绘制的函数的变量。

\documentclass[border=5pt,tikz]{standalone}

\begin{document}
\begin{tikzpicture}
    \draw [domain=0:50,variable=\t,smooth,samples=500]
        plot ({\t r}: {1+2*exp(-\t/10)});
\end{tikzpicture}
\end{document}

我的问题很简单,为什么变量必须是一个宏(\t在这种情况下),而不仅仅是一个字母(例如t)或一个单词(例如theta),因为我认为我们在使用图形计算器或计算机代数系统时通常使用字母?例如,PSTricks 在绘图时也不需要宏。在 PSTricks 中,独立变量\psplot[algebraic]{-4}{4}{x^2-5*x+6}在哪里x,它不需要是宏\x

使用宏的相关情况是当我们使用诸如 之类的循环时\foreach \t in {1,...,2}{<do with \t>}。但我不认为绘图需要\t向用户公开这样的迭代变量。希望您理解我所不理解的内容。

你可能会想我为什么会大惊小怪。因为宏使得函数表达式不再自然、优雅、美观、简单等。例如,t^2-5*t+6变成了\t*\t-5*\t+6,这不自然,当然,的存在\消耗了更多的击键次数。

您认为当前语法中独立变量必须是宏有一个好处吗?

答案1

编写解析器时pgfmath,主要目的是提供持续的calc并且比该包(以前负责执行所有计算)的数学运算稍微更通用,而没有该fp包的开销。此外,与变量的集成\foreach也很重要(如上所述)。

因此,每个传递给pgfmath解析器的表达式\edef在解析之前都会被立即执行。这意味着在大多数情况下(除非你巧妙地使用\noexpand双引号),

  • 任何未扩展的标记都是TeX寄存器
  • 解析器不必担心检查标记是否可扩展

目前,可以定义一个可以代表绘图变量的函数(如上所示)。据我所知,这是实现 OP 要求的唯一方法。但(正如已经指出的那样)解析数字比解析/评估函数更快。

作为“附注”,我真心想pgfmath暂时修复一下数学运算,PGF并认为luatex等到“合适的”程序员出现时,他们会介入并解决问题。可惜这并没有发生。

答案2

为什么?我不知道。

不过,TikZ 除了遍历域之外不做任何其他事情。当 TikZ 绘制函数时,它会\pgfplotfunction为此使用 PGF 宏。在我们的例子中,它被调用的方式类似于(第三个参数不正确,但这基本上是您在 PGF 中执行此操作的方式)

\pgfplotfunction{\t}{0, 0.10019, ..., 50}{\pgfpointpolar{\t r}{1+2*exp(-\t/10)}

在定义中\pgfplotfunction我们发现类似

% Initialize plotting
\foreach #1 in {#2}{
   % parse #3, extract x and y and sent it to the plotter
}
% Do the actual plotting

解决方法是定义一个 PGFmath 变量,该变量仅扩展到绘图仪使用的变量。为了不覆盖任何已定义的宏(如\t或)\theta(路径上的节点可以使用),我在 am@cro 中“隐藏”了实际变量名称。

\tikzset{
  variable*/.style={
    declare function={#1=\tikz@plot@var;},
    variable=\tikz@plot@var}}

现在您可以说variable*=theta然后在函数中使用theta而不是。\t

我在下面的代码中添加了一个“快速”版本,因为我们的变量已经由循环计算\foreach,不需要额外的解析或评估。因此,我将迭代器的值直接复制到\pgfmathresult


请注意,如果你使用 gnuplot(TeX 和 TikZ 的外部工具)进行绘图,使用function绘图运算符如下

\draw plot[parametric, domain=0:50, samples=500, smooth]
        function {cos(t)*(1+2*exp(-t/10)), sin(t)*(1+2*exp(-t/10))};

您需要使用变量x,对于参数图,t

代码

\documentclass[border=5pt,tikz]{standalone}
\makeatletter
\tikzset{variable*/.code=\pgfmathdeclarefunction{#1}{0}{\let\pgfmathresult\tikz@plot@var}%
                         \def\tikz@plot@var{\tikz@plot@var}}
\makeatother
\begin{document}
\begin{tikzpicture}
    \draw [domain=0:50,variable*=theta,smooth,samples=500]
        plot (theta r: {1 + 2 * exp( -theta / 10)});
\end{tikzpicture}
\end{document}

答案3

(编辑)2017:由于xint 1.1 (2014/10/28)xinttools不再被 加载xintfrac。代码已更新。


我根本不推荐它,因为好的 key=value 语法已经丢失,但可以完成一些工作TikZ,避免在绘图中使用变量的宏。但仍然需要一个宏,现在用于给出绘制点的表达式。我试过不用它,但似乎coordinates需要一些完全可扩展的东西,所以我不能\xintFor在那里使用它。

\Sample\SamplE\SampleFit有点难以理解,它们的作用是计算 ,这将由与实际绘图相对应的#1宏(名称任意)使用。将是小数点后有 4 位的定点数。\PointMacro#1

\documentclass[border=5pt,tikz]{standalone}
\usepackage{xintfrac, xinttools}

% \Sample {N}\pointmacro {start:end}
% it returns expandably the N points from  N equispaced samples starting with
% start and ending with end.
% \pointmacro (name arbitrary) 
% should be a one-parameter macro which returns a point
% as recognized by tikz (such as (x,y), or (angle:radius))
% example \def\macro #1 {(#1, {(#1)^2})}
% see examples below

\def\Sample #1#2#3{\SamplE {#1}#2#3;}

\def\SamplE #1#2#3:#4;{\expandafter\xintApplyUnbraced\expandafter
     {\expandafter\SampleFit\expandafter #2\expandafter
       {\romannumeral0\xintdiv{\xintSub{#4}{#3}}{\xintDec{#1}}}{#3}}
     {\xintSeq{0}{#1-1}}}

\def\SampleFit #1#2#3#4{\expandafter #1\expandafter{\romannumeral0%
                       \xinttrunc {4}{\xintAdd{#3}{\xintMul{#2}{#4}}}}}

\begin{document}    
\tikzset {x=.5cm, y=.5cm}

\begin{tikzpicture}
    \def\ParabolaPoint #1{(#1, {(#1)^2})}% negative #1 within parentheses!
    \draw [smooth] plot coordinates {\Sample {25}\ParabolaPoint {-2:2}};
\end{tikzpicture}

\begin{tikzpicture}
    \def\CubicPoint #1{(#1, {(#1)^3})}
    \draw [smooth] plot coordinates {\Sample {25}\CubicPoint {-1.25:1.25}};
\end{tikzpicture}

\begin{tikzpicture}
    \def\SpiralPoint #1{({#1 r}: {1+2*exp(-#1/10)})}
    \draw [smooth] plot coordinates {\Sample {200}\SpiralPoint {0:50}};
\end{tikzpicture}

\end{document}

抛物线立方体螺旋

相关内容