我最开始遇到的问题是路径末端用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}