How to draw a coil such that you can see if it's right or left handed?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
29
down vote

favorite
5












If I draw a coil in tikz I usually do something like this:



documentclass[tikz]standalone
usetikzlibrarydecorations.pathmorphing,patterns

begindocument

begintikzpicture
draw[decoration=aspect=0.3, segment length=3.2mm, amplitude=3mm,coil,decorate,opacity=0.9] (1,0) -- (3,0);
endtikzpicture
enddocument


Which looks like this:



enter image description here



In some cases (for example in eletrodynamics) it might matter if the coil is right or left handed.



How can I modify the code above such that it looks like this:



enter image description here



If you have another, maybe better way to visualize the direction I am interested in it too.










share|improve this question

















  • 1




    The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
    – samcarter
    Sep 6 at 12:43











  • It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
    – John Kormylo
    Sep 6 at 12:52










  • @samcarter I want the line with change and the little gap.
    – Julia
    Sep 6 at 13:27














up vote
29
down vote

favorite
5












If I draw a coil in tikz I usually do something like this:



documentclass[tikz]standalone
usetikzlibrarydecorations.pathmorphing,patterns

begindocument

begintikzpicture
draw[decoration=aspect=0.3, segment length=3.2mm, amplitude=3mm,coil,decorate,opacity=0.9] (1,0) -- (3,0);
endtikzpicture
enddocument


Which looks like this:



enter image description here



In some cases (for example in eletrodynamics) it might matter if the coil is right or left handed.



How can I modify the code above such that it looks like this:



enter image description here



If you have another, maybe better way to visualize the direction I am interested in it too.










share|improve this question

















  • 1




    The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
    – samcarter
    Sep 6 at 12:43











  • It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
    – John Kormylo
    Sep 6 at 12:52










  • @samcarter I want the line with change and the little gap.
    – Julia
    Sep 6 at 13:27












up vote
29
down vote

favorite
5









up vote
29
down vote

favorite
5






5





If I draw a coil in tikz I usually do something like this:



documentclass[tikz]standalone
usetikzlibrarydecorations.pathmorphing,patterns

begindocument

begintikzpicture
draw[decoration=aspect=0.3, segment length=3.2mm, amplitude=3mm,coil,decorate,opacity=0.9] (1,0) -- (3,0);
endtikzpicture
enddocument


Which looks like this:



enter image description here



In some cases (for example in eletrodynamics) it might matter if the coil is right or left handed.



How can I modify the code above such that it looks like this:



enter image description here



If you have another, maybe better way to visualize the direction I am interested in it too.










share|improve this question













If I draw a coil in tikz I usually do something like this:



documentclass[tikz]standalone
usetikzlibrarydecorations.pathmorphing,patterns

begindocument

begintikzpicture
draw[decoration=aspect=0.3, segment length=3.2mm, amplitude=3mm,coil,decorate,opacity=0.9] (1,0) -- (3,0);
endtikzpicture
enddocument


Which looks like this:



enter image description here



In some cases (for example in eletrodynamics) it might matter if the coil is right or left handed.



How can I modify the code above such that it looks like this:



enter image description here



If you have another, maybe better way to visualize the direction I am interested in it too.







tikz-pgf






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 6 at 11:58









Julia

684513




684513







  • 1




    The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
    – samcarter
    Sep 6 at 12:43











  • It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
    – John Kormylo
    Sep 6 at 12:52










  • @samcarter I want the line with change and the little gap.
    – Julia
    Sep 6 at 13:27












  • 1




    The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
    – samcarter
    Sep 6 at 12:43











  • It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
    – John Kormylo
    Sep 6 at 12:52










  • @samcarter I want the line with change and the little gap.
    – Julia
    Sep 6 at 13:27







1




1




The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
– samcarter
Sep 6 at 12:43





The image quality of your second image is not very good. Can you clarify which aspect of it you'd like to replicate in your own image? There seem to be a change in line colour/line width as well as a small gap where the wire overlaps, but it is hard to see clearly in this pixelated image.
– samcarter
Sep 6 at 12:43













It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
– John Kormylo
Sep 6 at 12:52




It only matters in a schematic for transformers. One typically adds a dot toward one end of the coil to indicate polarity.
– John Kormylo
Sep 6 at 12:52












@samcarter I want the line with change and the little gap.
– Julia
Sep 6 at 13:27




@samcarter I want the line with change and the little gap.
– Julia
Sep 6 at 13:27










2 Answers
2






active

oldest

votes

















up vote
45
down vote













The starting point of all this is the code in pgflibrarydecorations.pathmorphing.code.tex. I acknowledge a comment by joojaa that pointed out that the halo was not quite right in the original answers. I also appreciate a comment by Robert Harvey, who encouraged me to clean up. What I did is to modify the coil decoration of the decorations.pathmorphing library. There is still a lot of room for improvement. The keys in the beginning allow you to adjust the color, opacity, width of coil and additional width of the halo, I hope the names I gave to these parameters are self-explanatory.



enter image description here



documentclass[tikz,border=3.14mm]standalone
usetikzlibrarydecorations.pathmorphing
pgfkeys%
/pgf/decoration/.cd,
3d coil color/.store in=TDCoilColor,
3d coil color/.initial=black,
3d coil color=black,
3d coil width/.store in=TDCoilWidth,
3d coil width/.initial=0.4pt,
3d coil width=0.4pt,
3d coil dist/.store in=TDCoilDist,
3d coil dist/.initial=0.6pt,
3d coil dist=0.6pt,
3d coil opacity/.store in=TDCoilOpacity,
3d coil opacity/.initial=1,
3d coil opacity=1


makeatletter % https://tex.stackexchange.com/a/219088/121799
tikzsetget stroke color/.code=%
expandafterglobal% Jump over, now we have global
expandafterlet% Jump over now we have globallet
expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
, % globalletpgf... in expanded form
restore stroke color/.code=pgf@setstrokecolor#1,

defpgfpoint@onthreedcoil#1#2#3%
pgf@x=#1pgfdecorationsegmentamplitude%
pgf@x=pgfdecorationsegmentaspectpgf@x%
pgf@y=#2pgfdecorationsegmentamplitude%
pgf@xa=0.083333333333pgfdecorationsegmentlength%
advancepgf@x by#3pgf@xa%
advancepgf@x by-initialoffset pt%


% coil decoration
%
% Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

pgfdeclaredecoration3d coilinitial

stateinitial[width=0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude,
next state=coil, persistent precomputation=
tikzsetget stroke color
pgfmathsetmacroinitialoffset0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude
]
%
pgfpathmovetopgfpointorigin
pgfsetstrokecolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfsetlinewidth1.5*TDCoilWidth
pgfpathcurveto
pgfpoint@oncoil0 0.5551
pgfpoint@oncoil0.445 1 2
pgfpoint@oncoil1 1 3
pgfusepathstroke
pgfcoordinateTD@coilastpgfpoint@oncoil1 1 3

statecoil[switch if less than=%
1.25pgfdecorationsegmentlength+%
pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
pgfdecorationsegmentaspectpgfdecorationsegmentamplitude to last,
width=+pgfdecorationsegmentlength]
% line in the back
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpointanchorTD@coilastcenter
pgfsetlinewidthTDCoilWidth
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 4
pgfpoint@onthreedcoil2 0.5555
pgfpoint@onthreedcoil2 0 6
pgfpathcurveto
pgfpoint@onthreedcoil2 -0.5557
pgfpoint@onthreedcoil1.555-1 8
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke
%
% white background for front thick part
%
pgfsetstrokeopacity1
pgfsetstrokecolorwhite
pgfsetfillcolorwhite
pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
% draw forward
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
%
% draw the thick foreground path
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfsetlinewidthTDCoilWidth
% forward shifted +
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back shfted -
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill % <- added
pgfcoordinateTD@coilastpgfpoint@onthreedcoil1 1 15

statelast[width=.25pgfdecorationsegmentlength+%
pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
pgfdecorationsegmentaspectpgfdecorationsegmentamplitude,next state=final]

pgfsetstrokecolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfsetlinewidthTDCoilWidth
pgfpathmovetopgfpointanchorTD@coilastcenter
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 4
pgfpoint@onthreedcoil2 0.5555
pgfpoint@onthreedcoil2 0 6

statefinal

pgfpathlinetopgfpointdecoratedpathlast
pgfusepathstroke
tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


makeatother

begindocument
begintikzpicture
draw[decoration=3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
decorate] (0,0) -- (0,3);
draw[decoration=3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil,
decorate] (2,3) -- (2,0);
draw[decoration=3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
decorate] (4,3) to[out=0,in=90] (6,0);
endtikzpicture
enddocument


FUN: The mandatory animation can be made with the same preamble + usepackagetikzmarmots and



begindocument
foreach X [evaluate=X as Y using sin(X)]in 0,10,...,350

begintikzpicture
path[use as bounding box] (-1,-0.2) rectangle (1,4);
draw[decoration=3d coil color=blue,aspect=0.35, segment
length=(1.2+0.7*Y)*1mm, amplitude=3mm,3d coil,
decorate] (0,0) -- (0,2);
beginscope[shift=(-0.9,1+0.5*Y)]
marmot[teeth,whiskers]
endscope
endtikzpicture
enddocument


enter image description here



BONUS: A "complete" version, i.e. an analog of Jake's complete sines with a "closed" option (analogous to the closed zigzags.)



documentclass[tikz,border=3.14mm]standalone
usetikzlibrarydecorations.pathmorphing
makeatletter
newififcoil@closed
pgfkeys%
/pgf/decoration/.cd,
3d coil color/.store in=TDCoilColor,
3d coil color/.initial=black,
3d coil color=black,
3d coil width/.store in=TDCoilWidth,
3d coil width/.initial=0.4pt,
3d coil width=0.4pt,
3d coil dist/.store in=TDCoilDist,
3d coil dist/.initial=0.6pt,
3d coil dist=0.6pt,
3d coil opacity/.store in=TDCoilOpacity,
3d coil opacity/.initial=1,
3d coil opacity=1,
3d coil closed/.code=coil@closedtrue


% https://tex.stackexchange.com/a/219088/121799
tikzsetget stroke color/.code=%
expandafterglobal% Jump over, now we have global
expandafterlet% Jump over now we have globallet
expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
, % globalletpgf... in expanded form
restore stroke color/.code=pgf@setstrokecolor#1,

defpgfpoint@onthreedcoil#1#2#3%
pgf@x=#1pgfdecorationsegmentamplitude%
pgf@x=pgfdecorationsegmentaspectpgf@x%
pgf@y=#2pgfdecorationsegmentamplitude%
pgf@xa=0.083333333333pgfdecorationsegmentlength%
advancepgf@x by#3pgf@xa%
advancepgf@x by-generaloffset pt%


% coil decoration
%
% Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

pgfdeclaredecoration3d complete coilinitial

stateinitial[width=0.5*pgfdecorationsegmentlength,
next state=coil, persistent precomputation=% from https://tex.stackexchange.com/a/25689/121799
pgfmathsetmacromatchinglengthpgfdecoratedinputsegmentlength / int(pgfdecoratedinputsegmentlength/pgfdecorationsegmentlength)
setlengthpgfdecorationsegmentlengthmatchinglength pt
tikzsetget stroke color
pgfmathsetmacrogeneraloffsetpgfdecorationsegmentlength
pgfmathsetmacroinitialoffset1.5*pgfdecorationsegmentlength
pgfmathsetmacroauxoffset2.5*pgfdecorationsegmentlength
]
% line in the back
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfsetlinewidthTDCoilWidth
ifcoil@closed
begingroup
defgeneraloffsetauxoffset
pgfpathmovetopgfpoint@onthreedcoil1 1 15
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 16
pgfpoint@onthreedcoil2 0.55517
pgfpoint@onthreedcoil2 0 18
pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
pgfcoordinateTD@coilfirstpgfpoint@onthreedcoil1 1 15
pgfusepathstroke
pgfsetstrokecolorTDCoilColor
endgroup
fi
begingroup %
defgeneraloffsetinitialoffset
ifcoil@closed
pgfpathmovetopgfpointanchorTD@coilastcenter
else
pgfpathmovetopgfpointorigin
fi
pgfpathcurveto
pgfpoint@onthreedcoil2 -0.5557
pgfpoint@onthreedcoil1.555-1 8
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke
%
% white background for front thick part
%
pgfsetstrokeopacity1
pgfsetstrokecolorwhite
pgfsetfillcolorwhite
pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
% draw forward
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
%
% draw the thick foreground path
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfsetlinewidthTDCoilWidth
% forward shifted +
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back shfted -
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
pgfpathmovetopgfpoint@onthreedcoil1 1 15
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 16
pgfpoint@onthreedcoil2 0.55517
pgfpoint@onthreedcoil2 0 18
pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
pgfusepathstroke
endgroup

statecoil[switch if less than=%
1.9*pgfdecorationsegmentlength to last,
width=+pgfdecorationsegmentlength]
% line in the back
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpointanchorTD@coilastcenter
pgfsetlinewidthTDCoilWidth
pgfpathcurveto
pgfpoint@onthreedcoil2 -0.5557
pgfpoint@onthreedcoil1.555-1 8
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke
%
% white background for front thick part
%
pgfsetstrokeopacity1
pgfsetstrokecolorwhite
pgfsetfillcolorwhite
pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
% draw forward
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
%
% draw the thick foreground path
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfsetlinewidthTDCoilWidth
% forward shifted +
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back shfted -
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
pgfpathmovetopgfpoint@onthreedcoil1 1 15
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 16
pgfpoint@onthreedcoil2 0.55517
pgfpoint@onthreedcoil2 0 18
pgfusepathstroke
pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

statelast[next state=final]
% line in the back
%
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpointanchorTD@coilastcenter
pgfsetlinewidthTDCoilWidth
pgfpathcurveto
pgfpoint@onthreedcoil2 -0.5557
pgfpoint@onthreedcoil1.555-1 8
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke
%
% draw the thick foreground path
%
ifcoil@closed %pgfpointanchorTD@coilfirstcenter
%
% white background for front thick part
%
pgfsetstrokeopacity1
pgfsetstrokecolorwhite
pgfsetfillcolorwhite
pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
% draw forward
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpointanchorTD@coilfirstcenter
% draw the curve back
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfsetlinewidthTDCoilWidth
% forward shifted +
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpointanchorTD@coilfirstcenter
% draw the curve back shifted
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
else
%
% white background for front thick part
%
pgfsetstrokeopacity1
pgfsetstrokecolorwhite
pgfsetfillcolorwhite
pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
% draw forward
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
pgfsetstrokecolorTDCoilColor
pgfsetfillcolorTDCoilColor
pgfsetstrokeopacityTDCoilOpacity
pgfpathmovetopgfpoint@onthreedcoil1 1 3
pgfsetlinewidthTDCoilWidth
% forward shifted +
pgfpathmovetopgfpoint@onthreedcoil1 -1 9
pgfpathcurveto
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil0 -0.55511.25
pgfpoint@onthreedcoil0 0 12.5
pgfpathcurveto
pgfpoint@onthreedcoil0 0.55513.25
pgfpoint@onthreedcoil0.445 1 14.25
pgfpoint@onthreedcoil1 1 15
% draw the curve back shifted
pgfpathcurveto
pgfpoint@onthreedcoil0.445 1 14
pgfpoint@onthreedcoil0 0.55512.75
pgfpoint@onthreedcoil0 0 11.5
pgfpathcurveto
pgfpoint@onthreedcoil0 -0.55510.75
pgfpoint@onthreedcoil0.445-1 10
pgfpoint@onthreedcoil1 -1 9
pgfusepathstroke,fill
fi
pgfpathmovetopgfpoint@onthreedcoil1 1 15
ifcoil@closed %TD@coilfirst
else
pgfpathcurveto
pgfpoint@onthreedcoil1.555 1 16
pgfpoint@onthreedcoil2 0.55517
pgfpoint@onthreedcoil2 0 18
fi
pgfusepathstroke
%pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

statefinal

pgfpathmovetopgfpointdecoratedpathlast
tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


makeatother

begindocument
begintikzpicture
draw[decoration=3d coil color=red,aspect=0.35, segment length=3.1mm,
amplitude=3mm,3d complete coil,
decorate] (0,1) -- (0,6);
draw[decoration=3d coil color=blue,3d coil opacity=0.9,aspect=0.5,
segment length=2*pi*3cm/50, amplitude=5mm,3d complete coil,
3d coil closed,
decorate] (5,3.5) circle (3);
draw[decoration=3d coil color=green!60!black,aspect=0.5, segment length=3.1mm,
amplitude=4mm,3d complete coil,
decorate] (0,-1) -- (0,-6);
draw[decoration=3d coil color=purple,3d coil opacity=0.9,aspect=0.5,
segment length=2*pi*3cm/50, amplitude=3mm,3d complete coil,
3d coil closed,
decorate] (5,-3.5) circle (3);
endtikzpicture
enddocument


enter image description here






share|improve this answer


















  • 3




    The decorations in pgf, it's the most difficult, wonderful work, bravo!
    – AndréC
    Sep 6 at 16:05










  • @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
    – marmot
    Sep 6 at 16:09










  • You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
    – joojaa
    Sep 6 at 16:30











  • @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
    – joojaa
    Sep 6 at 16:40






  • 1




    Another beautiful piece of marmot magic!
    – Max
    Sep 7 at 18:04

















up vote
23
down vote













If you put negative values for aspect and amplitude, you can get the mirrored coil, add this in the @marmot's answer may complete the desired output; also I added an option using markings to get some similar drawing that uses scope and yscale to invert the marking, then a new variable to control the coil color,when the path is straight it has good result, markings path lacks bending good results.



EDIT: Added a control for marking step to improve bending results.



RESULT:



enter image description here



MWE:



documentclass[tikz,border=20pt]standalone
usetikzlibrarydecorations.pathmorphing,decorations.markings

begindocument

begintikzpicture[
CoilColor/.store in=coilcolor,CoilColor=black,
Step/.store in=Step,Step=0.1,
Coil/.style=
double=black,
draw=gray!50,
decoration=
#1,
segment length=3mm,
coil
,
decorate,
,
Coil2/.style=
decorate,
decoration=
markings,
mark= between positions 0 and 1 step Step
with
beginscope[yscale=#1]
draw[xshift=9.2,fill,coilcolor!70!black]
(0,0)++(-135: 0.2 and 0.4)
.. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
.. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
draw[white,line width=2pt]
(0,0)++(90: 0.2 and 0.4)
.. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
draw[fill=coilcolor,coilcolor]
(0,0)++(90: 0.2 and 0.4)
.. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
.. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
endscope



]
draw[Coil=aspect=-0.3,amplitude=-3mm,blue] (0,0) -- ++ (0,-3);
draw[Coil=aspect=0.3,amplitude=3mm,red] (1.5,0) -- ++ (0,-3);
draw[Coil=aspect=0.3,amplitude=3mm,green!50!black] (3,0) arc (90:0:3);
draw[Coil=aspect=-0.3,amplitude=-3mm] (3,1) arc (90:0:4);

draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);

endtikzpicture
enddocument



UPDATE:
Acording to @marmot's suggestion closing the gaps and drawing all the variations, using pgfdecoratedpathlength, /pgf/decoration/mark info/sequence number.



RESULT:
enter image description here



MWE:



documentclass[tikz,border=20pt]standalone
usetikzlibrarydecorations.markings

begindocument

begintikzpicture[
CoilColor/.store in=coilcolor,CoilColor=black,
Step/.store in=Step,Step=0.1,
Width/.store in=Width,Width=0.4,
Coil2/.style=
decorate,
decoration=
markings,
mark= between positions 0 and 1 step Step
with
beginscope[yscale=#1]
pgfmathparseint(pgfdecoratedpathlength/28.45*100*Step)
edefHightpgfmathresult
ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number=1
path (0,0)++(90: Hight/200 and Width) coordinate (b);
fi
ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number>1
coordinate (b) at (d);
fi
path (b) arc (90:-135: Hight/200 and Width) coordinate (a);
path (b) arc (90:-45: Hight/200 and Width) coordinate (c);
path (b)++(Hight/100,0) coordinate (d);
draw[fill,coilcolor!70!black]
(c)
.. controls +(-0.175,0) and +(-0.275,0) .. (d)
.. controls +(-0.325,0) and +(-0.225,0) .. (c);
draw[white,line width=2pt]
(b)
.. controls +(0.3,0) and +(0.2,0) .. (c);
draw[fill,coilcolor]
(b)
.. controls +(0.275,0) and +(0.175,0) .. (c)
.. controls +(0.225,0) and +(0.325,0) .. (b);
endscope



]

draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);

draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
to [in=90,out=0] ++(2.5,-1)
to [in=180,out=-90] ++(2.5,-1)
to [in=-90,out=0] ++(2,1.5)
to [in=-90,out=90] ++(0.5,3) arc (0:90:2);

draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
to [in=90,out=0] ++(1.5,-1)
to [in=180,out=-90] ++(4,-1)
to [in=-90,out=0] ++(3,2.5)
to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);

draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);

endtikzpicture
enddocument





share|improve this answer






















    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',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f449675%2fhow-to-draw-a-coil-such-that-you-can-see-if-its-right-or-left-handed%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    45
    down vote













    The starting point of all this is the code in pgflibrarydecorations.pathmorphing.code.tex. I acknowledge a comment by joojaa that pointed out that the halo was not quite right in the original answers. I also appreciate a comment by Robert Harvey, who encouraged me to clean up. What I did is to modify the coil decoration of the decorations.pathmorphing library. There is still a lot of room for improvement. The keys in the beginning allow you to adjust the color, opacity, width of coil and additional width of the halo, I hope the names I gave to these parameters are self-explanatory.



    enter image description here



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1


    makeatletter % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-initialoffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d coilinitial

    stateinitial[width=0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude,
    next state=coil, persistent precomputation=
    tikzsetget stroke color
    pgfmathsetmacroinitialoffset0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude
    ]
    %
    pgfpathmovetopgfpointorigin
    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidth1.5*TDCoilWidth
    pgfpathcurveto
    pgfpoint@oncoil0 0.5551
    pgfpoint@oncoil0.445 1 2
    pgfpoint@oncoil1 1 3
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@oncoil1 1 3

    statecoil[switch if less than=%
    1.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill % <- added
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil1 1 15

    statelast[width=.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude,next state=final]

    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6

    statefinal

    pgfpathlinetopgfpointdecoratedpathlast
    pgfusepathstroke
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,3);
    draw[decoration=3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (2,3) -- (2,0);
    draw[decoration=3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (4,3) to[out=0,in=90] (6,0);
    endtikzpicture
    enddocument


    FUN: The mandatory animation can be made with the same preamble + usepackagetikzmarmots and



    begindocument
    foreach X [evaluate=X as Y using sin(X)]in 0,10,...,350

    begintikzpicture
    path[use as bounding box] (-1,-0.2) rectangle (1,4);
    draw[decoration=3d coil color=blue,aspect=0.35, segment
    length=(1.2+0.7*Y)*1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,2);
    beginscope[shift=(-0.9,1+0.5*Y)]
    marmot[teeth,whiskers]
    endscope
    endtikzpicture
    enddocument


    enter image description here



    BONUS: A "complete" version, i.e. an analog of Jake's complete sines with a "closed" option (analogous to the closed zigzags.)



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    makeatletter
    newififcoil@closed
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1,
    3d coil closed/.code=coil@closedtrue


    % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-generaloffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d complete coilinitial

    stateinitial[width=0.5*pgfdecorationsegmentlength,
    next state=coil, persistent precomputation=% from https://tex.stackexchange.com/a/25689/121799
    pgfmathsetmacromatchinglengthpgfdecoratedinputsegmentlength / int(pgfdecoratedinputsegmentlength/pgfdecorationsegmentlength)
    setlengthpgfdecorationsegmentlengthmatchinglength pt
    tikzsetget stroke color
    pgfmathsetmacrogeneraloffsetpgfdecorationsegmentlength
    pgfmathsetmacroinitialoffset1.5*pgfdecorationsegmentlength
    pgfmathsetmacroauxoffset2.5*pgfdecorationsegmentlength
    ]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    ifcoil@closed
    begingroup
    defgeneraloffsetauxoffset
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilfirstpgfpoint@onthreedcoil1 1 15
    pgfusepathstroke
    pgfsetstrokecolorTDCoilColor
    endgroup
    fi
    begingroup %
    defgeneraloffsetinitialoffset
    ifcoil@closed
    pgfpathmovetopgfpointanchorTD@coilastcenter
    else
    pgfpathmovetopgfpointorigin
    fi
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    endgroup

    statecoil[switch if less than=%
    1.9*pgfdecorationsegmentlength to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statelast[next state=final]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % draw the thick foreground path
    %
    ifcoil@closed %pgfpointanchorTD@coilfirstcenter
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    else
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    fi
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    ifcoil@closed %TD@coilfirst
    else
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    fi
    pgfusepathstroke
    %pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statefinal

    pgfpathmovetopgfpointdecoratedpathlast
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=red,aspect=0.35, segment length=3.1mm,
    amplitude=3mm,3d complete coil,
    decorate] (0,1) -- (0,6);
    draw[decoration=3d coil color=blue,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=5mm,3d complete coil,
    3d coil closed,
    decorate] (5,3.5) circle (3);
    draw[decoration=3d coil color=green!60!black,aspect=0.5, segment length=3.1mm,
    amplitude=4mm,3d complete coil,
    decorate] (0,-1) -- (0,-6);
    draw[decoration=3d coil color=purple,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=3mm,3d complete coil,
    3d coil closed,
    decorate] (5,-3.5) circle (3);
    endtikzpicture
    enddocument


    enter image description here






    share|improve this answer


















    • 3




      The decorations in pgf, it's the most difficult, wonderful work, bravo!
      – AndréC
      Sep 6 at 16:05










    • @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
      – marmot
      Sep 6 at 16:09










    • You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
      – joojaa
      Sep 6 at 16:30











    • @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
      – joojaa
      Sep 6 at 16:40






    • 1




      Another beautiful piece of marmot magic!
      – Max
      Sep 7 at 18:04














    up vote
    45
    down vote













    The starting point of all this is the code in pgflibrarydecorations.pathmorphing.code.tex. I acknowledge a comment by joojaa that pointed out that the halo was not quite right in the original answers. I also appreciate a comment by Robert Harvey, who encouraged me to clean up. What I did is to modify the coil decoration of the decorations.pathmorphing library. There is still a lot of room for improvement. The keys in the beginning allow you to adjust the color, opacity, width of coil and additional width of the halo, I hope the names I gave to these parameters are self-explanatory.



    enter image description here



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1


    makeatletter % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-initialoffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d coilinitial

    stateinitial[width=0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude,
    next state=coil, persistent precomputation=
    tikzsetget stroke color
    pgfmathsetmacroinitialoffset0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude
    ]
    %
    pgfpathmovetopgfpointorigin
    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidth1.5*TDCoilWidth
    pgfpathcurveto
    pgfpoint@oncoil0 0.5551
    pgfpoint@oncoil0.445 1 2
    pgfpoint@oncoil1 1 3
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@oncoil1 1 3

    statecoil[switch if less than=%
    1.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill % <- added
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil1 1 15

    statelast[width=.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude,next state=final]

    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6

    statefinal

    pgfpathlinetopgfpointdecoratedpathlast
    pgfusepathstroke
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,3);
    draw[decoration=3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (2,3) -- (2,0);
    draw[decoration=3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (4,3) to[out=0,in=90] (6,0);
    endtikzpicture
    enddocument


    FUN: The mandatory animation can be made with the same preamble + usepackagetikzmarmots and



    begindocument
    foreach X [evaluate=X as Y using sin(X)]in 0,10,...,350

    begintikzpicture
    path[use as bounding box] (-1,-0.2) rectangle (1,4);
    draw[decoration=3d coil color=blue,aspect=0.35, segment
    length=(1.2+0.7*Y)*1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,2);
    beginscope[shift=(-0.9,1+0.5*Y)]
    marmot[teeth,whiskers]
    endscope
    endtikzpicture
    enddocument


    enter image description here



    BONUS: A "complete" version, i.e. an analog of Jake's complete sines with a "closed" option (analogous to the closed zigzags.)



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    makeatletter
    newififcoil@closed
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1,
    3d coil closed/.code=coil@closedtrue


    % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-generaloffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d complete coilinitial

    stateinitial[width=0.5*pgfdecorationsegmentlength,
    next state=coil, persistent precomputation=% from https://tex.stackexchange.com/a/25689/121799
    pgfmathsetmacromatchinglengthpgfdecoratedinputsegmentlength / int(pgfdecoratedinputsegmentlength/pgfdecorationsegmentlength)
    setlengthpgfdecorationsegmentlengthmatchinglength pt
    tikzsetget stroke color
    pgfmathsetmacrogeneraloffsetpgfdecorationsegmentlength
    pgfmathsetmacroinitialoffset1.5*pgfdecorationsegmentlength
    pgfmathsetmacroauxoffset2.5*pgfdecorationsegmentlength
    ]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    ifcoil@closed
    begingroup
    defgeneraloffsetauxoffset
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilfirstpgfpoint@onthreedcoil1 1 15
    pgfusepathstroke
    pgfsetstrokecolorTDCoilColor
    endgroup
    fi
    begingroup %
    defgeneraloffsetinitialoffset
    ifcoil@closed
    pgfpathmovetopgfpointanchorTD@coilastcenter
    else
    pgfpathmovetopgfpointorigin
    fi
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    endgroup

    statecoil[switch if less than=%
    1.9*pgfdecorationsegmentlength to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statelast[next state=final]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % draw the thick foreground path
    %
    ifcoil@closed %pgfpointanchorTD@coilfirstcenter
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    else
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    fi
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    ifcoil@closed %TD@coilfirst
    else
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    fi
    pgfusepathstroke
    %pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statefinal

    pgfpathmovetopgfpointdecoratedpathlast
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=red,aspect=0.35, segment length=3.1mm,
    amplitude=3mm,3d complete coil,
    decorate] (0,1) -- (0,6);
    draw[decoration=3d coil color=blue,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=5mm,3d complete coil,
    3d coil closed,
    decorate] (5,3.5) circle (3);
    draw[decoration=3d coil color=green!60!black,aspect=0.5, segment length=3.1mm,
    amplitude=4mm,3d complete coil,
    decorate] (0,-1) -- (0,-6);
    draw[decoration=3d coil color=purple,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=3mm,3d complete coil,
    3d coil closed,
    decorate] (5,-3.5) circle (3);
    endtikzpicture
    enddocument


    enter image description here






    share|improve this answer


















    • 3




      The decorations in pgf, it's the most difficult, wonderful work, bravo!
      – AndréC
      Sep 6 at 16:05










    • @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
      – marmot
      Sep 6 at 16:09










    • You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
      – joojaa
      Sep 6 at 16:30











    • @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
      – joojaa
      Sep 6 at 16:40






    • 1




      Another beautiful piece of marmot magic!
      – Max
      Sep 7 at 18:04












    up vote
    45
    down vote










    up vote
    45
    down vote









    The starting point of all this is the code in pgflibrarydecorations.pathmorphing.code.tex. I acknowledge a comment by joojaa that pointed out that the halo was not quite right in the original answers. I also appreciate a comment by Robert Harvey, who encouraged me to clean up. What I did is to modify the coil decoration of the decorations.pathmorphing library. There is still a lot of room for improvement. The keys in the beginning allow you to adjust the color, opacity, width of coil and additional width of the halo, I hope the names I gave to these parameters are self-explanatory.



    enter image description here



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1


    makeatletter % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-initialoffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d coilinitial

    stateinitial[width=0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude,
    next state=coil, persistent precomputation=
    tikzsetget stroke color
    pgfmathsetmacroinitialoffset0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude
    ]
    %
    pgfpathmovetopgfpointorigin
    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidth1.5*TDCoilWidth
    pgfpathcurveto
    pgfpoint@oncoil0 0.5551
    pgfpoint@oncoil0.445 1 2
    pgfpoint@oncoil1 1 3
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@oncoil1 1 3

    statecoil[switch if less than=%
    1.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill % <- added
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil1 1 15

    statelast[width=.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude,next state=final]

    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6

    statefinal

    pgfpathlinetopgfpointdecoratedpathlast
    pgfusepathstroke
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,3);
    draw[decoration=3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (2,3) -- (2,0);
    draw[decoration=3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (4,3) to[out=0,in=90] (6,0);
    endtikzpicture
    enddocument


    FUN: The mandatory animation can be made with the same preamble + usepackagetikzmarmots and



    begindocument
    foreach X [evaluate=X as Y using sin(X)]in 0,10,...,350

    begintikzpicture
    path[use as bounding box] (-1,-0.2) rectangle (1,4);
    draw[decoration=3d coil color=blue,aspect=0.35, segment
    length=(1.2+0.7*Y)*1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,2);
    beginscope[shift=(-0.9,1+0.5*Y)]
    marmot[teeth,whiskers]
    endscope
    endtikzpicture
    enddocument


    enter image description here



    BONUS: A "complete" version, i.e. an analog of Jake's complete sines with a "closed" option (analogous to the closed zigzags.)



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    makeatletter
    newififcoil@closed
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1,
    3d coil closed/.code=coil@closedtrue


    % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-generaloffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d complete coilinitial

    stateinitial[width=0.5*pgfdecorationsegmentlength,
    next state=coil, persistent precomputation=% from https://tex.stackexchange.com/a/25689/121799
    pgfmathsetmacromatchinglengthpgfdecoratedinputsegmentlength / int(pgfdecoratedinputsegmentlength/pgfdecorationsegmentlength)
    setlengthpgfdecorationsegmentlengthmatchinglength pt
    tikzsetget stroke color
    pgfmathsetmacrogeneraloffsetpgfdecorationsegmentlength
    pgfmathsetmacroinitialoffset1.5*pgfdecorationsegmentlength
    pgfmathsetmacroauxoffset2.5*pgfdecorationsegmentlength
    ]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    ifcoil@closed
    begingroup
    defgeneraloffsetauxoffset
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilfirstpgfpoint@onthreedcoil1 1 15
    pgfusepathstroke
    pgfsetstrokecolorTDCoilColor
    endgroup
    fi
    begingroup %
    defgeneraloffsetinitialoffset
    ifcoil@closed
    pgfpathmovetopgfpointanchorTD@coilastcenter
    else
    pgfpathmovetopgfpointorigin
    fi
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    endgroup

    statecoil[switch if less than=%
    1.9*pgfdecorationsegmentlength to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statelast[next state=final]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % draw the thick foreground path
    %
    ifcoil@closed %pgfpointanchorTD@coilfirstcenter
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    else
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    fi
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    ifcoil@closed %TD@coilfirst
    else
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    fi
    pgfusepathstroke
    %pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statefinal

    pgfpathmovetopgfpointdecoratedpathlast
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=red,aspect=0.35, segment length=3.1mm,
    amplitude=3mm,3d complete coil,
    decorate] (0,1) -- (0,6);
    draw[decoration=3d coil color=blue,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=5mm,3d complete coil,
    3d coil closed,
    decorate] (5,3.5) circle (3);
    draw[decoration=3d coil color=green!60!black,aspect=0.5, segment length=3.1mm,
    amplitude=4mm,3d complete coil,
    decorate] (0,-1) -- (0,-6);
    draw[decoration=3d coil color=purple,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=3mm,3d complete coil,
    3d coil closed,
    decorate] (5,-3.5) circle (3);
    endtikzpicture
    enddocument


    enter image description here






    share|improve this answer














    The starting point of all this is the code in pgflibrarydecorations.pathmorphing.code.tex. I acknowledge a comment by joojaa that pointed out that the halo was not quite right in the original answers. I also appreciate a comment by Robert Harvey, who encouraged me to clean up. What I did is to modify the coil decoration of the decorations.pathmorphing library. There is still a lot of room for improvement. The keys in the beginning allow you to adjust the color, opacity, width of coil and additional width of the halo, I hope the names I gave to these parameters are self-explanatory.



    enter image description here



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1


    makeatletter % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-initialoffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d coilinitial

    stateinitial[width=0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude,
    next state=coil, persistent precomputation=
    tikzsetget stroke color
    pgfmathsetmacroinitialoffset0.25*pgfdecorationsegmentlength+pgfdecorationsegmentaspect*pgfdecorationsegmentamplitude
    ]
    %
    pgfpathmovetopgfpointorigin
    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidth1.5*TDCoilWidth
    pgfpathcurveto
    pgfpoint@oncoil0 0.5551
    pgfpoint@oncoil0.445 1 2
    pgfpoint@oncoil1 1 3
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@oncoil1 1 3

    statecoil[switch if less than=%
    1.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill % <- added
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil1 1 15

    statelast[width=.25pgfdecorationsegmentlength+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude+%
    pgfdecorationsegmentaspectpgfdecorationsegmentamplitude,next state=final]

    pgfsetstrokecolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 4
    pgfpoint@onthreedcoil2 0.5555
    pgfpoint@onthreedcoil2 0 6

    statefinal

    pgfpathlinetopgfpointdecoratedpathlast
    pgfusepathstroke
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=blue,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,3);
    draw[decoration=3d coil color=red,3d coil opacity=0.9,aspect=0.45, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (2,3) -- (2,0);
    draw[decoration=3d coil color=green!60!black,3d coil opacity=0.9,aspect=0.35, segment length=3.1mm, amplitude=3mm,3d coil,
    decorate] (4,3) to[out=0,in=90] (6,0);
    endtikzpicture
    enddocument


    FUN: The mandatory animation can be made with the same preamble + usepackagetikzmarmots and



    begindocument
    foreach X [evaluate=X as Y using sin(X)]in 0,10,...,350

    begintikzpicture
    path[use as bounding box] (-1,-0.2) rectangle (1,4);
    draw[decoration=3d coil color=blue,aspect=0.35, segment
    length=(1.2+0.7*Y)*1mm, amplitude=3mm,3d coil,
    decorate] (0,0) -- (0,2);
    beginscope[shift=(-0.9,1+0.5*Y)]
    marmot[teeth,whiskers]
    endscope
    endtikzpicture
    enddocument


    enter image description here



    BONUS: A "complete" version, i.e. an analog of Jake's complete sines with a "closed" option (analogous to the closed zigzags.)



    documentclass[tikz,border=3.14mm]standalone
    usetikzlibrarydecorations.pathmorphing
    makeatletter
    newififcoil@closed
    pgfkeys%
    /pgf/decoration/.cd,
    3d coil color/.store in=TDCoilColor,
    3d coil color/.initial=black,
    3d coil color=black,
    3d coil width/.store in=TDCoilWidth,
    3d coil width/.initial=0.4pt,
    3d coil width=0.4pt,
    3d coil dist/.store in=TDCoilDist,
    3d coil dist/.initial=0.6pt,
    3d coil dist=0.6pt,
    3d coil opacity/.store in=TDCoilOpacity,
    3d coil opacity/.initial=1,
    3d coil opacity=1,
    3d coil closed/.code=coil@closedtrue


    % https://tex.stackexchange.com/a/219088/121799
    tikzsetget stroke color/.code=%
    expandafterglobal% Jump over, now we have global
    expandafterlet% Jump over now we have globallet
    expandafterpgfsavedstrokecolor% Jump we have globalletpgf...
    csnamestringcolor@pgfstrokecolorendcsname% Finally expand this and put it at the end
    , % globalletpgf... in expanded form
    restore stroke color/.code=pgf@setstrokecolor#1,

    defpgfpoint@onthreedcoil#1#2#3%
    pgf@x=#1pgfdecorationsegmentamplitude%
    pgf@x=pgfdecorationsegmentaspectpgf@x%
    pgf@y=#2pgfdecorationsegmentamplitude%
    pgf@xa=0.083333333333pgfdecorationsegmentlength%
    advancepgf@x by#3pgf@xa%
    advancepgf@x by-generaloffset pt%


    % coil decoration
    %
    % Parameters: pgfdecorationsegmentamplitude, pgfdecorationsegmentlength,

    pgfdeclaredecoration3d complete coilinitial

    stateinitial[width=0.5*pgfdecorationsegmentlength,
    next state=coil, persistent precomputation=% from https://tex.stackexchange.com/a/25689/121799
    pgfmathsetmacromatchinglengthpgfdecoratedinputsegmentlength / int(pgfdecoratedinputsegmentlength/pgfdecorationsegmentlength)
    setlengthpgfdecorationsegmentlengthmatchinglength pt
    tikzsetget stroke color
    pgfmathsetmacrogeneraloffsetpgfdecorationsegmentlength
    pgfmathsetmacroinitialoffset1.5*pgfdecorationsegmentlength
    pgfmathsetmacroauxoffset2.5*pgfdecorationsegmentlength
    ]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfsetlinewidthTDCoilWidth
    ifcoil@closed
    begingroup
    defgeneraloffsetauxoffset
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilfirstpgfpoint@onthreedcoil1 1 15
    pgfusepathstroke
    pgfsetstrokecolorTDCoilColor
    endgroup
    fi
    begingroup %
    defgeneraloffsetinitialoffset
    ifcoil@closed
    pgfpathmovetopgfpointanchorTD@coilastcenter
    else
    pgfpathmovetopgfpointorigin
    fi
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    endgroup

    statecoil[switch if less than=%
    1.9*pgfdecorationsegmentlength to last,
    width=+pgfdecorationsegmentlength]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    %
    % draw the thick foreground path
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shfted -
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    pgfusepathstroke
    pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statelast[next state=final]
    % line in the back
    %
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpointanchorTD@coilastcenter
    pgfsetlinewidthTDCoilWidth
    pgfpathcurveto
    pgfpoint@onthreedcoil2 -0.5557
    pgfpoint@onthreedcoil1.555-1 8
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke
    %
    % draw the thick foreground path
    %
    ifcoil@closed %pgfpointanchorTD@coilfirstcenter
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpointanchorTD@coilfirstcenter
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    else
    %
    % white background for front thick part
    %
    pgfsetstrokeopacity1
    pgfsetstrokecolorwhite
    pgfsetfillcolorwhite
    pgfsetlinewidth1.5*TDCoilWidth+1.5*TDCoilDist
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    % draw forward
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    pgfsetstrokecolorTDCoilColor
    pgfsetfillcolorTDCoilColor
    pgfsetstrokeopacityTDCoilOpacity
    pgfpathmovetopgfpoint@onthreedcoil1 1 3
    pgfsetlinewidthTDCoilWidth
    % forward shifted +
    pgfpathmovetopgfpoint@onthreedcoil1 -1 9
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil0 -0.55511.25
    pgfpoint@onthreedcoil0 0 12.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 0.55513.25
    pgfpoint@onthreedcoil0.445 1 14.25
    pgfpoint@onthreedcoil1 1 15
    % draw the curve back shifted
    pgfpathcurveto
    pgfpoint@onthreedcoil0.445 1 14
    pgfpoint@onthreedcoil0 0.55512.75
    pgfpoint@onthreedcoil0 0 11.5
    pgfpathcurveto
    pgfpoint@onthreedcoil0 -0.55510.75
    pgfpoint@onthreedcoil0.445-1 10
    pgfpoint@onthreedcoil1 -1 9
    pgfusepathstroke,fill
    fi
    pgfpathmovetopgfpoint@onthreedcoil1 1 15
    ifcoil@closed %TD@coilfirst
    else
    pgfpathcurveto
    pgfpoint@onthreedcoil1.555 1 16
    pgfpoint@onthreedcoil2 0.55517
    pgfpoint@onthreedcoil2 0 18
    fi
    pgfusepathstroke
    %pgfcoordinateTD@coilastpgfpoint@onthreedcoil2 0 18

    statefinal

    pgfpathmovetopgfpointdecoratedpathlast
    tikzsetrestore stroke color/.expand once=pgfsavedstrokecolor


    makeatother

    begindocument
    begintikzpicture
    draw[decoration=3d coil color=red,aspect=0.35, segment length=3.1mm,
    amplitude=3mm,3d complete coil,
    decorate] (0,1) -- (0,6);
    draw[decoration=3d coil color=blue,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=5mm,3d complete coil,
    3d coil closed,
    decorate] (5,3.5) circle (3);
    draw[decoration=3d coil color=green!60!black,aspect=0.5, segment length=3.1mm,
    amplitude=4mm,3d complete coil,
    decorate] (0,-1) -- (0,-6);
    draw[decoration=3d coil color=purple,3d coil opacity=0.9,aspect=0.5,
    segment length=2*pi*3cm/50, amplitude=3mm,3d complete coil,
    3d coil closed,
    decorate] (5,-3.5) circle (3);
    endtikzpicture
    enddocument


    enter image description here







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 8 at 16:54

























    answered Sep 6 at 14:07









    marmot

    58.8k463126




    58.8k463126







    • 3




      The decorations in pgf, it's the most difficult, wonderful work, bravo!
      – AndréC
      Sep 6 at 16:05










    • @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
      – marmot
      Sep 6 at 16:09










    • You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
      – joojaa
      Sep 6 at 16:30











    • @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
      – joojaa
      Sep 6 at 16:40






    • 1




      Another beautiful piece of marmot magic!
      – Max
      Sep 7 at 18:04












    • 3




      The decorations in pgf, it's the most difficult, wonderful work, bravo!
      – AndréC
      Sep 6 at 16:05










    • @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
      – marmot
      Sep 6 at 16:09










    • You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
      – joojaa
      Sep 6 at 16:30











    • @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
      – joojaa
      Sep 6 at 16:40






    • 1




      Another beautiful piece of marmot magic!
      – Max
      Sep 7 at 18:04







    3




    3




    The decorations in pgf, it's the most difficult, wonderful work, bravo!
    – AndréC
    Sep 6 at 16:05




    The decorations in pgf, it's the most difficult, wonderful work, bravo!
    – AndréC
    Sep 6 at 16:05












    @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
    – marmot
    Sep 6 at 16:09




    @AndréC Merci, but I am actually not really happy, What I would love to achieve is that it is not necessary to set the color, opacity and so on explicitly. And then there are more downsides. Assume I was able to achieve this, then the decomposition of the path in little segments has further downsides such as the fact that a dashed line will not look nice. So there is a lot of room for improvement...
    – marmot
    Sep 6 at 16:09












    You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
    – joojaa
    Sep 6 at 16:30





    You can draw two lines that overlap when they are thin but then move away from each other on the thicker part so no step function in thickness LIkewise you can draw a white line on that is thicker on the top part so overlap is along path
    – joojaa
    Sep 6 at 16:30













    @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
    – joojaa
    Sep 6 at 16:40




    @marmot its slightly less work. The strokes overlap anyway. So no particular reason to fill stuff except pedantry
    – joojaa
    Sep 6 at 16:40




    1




    1




    Another beautiful piece of marmot magic!
    – Max
    Sep 7 at 18:04




    Another beautiful piece of marmot magic!
    – Max
    Sep 7 at 18:04










    up vote
    23
    down vote













    If you put negative values for aspect and amplitude, you can get the mirrored coil, add this in the @marmot's answer may complete the desired output; also I added an option using markings to get some similar drawing that uses scope and yscale to invert the marking, then a new variable to control the coil color,when the path is straight it has good result, markings path lacks bending good results.



    EDIT: Added a control for marking step to improve bending results.



    RESULT:



    enter image description here



    MWE:



    documentclass[tikz,border=20pt]standalone
    usetikzlibrarydecorations.pathmorphing,decorations.markings

    begindocument

    begintikzpicture[
    CoilColor/.store in=coilcolor,CoilColor=black,
    Step/.store in=Step,Step=0.1,
    Coil/.style=
    double=black,
    draw=gray!50,
    decoration=
    #1,
    segment length=3mm,
    coil
    ,
    decorate,
    ,
    Coil2/.style=
    decorate,
    decoration=
    markings,
    mark= between positions 0 and 1 step Step
    with
    beginscope[yscale=#1]
    draw[xshift=9.2,fill,coilcolor!70!black]
    (0,0)++(-135: 0.2 and 0.4)
    .. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
    .. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
    draw[white,line width=2pt]
    (0,0)++(90: 0.2 and 0.4)
    .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
    draw[fill=coilcolor,coilcolor]
    (0,0)++(90: 0.2 and 0.4)
    .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
    .. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
    endscope



    ]
    draw[Coil=aspect=-0.3,amplitude=-3mm,blue] (0,0) -- ++ (0,-3);
    draw[Coil=aspect=0.3,amplitude=3mm,red] (1.5,0) -- ++ (0,-3);
    draw[Coil=aspect=0.3,amplitude=3mm,green!50!black] (3,0) arc (90:0:3);
    draw[Coil=aspect=-0.3,amplitude=-3mm] (3,1) arc (90:0:4);

    draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
    draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
    draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
    draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);

    endtikzpicture
    enddocument



    UPDATE:
    Acording to @marmot's suggestion closing the gaps and drawing all the variations, using pgfdecoratedpathlength, /pgf/decoration/mark info/sequence number.



    RESULT:
    enter image description here



    MWE:



    documentclass[tikz,border=20pt]standalone
    usetikzlibrarydecorations.markings

    begindocument

    begintikzpicture[
    CoilColor/.store in=coilcolor,CoilColor=black,
    Step/.store in=Step,Step=0.1,
    Width/.store in=Width,Width=0.4,
    Coil2/.style=
    decorate,
    decoration=
    markings,
    mark= between positions 0 and 1 step Step
    with
    beginscope[yscale=#1]
    pgfmathparseint(pgfdecoratedpathlength/28.45*100*Step)
    edefHightpgfmathresult
    ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number=1
    path (0,0)++(90: Hight/200 and Width) coordinate (b);
    fi
    ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number>1
    coordinate (b) at (d);
    fi
    path (b) arc (90:-135: Hight/200 and Width) coordinate (a);
    path (b) arc (90:-45: Hight/200 and Width) coordinate (c);
    path (b)++(Hight/100,0) coordinate (d);
    draw[fill,coilcolor!70!black]
    (c)
    .. controls +(-0.175,0) and +(-0.275,0) .. (d)
    .. controls +(-0.325,0) and +(-0.225,0) .. (c);
    draw[white,line width=2pt]
    (b)
    .. controls +(0.3,0) and +(0.2,0) .. (c);
    draw[fill,coilcolor]
    (b)
    .. controls +(0.275,0) and +(0.175,0) .. (c)
    .. controls +(0.225,0) and +(0.325,0) .. (b);
    endscope



    ]

    draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
    draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);

    draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
    to [in=90,out=0] ++(2.5,-1)
    to [in=180,out=-90] ++(2.5,-1)
    to [in=-90,out=0] ++(2,1.5)
    to [in=-90,out=90] ++(0.5,3) arc (0:90:2);

    draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
    to [in=90,out=0] ++(1.5,-1)
    to [in=180,out=-90] ++(4,-1)
    to [in=-90,out=0] ++(3,2.5)
    to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);

    draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
    draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);

    endtikzpicture
    enddocument





    share|improve this answer


























      up vote
      23
      down vote













      If you put negative values for aspect and amplitude, you can get the mirrored coil, add this in the @marmot's answer may complete the desired output; also I added an option using markings to get some similar drawing that uses scope and yscale to invert the marking, then a new variable to control the coil color,when the path is straight it has good result, markings path lacks bending good results.



      EDIT: Added a control for marking step to improve bending results.



      RESULT:



      enter image description here



      MWE:



      documentclass[tikz,border=20pt]standalone
      usetikzlibrarydecorations.pathmorphing,decorations.markings

      begindocument

      begintikzpicture[
      CoilColor/.store in=coilcolor,CoilColor=black,
      Step/.store in=Step,Step=0.1,
      Coil/.style=
      double=black,
      draw=gray!50,
      decoration=
      #1,
      segment length=3mm,
      coil
      ,
      decorate,
      ,
      Coil2/.style=
      decorate,
      decoration=
      markings,
      mark= between positions 0 and 1 step Step
      with
      beginscope[yscale=#1]
      draw[xshift=9.2,fill,coilcolor!70!black]
      (0,0)++(-135: 0.2 and 0.4)
      .. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
      .. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
      draw[white,line width=2pt]
      (0,0)++(90: 0.2 and 0.4)
      .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
      draw[fill=coilcolor,coilcolor]
      (0,0)++(90: 0.2 and 0.4)
      .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
      .. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
      endscope



      ]
      draw[Coil=aspect=-0.3,amplitude=-3mm,blue] (0,0) -- ++ (0,-3);
      draw[Coil=aspect=0.3,amplitude=3mm,red] (1.5,0) -- ++ (0,-3);
      draw[Coil=aspect=0.3,amplitude=3mm,green!50!black] (3,0) arc (90:0:3);
      draw[Coil=aspect=-0.3,amplitude=-3mm] (3,1) arc (90:0:4);

      draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
      draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
      draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
      draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);

      endtikzpicture
      enddocument



      UPDATE:
      Acording to @marmot's suggestion closing the gaps and drawing all the variations, using pgfdecoratedpathlength, /pgf/decoration/mark info/sequence number.



      RESULT:
      enter image description here



      MWE:



      documentclass[tikz,border=20pt]standalone
      usetikzlibrarydecorations.markings

      begindocument

      begintikzpicture[
      CoilColor/.store in=coilcolor,CoilColor=black,
      Step/.store in=Step,Step=0.1,
      Width/.store in=Width,Width=0.4,
      Coil2/.style=
      decorate,
      decoration=
      markings,
      mark= between positions 0 and 1 step Step
      with
      beginscope[yscale=#1]
      pgfmathparseint(pgfdecoratedpathlength/28.45*100*Step)
      edefHightpgfmathresult
      ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number=1
      path (0,0)++(90: Hight/200 and Width) coordinate (b);
      fi
      ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number>1
      coordinate (b) at (d);
      fi
      path (b) arc (90:-135: Hight/200 and Width) coordinate (a);
      path (b) arc (90:-45: Hight/200 and Width) coordinate (c);
      path (b)++(Hight/100,0) coordinate (d);
      draw[fill,coilcolor!70!black]
      (c)
      .. controls +(-0.175,0) and +(-0.275,0) .. (d)
      .. controls +(-0.325,0) and +(-0.225,0) .. (c);
      draw[white,line width=2pt]
      (b)
      .. controls +(0.3,0) and +(0.2,0) .. (c);
      draw[fill,coilcolor]
      (b)
      .. controls +(0.275,0) and +(0.175,0) .. (c)
      .. controls +(0.225,0) and +(0.325,0) .. (b);
      endscope



      ]

      draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
      draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);

      draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
      to [in=90,out=0] ++(2.5,-1)
      to [in=180,out=-90] ++(2.5,-1)
      to [in=-90,out=0] ++(2,1.5)
      to [in=-90,out=90] ++(0.5,3) arc (0:90:2);

      draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
      to [in=90,out=0] ++(1.5,-1)
      to [in=180,out=-90] ++(4,-1)
      to [in=-90,out=0] ++(3,2.5)
      to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);

      draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
      draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);

      endtikzpicture
      enddocument





      share|improve this answer
























        up vote
        23
        down vote










        up vote
        23
        down vote









        If you put negative values for aspect and amplitude, you can get the mirrored coil, add this in the @marmot's answer may complete the desired output; also I added an option using markings to get some similar drawing that uses scope and yscale to invert the marking, then a new variable to control the coil color,when the path is straight it has good result, markings path lacks bending good results.



        EDIT: Added a control for marking step to improve bending results.



        RESULT:



        enter image description here



        MWE:



        documentclass[tikz,border=20pt]standalone
        usetikzlibrarydecorations.pathmorphing,decorations.markings

        begindocument

        begintikzpicture[
        CoilColor/.store in=coilcolor,CoilColor=black,
        Step/.store in=Step,Step=0.1,
        Coil/.style=
        double=black,
        draw=gray!50,
        decoration=
        #1,
        segment length=3mm,
        coil
        ,
        decorate,
        ,
        Coil2/.style=
        decorate,
        decoration=
        markings,
        mark= between positions 0 and 1 step Step
        with
        beginscope[yscale=#1]
        draw[xshift=9.2,fill,coilcolor!70!black]
        (0,0)++(-135: 0.2 and 0.4)
        .. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
        .. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
        draw[white,line width=2pt]
        (0,0)++(90: 0.2 and 0.4)
        .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
        draw[fill=coilcolor,coilcolor]
        (0,0)++(90: 0.2 and 0.4)
        .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
        .. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
        endscope



        ]
        draw[Coil=aspect=-0.3,amplitude=-3mm,blue] (0,0) -- ++ (0,-3);
        draw[Coil=aspect=0.3,amplitude=3mm,red] (1.5,0) -- ++ (0,-3);
        draw[Coil=aspect=0.3,amplitude=3mm,green!50!black] (3,0) arc (90:0:3);
        draw[Coil=aspect=-0.3,amplitude=-3mm] (3,1) arc (90:0:4);

        draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
        draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
        draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
        draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);

        endtikzpicture
        enddocument



        UPDATE:
        Acording to @marmot's suggestion closing the gaps and drawing all the variations, using pgfdecoratedpathlength, /pgf/decoration/mark info/sequence number.



        RESULT:
        enter image description here



        MWE:



        documentclass[tikz,border=20pt]standalone
        usetikzlibrarydecorations.markings

        begindocument

        begintikzpicture[
        CoilColor/.store in=coilcolor,CoilColor=black,
        Step/.store in=Step,Step=0.1,
        Width/.store in=Width,Width=0.4,
        Coil2/.style=
        decorate,
        decoration=
        markings,
        mark= between positions 0 and 1 step Step
        with
        beginscope[yscale=#1]
        pgfmathparseint(pgfdecoratedpathlength/28.45*100*Step)
        edefHightpgfmathresult
        ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number=1
        path (0,0)++(90: Hight/200 and Width) coordinate (b);
        fi
        ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number>1
        coordinate (b) at (d);
        fi
        path (b) arc (90:-135: Hight/200 and Width) coordinate (a);
        path (b) arc (90:-45: Hight/200 and Width) coordinate (c);
        path (b)++(Hight/100,0) coordinate (d);
        draw[fill,coilcolor!70!black]
        (c)
        .. controls +(-0.175,0) and +(-0.275,0) .. (d)
        .. controls +(-0.325,0) and +(-0.225,0) .. (c);
        draw[white,line width=2pt]
        (b)
        .. controls +(0.3,0) and +(0.2,0) .. (c);
        draw[fill,coilcolor]
        (b)
        .. controls +(0.275,0) and +(0.175,0) .. (c)
        .. controls +(0.225,0) and +(0.325,0) .. (b);
        endscope



        ]

        draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
        draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);

        draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
        to [in=90,out=0] ++(2.5,-1)
        to [in=180,out=-90] ++(2.5,-1)
        to [in=-90,out=0] ++(2,1.5)
        to [in=-90,out=90] ++(0.5,3) arc (0:90:2);

        draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
        to [in=90,out=0] ++(1.5,-1)
        to [in=180,out=-90] ++(4,-1)
        to [in=-90,out=0] ++(3,2.5)
        to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);

        draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
        draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);

        endtikzpicture
        enddocument





        share|improve this answer














        If you put negative values for aspect and amplitude, you can get the mirrored coil, add this in the @marmot's answer may complete the desired output; also I added an option using markings to get some similar drawing that uses scope and yscale to invert the marking, then a new variable to control the coil color,when the path is straight it has good result, markings path lacks bending good results.



        EDIT: Added a control for marking step to improve bending results.



        RESULT:



        enter image description here



        MWE:



        documentclass[tikz,border=20pt]standalone
        usetikzlibrarydecorations.pathmorphing,decorations.markings

        begindocument

        begintikzpicture[
        CoilColor/.store in=coilcolor,CoilColor=black,
        Step/.store in=Step,Step=0.1,
        Coil/.style=
        double=black,
        draw=gray!50,
        decoration=
        #1,
        segment length=3mm,
        coil
        ,
        decorate,
        ,
        Coil2/.style=
        decorate,
        decoration=
        markings,
        mark= between positions 0 and 1 step Step
        with
        beginscope[yscale=#1]
        draw[xshift=9.2,fill,coilcolor!70!black]
        (0,0)++(-135: 0.2 and 0.4)
        .. controls +(-0.2,0) and +(-0.3,0) .. (90: 0.2 and 0.4)
        .. controls +(-0.33,0) and +(-0.23,0) .. (-135: 0.2 and 0.4);
        draw[white,line width=2pt]
        (0,0)++(90: 0.2 and 0.4)
        .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4);
        draw[fill=coilcolor,coilcolor]
        (0,0)++(90: 0.2 and 0.4)
        .. controls +(0.3,0) and +(0.2,0) .. (-45: 0.2 and 0.4)
        .. controls +(0.25,0) and +(0.35,0) .. (90: 0.2 and 0.4);
        endscope



        ]
        draw[Coil=aspect=-0.3,amplitude=-3mm,blue] (0,0) -- ++ (0,-3);
        draw[Coil=aspect=0.3,amplitude=3mm,red] (1.5,0) -- ++ (0,-3);
        draw[Coil=aspect=0.3,amplitude=3mm,green!50!black] (3,0) arc (90:0:3);
        draw[Coil=aspect=-0.3,amplitude=-3mm] (3,1) arc (90:0:4);

        draw[Coil2=-1,CoilColor=blue] (0,-4) -- ++ (0,-3);
        draw[Coil2=1,CoilColor=red] (1.5,-4) -- ++ (0,-3);
        draw[Coil2=-1,CoilColor=green!50!black,Step=0.065] (3,-4) arc (90:0:3);
        draw[Coil2=1,Step=0.048] (3,-3) arc (90:0:4);

        endtikzpicture
        enddocument



        UPDATE:
        Acording to @marmot's suggestion closing the gaps and drawing all the variations, using pgfdecoratedpathlength, /pgf/decoration/mark info/sequence number.



        RESULT:
        enter image description here



        MWE:



        documentclass[tikz,border=20pt]standalone
        usetikzlibrarydecorations.markings

        begindocument

        begintikzpicture[
        CoilColor/.store in=coilcolor,CoilColor=black,
        Step/.store in=Step,Step=0.1,
        Width/.store in=Width,Width=0.4,
        Coil2/.style=
        decorate,
        decoration=
        markings,
        mark= between positions 0 and 1 step Step
        with
        beginscope[yscale=#1]
        pgfmathparseint(pgfdecoratedpathlength/28.45*100*Step)
        edefHightpgfmathresult
        ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number=1
        path (0,0)++(90: Hight/200 and Width) coordinate (b);
        fi
        ifnumpgfkeysvalueof/pgf/decoration/mark info/sequence number>1
        coordinate (b) at (d);
        fi
        path (b) arc (90:-135: Hight/200 and Width) coordinate (a);
        path (b) arc (90:-45: Hight/200 and Width) coordinate (c);
        path (b)++(Hight/100,0) coordinate (d);
        draw[fill,coilcolor!70!black]
        (c)
        .. controls +(-0.175,0) and +(-0.275,0) .. (d)
        .. controls +(-0.325,0) and +(-0.225,0) .. (c);
        draw[white,line width=2pt]
        (b)
        .. controls +(0.3,0) and +(0.2,0) .. (c);
        draw[fill,coilcolor]
        (b)
        .. controls +(0.275,0) and +(0.175,0) .. (c)
        .. controls +(0.225,0) and +(0.325,0) .. (b);
        endscope



        ]

        draw[Coil2=-1,CoilColor=red,Step=0.15] (0.5,0) -- ++ (0,-3);
        draw[Coil2=1.5,CoilColor=magenta] (1.5,0) -- ++ (0,-3);

        draw[Coil2=1,CoilColor=green!70!black,Step=0.02] (0,-4)
        to [in=90,out=0] ++(2.5,-1)
        to [in=180,out=-90] ++(2.5,-1)
        to [in=-90,out=0] ++(2,1.5)
        to [in=-90,out=90] ++(0.5,3) arc (0:90:2);

        draw[Coil2=-1,CoilColor=green!50!cyan,Step=0.02] (0,-5)
        to [in=90,out=0] ++(1.5,-1)
        to [in=180,out=-90] ++(4,-1)
        to [in=-90,out=0] ++(3,2.5)
        to [in=-90,out=90] ++(0.5,4.5) arc (0:90:2);

        draw[Coil2=1,CoilColor=cyan!30!blue,Step=0.05] (5.7,-2) arc (360:0:1.5);
        draw[Coil2=-1,CoilColor=cyan!70!blue,Step=0.05] (6.5,-2) arc (360:0:1.5);

        endtikzpicture
        enddocument






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Sep 7 at 4:09

























        answered Sep 6 at 17:53









        J Leon V.

        6,775528




        6,775528



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f449675%2fhow-to-draw-a-coil-such-that-you-can-see-if-its-right-or-left-handed%23new-answer', 'question_page');

            );

            Post as a guest













































































            這個網誌中的熱門文章

            How to combine Bézier curves to a surface?

            Carbon dioxide

            Why am i infinitely getting the same tweet with the Twitter Search API?