沿着弯曲路径的定制装饰

沿着弯曲路径的定制装饰

我最开始遇到的问题是路径末端用snake或修饰的直线coil,我想去掉它们。我在这里找到了一个非常好的波浪线解决方案: https://tex.stackexchange.com/a/29645/36900

然而,现在我面临的问题是当我将这种装饰应用于弯曲路径时:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\usetikzlibrary{decorations.markings}

\pgfdeclaredecoration{complete sines}{initial}
{
    \state{initial}[
        width=+0pt,
        next state=sine,
        persistent precomputation={\pgfmathsetmacro\matchinglength{
            \pgfdecoratedinputsegmentlength / round(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength)}
            \setlength{\pgfdecorationsegmentlength}{\matchinglength pt}
        }] {}
    \state{sine}[width=\pgfdecorationsegmentlength]{
        \pgfpathsine{\pgfpoint{0.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
        \pgfpathcosine{\pgfpoint{0.25\pgfdecorationsegmentlength}{-\pgfdecorationsegmentamplitude}}
        \pgfpathsine{\pgfpoint{0.25\pgfdecorationsegmentlength}{-\pgfdecorationsegmentamplitude}}
        \pgfpathcosine{\pgfpoint{0.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
}
    \state{final}{}
}

\begin{document}

\begin{tikzpicture}[line width=1. pt]

        \draw[decorate, decoration={snake}] 
        (3,-3) arc (180:-90:1);
        \draw[line width=0.3pt]
        (3,-3) arc (180:-90:1);

        \draw[decorate,decoration={complete sines}] 
        (4,1) arc (180:-90:1);
        \draw[line width=0.3pt]
        (4,1) arc (180:-90:1);

      \end{tikzpicture}

\end{document}

在此处输入图片描述

我们清楚地看到,这些“装饰段”是如何简单地旋转并放在彼此后面的,由于重复图案的宽度有限,从而导致相对于初始路径的有限位移。

我想知道是否有可能“连续”地装饰一条路径。如果我可以像这样指定初始路径上每​​个点的 xy 位移(x 表示与初始路径相切)

{0.}{\amplitude * sin(2*pi/\wavelength * \x)}

其中\wavelength可以像上面的例子一样在开始时计算,并\x表示沿初始路径的实际位置。

沿 y 坐标叠加振荡也应该可以让我产生线圈。

我想可以定义一个具有宽度段的装饰1pt,但我认为一定有一个更简单的解决方案。

答案1

不确定这是否正是所需的,而且肯定存在速度很慢的风险。但这里采用的方法本质上是沿路径绘制正弦函数。

由于 TeX 的精度较低,路径末端很有可能出现一些不准确/不美观的情况。在有锐角的路径上也会出现一些不美观的情况。

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}

\tikzset{/pgf/decoration/.cd,
    number of sines/.initial=10,
    angle step/.initial=20,
}
\newdimen\tmpdimen
\pgfdeclaredecoration{complete sines}{initial}
{
    \state{initial}[
        width=+0pt,
        next state=move,
        persistent precomputation={
            \pgfmathparse{\pgfkeysvalueof{/pgf/decoration/angle step}}%
            \let\anglestep=\pgfmathresult%
            \let\currentangle=\pgfmathresult%
            \pgfmathsetlengthmacro{\pointsperanglestep}%
                {(\pgfdecoratedremainingdistance/\pgfkeysvalueof{/pgf/decoration/number of sines})/360*\anglestep}%
        }] {}
    \state{move}[width=+\pointsperanglestep, next state=draw]{
        \pgfpathmoveto{\pgfpointorigin}
    }
    \state{draw}[width=+\pointsperanglestep, switch if less than=1.25*\pointsperanglestep to final, % <- bit of a hack
        persistent postcomputation={
        \pgfmathparse{mod(\currentangle+\anglestep, 360)}%
        \let\currentangle=\pgfmathresult%
    }]{%
        \pgfmathsin{+\currentangle}%
        \tmpdimen=\pgfdecorationsegmentamplitude%
        \tmpdimen=\pgfmathresult\tmpdimen%
        \divide\tmpdimen by2\relax%
        \pgfpathlineto{\pgfqpoint{0pt}{\tmpdimen}}%
    }
    \state{final}{
        \ifdim\pgfdecoratedremainingdistance>0pt\relax
            \pgfpathlineto{\pgfpointdecoratedpathlast}
        \fi
   }
}

\begin{document}

\begin{tikzpicture}[
    sines/.style={
        very thick,
        line join=round, 
        draw=black, 
        decorate, 
        decoration={complete sines, number of sines=15, amplitude=5pt}
    }
]

  \draw [red, postaction={sines}] 
      (0,0) .. controls +(-1,1) and +(1,-1) .. (2,2);

  \draw [red, postaction={sines}] 
        (1,3) circle [radius=1];

\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容