向路径添加垂直噪点

向路径添加垂直噪点

为了演示,我想制作一个带有噪声的信号图。我将信号绘制为曲线路径

\begin{tikzpicture}
  \draw [thick,blue] (0,0) .. controls +(50:3) and +(160:2) .. +(3,0);
\end{tikzpicture}

为了增加噪音,我尝试使用random steps装饰器。不幸的是,这个装饰器会在 x 和 y 方向上随机化路径。有没有办法防止这种情况并仅在 y 方向上进行随机化?

答案1

有点类似于@Tom 的解决方案,但使用plot路径命令:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikz}
    \draw plot [domain=-2:2,samples=40,smooth] (\x,{-0.5*\x*\x+0.25*rand});
\end{tikz}
\end{document}

这将绘制曲线 -0.5*x²+0.25*rand,其中rand是介于 -1 和 1 之间的伪随机数,该数在图的每个采样点处独立生成。在上面的例子中,有 40 个采样点。更改此数字会改变曲线的“摆动度”。使smooth曲线变得平滑。将其移除以获得更接近random steps装饰的效果。

例子

如果要修复图像中的特定噪声,请明确设置随机种子\pgfmathsetseed{⟨integer⟩}。其默认值为\time*\year,因此可以在编译运行之间更改。

答案2

无法阻止随机步骤装饰器在两个方向上随机化。您必须创建自己的装饰器:

\pgfdeclaredecoration{random ysteps}{start}
{
  \state{start}[width=+0pt,next state=step,
     persistent precomputation=\pgfdecoratepathhascornerstrue]{}
  \state{step}[auto end on length=1.5\pgfdecorationsegmentlength,
           auto corner on length=1.5\pgfdecorationsegmentlength,               
           width=+\pgfdecorationsegmentlength]
  {
    \pgftransformresetnontranslations
    \pgfpathlineto{
      \pgfpoint{cos(\pgfdecoratedangle)*\pgfdecorationsegmentlength}
         {rand*\pgfdecorationsegmentamplitude}
    }
  }
  \state{final}
  {}
}

示例输出

编写这种类型的装饰器之所以困难,是因为 pgf 希望让大多数类型的装饰器都变得简单,因此会转换坐标系,使其与装饰部分开始处的路径相切。这样,大多数装饰器就变得微不足道了。要获得垂直噪声,必须重置这些转换。装饰的每个部分的宽度(决定了下次调用装饰器的原点)都是根据路径长度来衡量的,因此放置点之间的距离必须考虑旋转角度。

答案3

一个有效但不太优雅的解决方案:

\documentclass[parskip]{scrartcl}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
    \gdef\oldy{-5}  
  \foreach \x in {-4.9,-4.8,...,5}
  { \pgfmathsetmacro{\myfunction}{-0.2*\x*\x}
    \pgfmathsetmacro{\mynoise}{0.3*rand}
    \pgfmathsetmacro{\y}{\myfunction+\mynoise}
    \pgfmathsetmacro{\oldx}{\x-0.1}
    \draw (\oldx,\oldy) -- (\x,\y);
    \xdef\oldy{\y}
  }
\end{tikzpicture}

\end{document}

在此处输入图片描述

这绘制了函数-0.2x²在间隔内-5 至 5,步进0.1。函数的正常值将“随机”为+-0.3\oldy存储下一次迭代的最后一个函数值(因为每次迭代都是一个组,因此之后会忽略更改)。经过一番努力,这也可以变成带有\newcommand参数的。


编辑1:干得好:

\documentclass[parskip]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{backgrounds}

\begin{document}

\newcommand{\mynoisefunction}[7]{% function, min, max, step, noise, xscale, yscale
    \begin{tikzpicture}[show background rectangle, xscale=#6, yscale=#7]%
        \gdef\x{#2} 
        \pgfmathsetmacro{\temp}{#1}
        \gdef\oldy{\temp}%
        \pgfmathsetmacro{\secondstep}{#2+#4}%
        \pgfmathsetmacro{\thirdstep}{#2+2*#4}%
      \foreach \x in {\secondstep,\thirdstep,...,#3}%
      { \pgfmathsetmacro{\myfunction}{#1}%
        \pgfmathsetmacro{\mynoise}{#5*rand}%
        \pgfmathsetmacro{\y}{\myfunction+\mynoise}%
        \pgfmathsetmacro{\oldx}{\x-0.1}%
        \draw (\oldx,\oldy) -- (\x,\y);%
        \xdef\oldy{\y}%
      }%
    \end{tikzpicture}%
}

\mynoisefunction{1.5*sin(\x*180/pi)}{-8}{8}{0.1}{0.25}{1}{1}

\end{document}

自动 sin(x) 示例:

在此处输入图片描述

相关内容