circuitikz 包提供了一种在机械电路中绘制线性弹簧(具有恒定刚度的弹簧)的简单方法。我想以类似 circuitikz 的方式绘制非线性弹簧(其刚度会随着拉伸而变化),但 circuitikz 没有提供非线性弹簧的符号。我该怎么做?
期望输出
我希望这个符号看起来像一个线圈间距不均匀的弹簧:
最小工作示例
该代码将生成线性弹簧符号。
\documentclass{standalone}
\usepackage{circuitikz}
\begin{document}
\begin{circuitikz}
\draw (0,0) to [spring] (0, 2);
\end{circuitikz}
\end{document}
答案1
我制作了一个不太笨拙的版本,其中您可以使用一个键factor
来设置弹簧与中心的偏离程度,在此过程中,我最终可以轻松更改弹簧中的线圈数量,因此我添加了一个coils
键来更改它。 的默认值为factor
,0
因此行为与原始 相同,的spring
默认值为,与原始 相同。coils
4
现在你可以将它用于:
\draw (0,0) to [ravenspring={factor=2,coils=4}] (0, 2);
不改变任何定义。
旧答案如下,供参考。
代码:
\documentclass{standalone}
\usepackage{circuitikz}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \__raven_factor:nnnn #1 #2 #3 #4
{ \fp_eval:n { #2 + #1*(#3 - (#2))/#4 } }
\cs_new:Npn \__raven_factor_half:nnnn #1 #2 #3 #4
{ \fp_eval:n { 0.5 * ( #2 + #1*(#3 - #2)/#4 ) } }
\cs_set_eq:NN \FullFactor \__raven_factor:nnnn
\cs_set_eq:NN \HalfFactor \__raven_factor_half:nnnn
\cs_set_eq:NN \IntStepVariable \int_step_variable:nnNn
\ExplSyntaxOff
\makeatletter
\ctikzset{bipoles/ravenspring/height/.initial=.5}
\ctikzset{bipoles/ravenspring/width/.initial=.5}
\ctikzset{bipoles/ravenspring/factor/.initial=0}
\ctikzset{bipoles/ravenspring/coils/.initial=4}
\def\pgf@circ@ravenspring@path#1{\pgf@circ@bipole@path{ravenspring}{#1}}
\compattikzset{%
ravenspring/.code = {%
\ctikzset{\circuitikzbasekey,/tikz/to path=\pgf@circ@ravenspring@path}%
\ctikzset{\circuitikzbasekey/bipoles/ravenspring/.cd,#1}
}
}
\pgfcircdeclarebipole{}
{\ctikzvalof{bipoles/ravenspring/height}}
{ravenspring}
{\ctikzvalof{bipoles/ravenspring/height}}
{\ctikzvalof{bipoles/ravenspring/width}}
{%
\pgfsetlinewidth{\pgfkeysvalueof{/tikz/circuitikz/bipoles/thickness}\pgfstartlinewidth}
\pgftransformationadjustments
\edef\raven@coils{\number\numexpr\ctikzvalof{bipoles/ravenspring/coils}*2+1}
\pgfmathsetlength{\pgf@circ@res@step}
{(\ctikzvalof{bipoles/ravenspring/width}*\pgf@circ@Rlen+\pgfhorizontaltransformationadjustment*.5*\pgflinewidth)/(\raven@coils-1)/2}
\pgfpathmoveto{\pgfpoint{\pgf@circ@res@left-\pgfhorizontaltransformationadjustment*0.5*\pgflinewidth}{\pgf@circ@res@zero}}
\pgfsetcornersarced{\pgfpoint{.5\pgf@circ@res@up}{.5\pgf@circ@res@up}}
\pgf@circ@res@other = \pgf@circ@res@left
\edef\raven@factor{\ctikzvalof{bipoles/ravenspring/factor}}
\IntStepVariable {1} {\raven@coils} \raven@coil
{%
\advance\pgf@circ@res@other by
\ifnum
\ifnum\raven@coil=1\space 1\else 0\fi
\ifnum\raven@coil=\raven@coils\space 1\else 0\fi
=0
\expandafter\FullFactor
\else
\expandafter\HalfFactor
\fi
{\raven@coil}{2-\raven@factor}{2+\raven@factor}{\raven@coils}\pgf@circ@res@step
\ifnum \raven@coil=\raven@coils
\let\raven@moveto\pgf@circ@res@zero
\else
\ifodd\raven@coil
\let\raven@moveto\pgf@circ@res@up
\else
\let\raven@moveto\pgf@circ@res@down
\fi
\fi
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\raven@moveto}}
}
\pgfsetbuttcap
\pgfsetbeveljoin
\pgfusepath{stroke}
}
\makeatother
\begin{document}
\begin{circuitikz}
\draw (0,0) to [ravenspring={factor=2,coils=4}] (0, 2);
\end{circuitikz}
\begin{circuitikz}
\draw (0,0) to [ravenspring={factor=3,coils=6}] (0, 2);
\end{circuitikz}
\end{document}
旧答案,手动设置因素:
我声明了一个新形状,ravenspring
(如果您想重命名它,只需将所有出现的更改ravespring
为您喜欢的名称):
要改变弹簧每个环之间的比率,您必须改变<factor>
:
\advance\pgf@circ@res@other by <factor>\pgf@circ@res@step
因此,这些因子的总和为16
。如果总和不等于16
,则弹簧将比可用间隙短或长。此外,第一个和最后一个因子应减半,否则弹簧的最后半圈将太长。
完整代码:
\documentclass{standalone}
\usepackage{circuitikz}
\makeatletter
\ctikzset{bipoles/ravenspring/height/.initial=.5}
\ctikzset{bipoles/ravenspring/width/.initial=.5}
\def\pgf@circ@ravenspring@path#1{\pgf@circ@bipole@path{ravenspring}{#1}}
\compattikzset{ravenspring/.style = {\circuitikzbasekey, /tikz/to path=\pgf@circ@ravenspring@path, l=#1}}
\pgfcircdeclarebipole{}
{\ctikzvalof{bipoles/ravenspring/height}}
{ravenspring}
{\ctikzvalof{bipoles/ravenspring/height}}
{\ctikzvalof{bipoles/ravenspring/width}}
{%
\pgfsetlinewidth{\pgfkeysvalueof{/tikz/circuitikz/bipoles/thickness}\pgfstartlinewidth}
\pgftransformationadjustments
\pgfmathsetlength{\pgf@circ@res@step}
{(\ctikzvalof{bipoles/ravenspring/width}*\pgf@circ@Rlen+\pgfhorizontaltransformationadjustment*.5*\pgflinewidth)/16}
\pgfpathmoveto{\pgfpoint{\pgf@circ@res@left-\pgfhorizontaltransformationadjustment*0.5*\pgflinewidth}{\pgf@circ@res@zero}}
\pgfsetcornersarced{\pgfpoint{.5\pgf@circ@res@up}{.5\pgf@circ@res@up}}
\pgf@circ@res@other = \pgf@circ@res@left
\advance\pgf@circ@res@other by 0.50\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
\advance\pgf@circ@res@other by 1.25\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
\advance\pgf@circ@res@other by 1.50\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
\advance\pgf@circ@res@other by 1.75\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
\advance\pgf@circ@res@other by 2.00\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
\advance\pgf@circ@res@other by 2.25\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
\advance\pgf@circ@res@other by 2.50\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
\advance\pgf@circ@res@other by 2.75\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
\advance\pgf@circ@res@other by 1.50\pgf@circ@res@step
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@zero}}
\pgfsetbuttcap
\pgfsetbeveljoin
\pgfusepath{stroke}
}
\makeatother
\begin{document}
\begin{circuitikz}
\draw (0,0) to [ravenspring] (0, 2);
\end{circuitikz}
\end{document}
一些变体,改变了不均匀春天的:
上面的那个:
<factor>
s:
0.500
1.250
1.500
1.750
2.000
2.250
2.500
2.750
1.500
更加扭曲的是:
<factor>
s:
0.250
0.875
1.250
1.625
2.000
2.375
2.750
3.125
1.750
失真程度较低:
<factor>
s:
0.750
1.625
1.750
1.875
2.000
2.125
2.250
2.375
1.250
破碎的:
<factor>
s:
0.000
0.500
1.000
1.500
2.000
2.500
3.000
3.500
2.000