I made a less clumsy version, in which you can use a key factor
to set how off the spring is of the center and, in the process, I ended up making things easy to change the number of coils in the spring, so I added a coils
key to change that as well. The default value for factor
is 0
, so that the behaviour is the same of the original spring
, and the default for coils
is 4
, the same as the original.
Now you can use it with:
\draw (0,0) to [ravenspring={factor=2,coils=4}] (0, 2);
without changing any definition.
The old answer is down below, for reference.
Code:
\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}
Old answer, setting factors manually:
I declared a new shape, ravenspring
(if you want to rename it just change all occurrences of ravespring
to whatever name you prefer):
To change the ratio between each loop of the spring you have to change the <factor>
in:
\advance\pgf@circ@res@other by <factor>\pgf@circ@res@step
so that the sum of the factors is 16
. If you don't get the sum to be 16
, then the spring will be shorter or longer than the gap available. Furthermore, the first and last factors should be halved, otherwise the last half coil of the spring will be too long.
Full code:
\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}
A few variants, changing the unevenness of the spring:
The one above:
<factor>
s:
0.500
1.250
1.500
1.750
2.000
2.250
2.500
2.750
1.500
More distorted:
<factor>
s:
0.250
0.875
1.250
1.625
2.000
2.375
2.750
3.125
1.750
Less distorted:
<factor>
s:
0.750
1.625
1.750
1.875
2.000
2.125
2.250
2.375
1.250
Broken:
<factor>
s:
0.000
0.500
1.000
1.500
2.000
2.500
3.000
3.500
2.000