How can I draw a nonlinear spring in the style of Circuitikz for a mechanical schematic?
The circuitikz package provides an easy way to draw linear springs (springs that have constant stiffness) in a mechanical circuit. I would like to draw a nonlinear spring (its stiffness varies as it stretches) in a circuitikz-like manner, but circuitikz does not provide a symbol for a nonlinear spring. How can I do this?
Desired output
I would like the symbol to look like a spring with unevenly spaced coils:
Minimal working example
This code will generate a linear spring symbol.
documentclass{standalone}
usepackage{circuitikz}
begin{document}
begin{circuitikz}
draw (0,0) to [spring] (0, 2);
end{circuitikz}
end{document}
tikz-pgf circuitikz
add a comment |
The circuitikz package provides an easy way to draw linear springs (springs that have constant stiffness) in a mechanical circuit. I would like to draw a nonlinear spring (its stiffness varies as it stretches) in a circuitikz-like manner, but circuitikz does not provide a symbol for a nonlinear spring. How can I do this?
Desired output
I would like the symbol to look like a spring with unevenly spaced coils:
Minimal working example
This code will generate a linear spring symbol.
documentclass{standalone}
usepackage{circuitikz}
begin{document}
begin{circuitikz}
draw (0,0) to [spring] (0, 2);
end{circuitikz}
end{document}
tikz-pgf circuitikz
add a comment |
The circuitikz package provides an easy way to draw linear springs (springs that have constant stiffness) in a mechanical circuit. I would like to draw a nonlinear spring (its stiffness varies as it stretches) in a circuitikz-like manner, but circuitikz does not provide a symbol for a nonlinear spring. How can I do this?
Desired output
I would like the symbol to look like a spring with unevenly spaced coils:
Minimal working example
This code will generate a linear spring symbol.
documentclass{standalone}
usepackage{circuitikz}
begin{document}
begin{circuitikz}
draw (0,0) to [spring] (0, 2);
end{circuitikz}
end{document}
tikz-pgf circuitikz
The circuitikz package provides an easy way to draw linear springs (springs that have constant stiffness) in a mechanical circuit. I would like to draw a nonlinear spring (its stiffness varies as it stretches) in a circuitikz-like manner, but circuitikz does not provide a symbol for a nonlinear spring. How can I do this?
Desired output
I would like the symbol to look like a spring with unevenly spaced coils:
Minimal working example
This code will generate a linear spring symbol.
documentclass{standalone}
usepackage{circuitikz}
begin{document}
begin{circuitikz}
draw (0,0) to [spring] (0, 2);
end{circuitikz}
end{document}
tikz-pgf circuitikz
tikz-pgf circuitikz
asked Jan 31 at 18:37
RobotRavenRobotRaven
1668
1668
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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}
defpgf@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
edefraven@coils{numbernumexprctikzvalof{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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
edefraven@factor{ctikzvalof{bipoles/ravenspring/factor}}
IntStepVariable {1} {raven@coils} raven@coil
{%
advancepgf@circ@res@other by
ifnum
ifnumraven@coil=1space 1else 0fi
ifnumraven@coil=raven@coilsspace 1else 0fi
=0
expandafterFullFactor
else
expandafterHalfFactor
fi
{raven@coil}{2-raven@factor}{2+raven@factor}{raven@coils}pgf@circ@res@step
ifnum raven@coil=raven@coils
letraven@movetopgf@circ@res@zero
else
ifoddraven@coil
letraven@movetopgf@circ@res@up
else
letraven@movetopgf@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:
advancepgf@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}
defpgf@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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
advancepgf@circ@res@other by 0.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.00pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@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
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f472773%2fhow-can-i-draw-a-nonlinear-spring-in-the-style-of-circuitikz-for-a-mechanical-sc%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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}
defpgf@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
edefraven@coils{numbernumexprctikzvalof{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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
edefraven@factor{ctikzvalof{bipoles/ravenspring/factor}}
IntStepVariable {1} {raven@coils} raven@coil
{%
advancepgf@circ@res@other by
ifnum
ifnumraven@coil=1space 1else 0fi
ifnumraven@coil=raven@coilsspace 1else 0fi
=0
expandafterFullFactor
else
expandafterHalfFactor
fi
{raven@coil}{2-raven@factor}{2+raven@factor}{raven@coils}pgf@circ@res@step
ifnum raven@coil=raven@coils
letraven@movetopgf@circ@res@zero
else
ifoddraven@coil
letraven@movetopgf@circ@res@up
else
letraven@movetopgf@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:
advancepgf@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}
defpgf@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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
advancepgf@circ@res@other by 0.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.00pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@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
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
add a comment |
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}
defpgf@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
edefraven@coils{numbernumexprctikzvalof{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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
edefraven@factor{ctikzvalof{bipoles/ravenspring/factor}}
IntStepVariable {1} {raven@coils} raven@coil
{%
advancepgf@circ@res@other by
ifnum
ifnumraven@coil=1space 1else 0fi
ifnumraven@coil=raven@coilsspace 1else 0fi
=0
expandafterFullFactor
else
expandafterHalfFactor
fi
{raven@coil}{2-raven@factor}{2+raven@factor}{raven@coils}pgf@circ@res@step
ifnum raven@coil=raven@coils
letraven@movetopgf@circ@res@zero
else
ifoddraven@coil
letraven@movetopgf@circ@res@up
else
letraven@movetopgf@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:
advancepgf@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}
defpgf@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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
advancepgf@circ@res@other by 0.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.00pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@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
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
add a comment |
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}
defpgf@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
edefraven@coils{numbernumexprctikzvalof{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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
edefraven@factor{ctikzvalof{bipoles/ravenspring/factor}}
IntStepVariable {1} {raven@coils} raven@coil
{%
advancepgf@circ@res@other by
ifnum
ifnumraven@coil=1space 1else 0fi
ifnumraven@coil=raven@coilsspace 1else 0fi
=0
expandafterFullFactor
else
expandafterHalfFactor
fi
{raven@coil}{2-raven@factor}{2+raven@factor}{raven@coils}pgf@circ@res@step
ifnum raven@coil=raven@coils
letraven@movetopgf@circ@res@zero
else
ifoddraven@coil
letraven@movetopgf@circ@res@up
else
letraven@movetopgf@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:
advancepgf@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}
defpgf@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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
advancepgf@circ@res@other by 0.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.00pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@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
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}
defpgf@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
edefraven@coils{numbernumexprctikzvalof{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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
edefraven@factor{ctikzvalof{bipoles/ravenspring/factor}}
IntStepVariable {1} {raven@coils} raven@coil
{%
advancepgf@circ@res@other by
ifnum
ifnumraven@coil=1space 1else 0fi
ifnumraven@coil=raven@coilsspace 1else 0fi
=0
expandafterFullFactor
else
expandafterHalfFactor
fi
{raven@coil}{2-raven@factor}{2+raven@factor}{raven@coils}pgf@circ@res@step
ifnum raven@coil=raven@coils
letraven@movetopgf@circ@res@zero
else
ifoddraven@coil
letraven@movetopgf@circ@res@up
else
letraven@movetopgf@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:
advancepgf@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}
defpgf@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{.5pgf@circ@res@up}{.5pgf@circ@res@up}}
pgf@circ@res@other = pgf@circ@res@left
advancepgf@circ@res@other by 0.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 1.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.00pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.25pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 2.50pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@up}}
advancepgf@circ@res@other by 2.75pgf@circ@res@step
pgfpathlineto{pgfpoint{pgf@circ@res@other}{pgf@circ@res@down}}
advancepgf@circ@res@other by 1.50pgf@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
edited Feb 1 at 12:20
answered Jan 31 at 18:59
Phelype OleinikPhelype Oleinik
22.7k54482
22.7k54482
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
add a comment |
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
2
2
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
Impressive positively. My true compliments.
– Sebastiano
Jan 31 at 22:02
add a comment |
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f472773%2fhow-can-i-draw-a-nonlinear-spring-in-the-style-of-circuitikz-for-a-mechanical-sc%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown