我想用 TikZcoil
装饰画一个春天,但如果不手动进行微调,我就无法将其置于路径的中心。
例子:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\begin{document}
\begin{tikzpicture}
\draw
[%
thick,
decoration=
{%
coil,
amplitude=0.5cm,
aspect=0.7,
pre length=0.5cm,
post length=0.5cm,
segment length=1cm,
},%
decorate,
]
(0,0) -- (5cm, 0);
\end{tikzpicture}
\end{document}
弹簧不对称,左右两侧的长度不一样。
有没有办法自动计算pre length
或post length
参数segment length
以获得对称弹簧?
答案1
你可以这样做:
编辑:为了补偿纵横比小于 0.5 时的舍入误差,请更改
amplitude=(0.5*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect)
为amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\newcounter{Nocoils}
\setcounter{Nocoils}{3}
\newlength{\lengthspr}
\setlength{\lengthspr}{5cm}
\newlength{\preandpostlens}
\setlength{\preandpostlens}{0.3cm}
\tikzset{
/pgf/decoration/pre length=\preandpostlens,
/pgf/decoration/post length=\preandpostlens
}
\begin{document}
\begin{tikzpicture}
\setlength{\lengthspr}{5.21cm}
\setcounter{Nocoils}{5}
\draw
[%
thick,
decoration=
{%
coil,
aspect=0.7,
segment length=(\lengthspr-2*\pgfkeysvalueof{/pgf/decoration/pre length})/(\value{Nocoils}),
amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),
},%
decorate,
]
(0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\begin{tikzpicture}
\setlength{\lengthspr}{4cm}
\setlength{\preandpostlens}{0.72cm}
\setcounter{Nocoils}{4}
\draw
[%
thick,
decoration=
{%
coil,
aspect=0.27,
segment length=(\lengthspr-2*\preandpostlens)/(\value{Nocoils}),
amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),
},%
decorate,
]
(0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\end{document}
编辑:我建议另一种方法,即对每个弹簧使用相同的段长度,然后计算相应的线圈数,前长度和后长度取决于弹簧的总长度。也许这更可能是你想要的:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\newlength{\lengthspr}
\setlength{\lengthspr}{5cm}
\newlength{\seglens}
\setlength{\seglens}{0.5cm}
\newcounter{Nocoils}
\setcounter{Nocoils}{\fpeval{floor(\lengthspr/\seglens,0)}}
\newlength{\preandpostlens}
\setlength{\preandpostlens}{\fpeval{(\lengthspr-(\value{Nocoils}*\seglens))/2cm}cm}
\tikzset{
/pgf/decoration/pre length=\preandpostlens,
/pgf/decoration/post length=\preandpostlens
}
\begin{document}
\begin{tikzpicture}
\setlength{\lengthspr}{3.31cm}
\draw
[%
thick,
decoration=
{%
coil,
aspect=0.33,
segment length=\seglens,
amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),
},%
decorate,
]
(0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\begin{tikzpicture}
\setlength{\lengthspr}{5.21cm}
\setcounter{Nocoils}{\fpeval{floor(\lengthspr/\seglens,0)}}
\setlength{\preandpostlens}{\fpeval{(\lengthspr-(\value{Nocoils}*\seglens))/2cm}cm}
\draw
[%
thick,
decoration=
{%
coil,
aspect=0.33,
segment length=\seglens,
amplitude=(0.49*\pgfdecorationsegmentlength)/ (2*\pgfdecorationsegmentaspect),
},%
decorate,
]
(0,0) -- (\lengthspr, 0);
\end{tikzpicture}
\end{document}
答案2
在@Tom 的回答的帮助下,我进一步研究了一下。装饰的定义coil
在文件中给出pgflibrarydecorations.pathmorphing.code.tex
,并以
\pgfdeclaredecoration{coil}{coil}
{%
\state{coil}[switch if less than=%
1.5\pgfdecorationsegmentlength+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
width=+\pgfdecorationsegmentlength]
...
好的图案长度也是如此\pgfdecorationsegmentlength
,但困难在于最后的部分coil
较长,至少需要0.5\pgfdecorationsegmentlength + 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
。
换句话说,如果
L
是路径的全长,p
等于pre length
且post length
,s
是个segment length
,a
是个amplitude
,x
是个aspect
,n
是线圈数,那么
L = p + n⋅s + 0.5⋅s + 2⋅x⋅a + p
使用TikZ:根据路径长度计算“预长度”,我可以使用 获得完整路径长度\pgfmetadecoratedpathlength
,但如果我尝试设置 ,它不起作用amplitude
。所以我决定改为使用以下pre length
方法设置:
pre length=
(
\pgfkeysvalueof{/pgf/decoration/min prepost length}
+ 0.5*
(
\pgfmetadecoratedpathlength
- 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
- 0.5\pgfdecorationsegmentlength
- \pgfdecorationsegmentlength*floor
(
(
\pgfmetadecoratedpathlength
- 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
- 0.5\pgfdecorationsegmentlength
)
/\pgfdecorationsegmentlength
)
)
)
(mod
函数本来可以使这个表达式更清晰,但我得到了有关扩展的错误)。这里有一个专用键,用于确保和的/pgf/decoration/min prepost length
最小值。请注意,从数学上讲,第一个与取消,但为了清楚起见,我保留了它们。pre length
post length
\pgfkeysvalueof{/pgf/decoration/min prepost length}
0.5*(- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude)
我现在得到了一个几乎所有时间都能正常工作的计算(除了当aspect
为负数时,如果aspect*amplitude
大于segment length
,但对我来说已经足够了)。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\tikzset{%
,/pgf/decoration/min prepost length/.initial=2mm
,coil spring/.style={%
,thick
,smooth
,decorate
,decoration={
,coil
,aspect=0.5
,segment length=2mm
,amplitude=2mm
,pre length=
(
\pgfkeysvalueof{/pgf/decoration/min prepost length}
+ 0.5*
(
\pgfmetadecoratedpathlength
- 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
- 0.5\pgfdecorationsegmentlength
- \pgfdecorationsegmentlength*floor
(
(
\pgfmetadecoratedpathlength
- 2*\pgfkeysvalueof{/pgf/decoration/min prepost length}
- 2*\pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude
- 0.5\pgfdecorationsegmentlength
)
/\pgfdecorationsegmentlength
)
)
)
,post length=\pgfkeysvalueof{/pgf/decoration/min prepost length}
}
}
}
\begin{document}
\begin{tikzpicture}
\draw[gray, very thin, step=2mm] (0,-1) grid (5,4);
\draw (0,-1) grid (5,4);
\draw
[%
,coil spring, ultra thick
]
(0,3) -- +(5cm, 0);
\draw
[%
,coil spring, ultra thick
,decoration={aspect=0.5, amplitude=0.5cm, segment length=1cm}
]
(0,2) -- +(4.5cm, 0);
\draw
[%
,coil spring, ultra thick
,decoration={aspect=0.3, amplitude=0.5cm, segment length=1cm}
]
(0,1) -- +(5cm, 0);
\draw
[%
,coil spring, ultra thick
,decoration={aspect=-0.2, amplitude=0.5cm, min prepost length=1cm}
]
(0,0) -- +(5cm, 0);
\end{tikzpicture}
\end{document}