是 Tikz 的数值精度有限还是我不理解这种转换?

是 Tikz 的数值精度有限还是我不理解这种转换?

我正在使用形式为(-n 激活)非线性变换

x \mapsto (x + a * sin x), y \mapsto y

问题在于x = nπ,对于整数 n , 的点应该是变换的固定点,因为sin(nπ) = 0。将变换应用于以下对象似乎显示出与此推理预期的偏差。

变换应用于网格和函数y = f(x) = x而另一个相同的网格和函数则省略变换以供比较。代码和结果如下。我请你看一下预期相交的点。这似乎没有发生。第二张图片是从红线和蓝线的最后一个相交点拍摄的。

这是数值精度的限制吗?我该如何改进?

\documentclass[tikz,border=3mm]{standalone}
\usepgfmodule{nonlineartransformations}

\makeatletter
\def\mytransformation{%
\pgfmathsetmacro{\myX}{\pgf@x + (10)*sin(\pgf@x) }
\pgfmathsetmacro{\myY}{\pgf@y}
\setlength{\pgf@x}{\myX pt}
\setlength{\pgf@y}{\myY pt}
}
\makeatother

\begin{document}
\begin{tikzpicture}

\begin{scope}
\pgftransformnonlinear{\mytransformation}
\draw [red] (0,0) grid [xstep=.5*pi, ystep=-1] (23,23);
\draw [red, thick] (0,0) -- (20,20);
\end{scope}

\draw [blue, dashed,] (0,0) grid [step=.5*pi] (23,23);
\draw [blue, thick] (0,0) -- (20,20);

\end{tikzpicture}
\end{document}

在此处输入图片描述 在此处输入图片描述

答案1

让我们分解一下:

  1. PGFmath 假设 sin、cos 等参数以度为单位,而不是弧度,因此我们需要使用degr后缀运算符进行转换:sin(deg(X)或 sin(X r)。

  2. TikZ/PGF/TeX 内部与 pt 一起工作,其中1 厘米 = 28.45274 点。因此,即使我们将弧度转换为度数,结果也是完全错误的。

  3. TikZ/PGF 用途各种坐标系. 最重要的是

    • canvas我们使用实际长度的坐标系:(10mm, -3em)
    • xyz系(尽管我们经常只使用X) 其中我们使用标量值:(2, 2*pi+3/2)

    这两个坐标系都有极坐标版本(<angle>:<value>),但可以转换为X轻松获取价值。

    坐标系如何xyz知道一个值的长度,例如22*pi+3/2在纸上有多长?它使用另一个转换层和赋予键的值xy以及z。默认情况下,它们是x = 1cm(表示画布上向右方向 1 厘米)和y = 1m(向上)。

    这是PGF 在其层上提供

那么我们除以\pgf@x并将1cm其转换为度数就完成了吗?

1cm不完全是。首先,我们可以通过使用\pgf@xx除以来访问的值\pgf@x,但这样我们就在坐标系中了。我们需要通过将正弦乘以来xyz返回坐标系,这将带我得到你应该想要使用的这个公式:canvas\pgf@xx

\def\mytransformation{%
  \pgfmathsetlength\pgf@x{\pgf@x + 10*\pgf@xx*sin(\pgf@x/\pgf@xx r)}%
}

也就是说,转换画布X值返回到其 xyzX值,将其转换为度数,取其正弦值,然后将其乘回到画布坐标系(然后乘以 10 的因子)。


现在,如果你使用更复杂的xyz坐标系,我们就说x = {(1cm, 1cm)},即X轴在纸面上呈45°角,长度均为√2

  • \pgf@xx(单位的长度X轴入X方向)和
  • \pgf@xy(单位的长度X轴入方向)

将设置为 28.45274pt。
(是的,还有\pgf@yy\pgf@yx\pgf@zx\pgf@zy

我不知道你的转变会是什么样子。(那时候,我相信这是一个数学问题。)


如果你查看手册中的例子非线性变换你会注意到它只使用canvas坐标系中的坐标。该\polartransformation示例甚至使用

\draw (0pt,0mm) grid [xstep=10pt, ystep=5mm] (90pt, 20mm);

注意90pt!对于它要绘制的四分之一圆,这将是 90°。(或者 3.16314cm,即(3.16314, 2)在坐标系中xyz。有点接近 π,但纯属偶然——无论如何我们都在寻找 π/2。)


我已经添加了阴谋

\draw[dashed, ultra thick] plot[smooth,samples=100,domain=0:20] ({\x + 10 * sin(\x r)}, \x);

以供比较。根据您的实际任务,这可能只是一种绘制符合任何(?)变换的线条的更简单方法。

如果你真的想绘制一些东西,可以使用

代码

\documentclass[tikz,border=3mm]{standalone}
\usepgfmodule{nonlineartransformations}
\makeatletter
\def\mytransformation{%
  \pgfmathsetlength\pgf@x{\pgf@x + 10*\pgf@xx*sin(\pgf@x/\pgf@xx r)}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[x=.5cm]% for fun
\foreach \x in {-3,...,10}
  \path (0:\x*pi) node[below]{$\x\pi$}                   edge[help lines, very thin]         + (up:20) edge + (up:2pt) 
     ++ (0:.5*pi) node[below]{$\pgfmathprint{\x+.5}\pi$} edge[help lines, very thin, dotted] + (up:20) edge + (up:1pt);
\draw[dashed, ultra thick] plot[smooth,samples=100,domain=0:20] ({\x + 10 * sin(\x r)}, \x);
\foreach \sh in {-10,0,10}
  \draw[shift=(0:\sh)] (0,0) -- (20,20);
\begin{scope}
  \pgftransformnonlinear{\mytransformation}
  \draw [thick, red] (0,0) -- (20,20);
\end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容