Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Hi everybody I was trying to draw a spiral coiled tube

enter image description here

with TikZ decoration library. This is what i got so far:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations}


\pgfdeclaredecoration{example}{initial} {
\state{initial}[width=5mm, next state=mynext] {
%
    \pgfpathmoveto{\pgfpoint{0cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.6cm   }{.5cm   }}{\pgfpoint{0cm   }{0cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.1cm   }}{\pgfpoint{.5cm   }{0cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{1.2cm   }{.5cm   }}{\pgfpoint{.5cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.9cm   }}{\pgfpoint{0cm}{1cm}}
    \pgfpathmoveto{\pgfpoint{.5cm   }{0cm   }}
    } 
\state{mynext}[width=5mm]{
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.1cm   }}{\pgfpoint{.5cm   }{0cm   }}\pgfpathquadraticcurveto{\pgfpoint{1.2cm   }{.5cm   }}{\pgfpoint{.5cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.9cm   }}{\pgfpoint{0cm}{1cm}}
    \pgfpathmoveto{\pgfpoint{.5cm   }{0cm   }}
}
\state{final} {
    \pgfpathlineto{\pgfpointdecoratedpathlast}
    }
}


\begin{document}

\tikz[decoration=example] {
    \draw [decorate]    (0,0) -- (3,0); 
    \draw [blue!20!,decorate] (0,0) to [out=45,in=135] (3,0);
    \draw [red,decorate] (0,-5) to [out=30,in=100] (3,-5);
}
\end{document}

enter image description here

This results in a good one for straight lines, but with some bending there is a gap between the segments. So this is what i expected since i'am not able to hand over two coordinates to the next repetition.

I tried to compute the end point (upper corner) by storing \pgfdecoratedangle and transforming it back to the last segments angel but \pgfdecoratedangle seems to be empty.

So how can i connect those segments properly and/or how could one draw such a tube ?

Update: another approach with an existing decorations:

\documentclass[border=1mm]{standalone}
% based on http://tex.stackexchange.com/questions/31707/how-to-raise-a-generic-curve-problem-with-pgfdeclaredecoration
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{decorations.pathmorphing}

\tikzset{forcedist/.style={decorate, decoration={markings,
mark=between positions 0 and 1 step 0.0999 with {\draw[thick] (0,-#1) to[bend left] (0,#1); }}}}

\begin{document}

 \begin{tikzpicture}
  \draw [double distance = 1cm,thick, double=red, decoration=snake]  (0,0) .. controls++(1,1) and (6,-3).. (7,0);
  % those lines should be wavy
  \draw [forcedist=5mm]  (0,0) .. controls++(1,1) and (6,-3).. (7,0);
  \draw [double distance = 5mm,thick, double=red]  (0,3) --++(8,0);
  \draw [forcedist=2.5mm ]  (0,3)--++(8,0);
  \end{tikzpicture}

\end{document}

So this looks quite encouraging, although i'm not able to make those douled lines wavy so that there is a impression of a thicker spiral. The latter results in enter image description here

share|improve this question
    
\pgfdecoratedangle does indeed not work, strangely enough. Nevertheless you should post the code you tried. I guess you wanted to use the persistent pre/postcomputation options. Another approach would be to do something like this: tex.stackexchange.com/questions/31707/… –  canaaerus Jul 27 '12 at 5:24
    
Howdy thanks for the link this is quite close. But i can't get those double lines to be wavy. When i use persistent precomputation how can i store a point in such a way that i can refer on it after the transformation? –  bloodworks Aug 3 '12 at 9:03
    
@morbusg Ah, I was about the take a shot at this. Now it's even more appealing :-) I'll look into it after my fight with IEEE is over about my article. –  percusse Aug 3 '12 at 12:21
    
Allowing multiple bounties from multiple users at the same time might be an interesting game. –  Who is crazy first Aug 3 '12 at 18:25
1  
This may help. tex.stackexchange.com/a/43605/16062 –  Gustavo Aug 4 '12 at 12:56

3 Answers 3

up vote 4 down vote accepted

Here's a small modification of your original code that remembers the key point on the previous computation (the outer-forward corner). It does this by defining a coordinate node at that point. Since there are a lot of transformations involved, this seemed the simplest method of achieving that end.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/64074/86}
\usepackage{tikz}
\usetikzlibrary{decorations}


\pgfdeclaredecoration{example}{initial} {
\state{initial}[width=5mm, next state=mynext] {
%
    \pgfpathmoveto{\pgfpoint{0cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.6cm   }{.5cm  
}}{\pgfpoint{0cm   }{0cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.1cm  
}}{\pgfpoint{.5cm   }{0cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{1.2cm   }{.5cm  
}}{\pgfpoint{.5cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.9cm  
}}{\pgfpoint{0cm}{1cm}}
    \pgfpathmoveto{\pgfpoint{.5cm   }{0cm   }}
    \pgfcoordinate{coil-tmp}{\pgfpoint{.5cm}{1cm}}
    } 
\state{mynext}[width=5mm]{
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.1cm  
}}{\pgfpoint{.5cm   }{0cm   }}\pgfpathquadraticcurveto{\pgfpoint{1.2cm  
}{.5cm   }}{\pgfpoint{.5cm   }{1cm   }}
    \pgfpathquadraticcurveto{\pgfpoint{.25cm   }{.9cm  
}}{\pgfpointanchor{coil-tmp}{center}}
    \pgfpathmoveto{\pgfpoint{.5cm   }{0cm   }}
    \pgfcoordinate{coil-tmp}{\pgfpoint{.5cm}{1cm}}
}
\state{final} {
    \pgfpathlineto{\pgfpointdecoratedpathlast}
    }
}


\begin{document}

\tikz[decoration=example] {
    \draw [decorate]    (0,0) -- (3,0); 
    \draw [blue!20!,decorate] (0,0) to [out=45,in=135] (3,0);
    \draw [red,decorate] (0,-5) to [out=30,in=100] (3,-5);
}
\end{document}

Result:

Joined-up spiral

share|improve this answer
    
I guess one should amend this with the code from the questions about getting the coil decoration to end at the right place to get rid of the artefact at the end. –  Loop Space Aug 9 '12 at 8:40

Edit: I corrected my answer to avoid the bad practice of modifying a package file, following the suggestion of Paul Gaborit.

I made a few modifications to the code of this answer to get the following result:

enter image description here

enter image description here

\documentclass{article}

\usepackage{tikz}

\usetikzlibrary{decorations.pathmorphing}

\makeatletter

% Decorations based on
% http://tex.stackexchange.com/questions/32297/modify-tikz-coil-decoration/43605#43605

% coilup decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,

\pgfdeclaredecoration{coilup}{coil}
{
  \state{coil}[switch if less than=%
    1.5\pgfdecorationsegmentlength+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
               width=+\pgfdecorationsegmentlength]
  {
    \pgfpathcurveto
    {\pgfpoint@oncoil{0    }{ 0.555}{1}}
    {\pgfpoint@oncoil{0.445}{ 1    }{2}}
    {\pgfpoint@oncoil{1    }{ 1    }{3}}
    \pgfpathmoveto{\pgfpoint@oncoil{1    }{-1    }{9}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{0.445}{-1    }{10}}
    {\pgfpoint@oncoil{0    }{-0.555}{11}}
    {\pgfpoint@oncoil{0    }{ 0    }{12}}
  }
  \state{last}[width=.5\pgfdecorationsegmentlength+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
  {
    \pgfpathcurveto
    {\pgfpoint@oncoil{0    }{ 0.555}{1}}
    {\pgfpoint@oncoil{0.445}{ 1    }{2}}
    {\pgfpoint@oncoil{1    }{ 1    }{3}}
    \pgfpathmoveto{\pgfpoint@oncoil{1    }{ 1    }{3}}
    % Uncomment the following lines to close the last loop
    % \pgfpathcurveto
    % {\pgfpoint@oncoil{1.555}{ 1    }{4}}
    % {\pgfpoint@oncoil{2    }{ 0.555}{5}}
    % {\pgfpoint@oncoil{2    }{ 0    }{6}}
    % \pgfpathcurveto
    % {\pgfpoint@oncoil{2    }{-0.555}{7}}
    % {\pgfpoint@oncoil{1.555}{-1    }{8}}
    % {\pgfpoint@oncoil{0    }{-1    }{9}}      
  }
  \state{final}
  {
  \pgfpathmoveto{\pgfpointdecoratedpathlast}
  }
}

% coildown decoration
%
% Parameters: \pgfdecorationsegmentamplitude, \pgfdecorationsegmentlength,

\pgfdeclaredecoration{coildown}{coil}
{
  \state{coil}[switch if less than=%
    1.5\pgfdecorationsegmentlength+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude to last,
               width=+\pgfdecorationsegmentlength]
  {
    \pgfpathmoveto{\pgfpoint@oncoil{1    }{1    }{3}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{1.555}{ 1    }{4}}
    {\pgfpoint@oncoil{2    }{ 0.555}{5}}
    {\pgfpoint@oncoil{2    }{ 0    }{6}}
    \pgfpathcurveto
    {\pgfpoint@oncoil{2    }{-0.555}{7}}
    {\pgfpoint@oncoil{1.555}{-1    }{8}}
    {\pgfpoint@oncoil{1    }{-1    }{9}}
  }
  \state{last}[width=.5\pgfdecorationsegmentlength+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude+%
    \pgfdecorationsegmentaspect\pgfdecorationsegmentamplitude,next state=final]
  {
  % Comment the next 5 lines when closing the last loop
  \pgfpathmoveto{\pgfpoint@oncoil{1    }{ 1    }{3}}
  \pgfpathcurveto
  {\pgfpoint@oncoil{1.555}{ 1    }{4}}
  {\pgfpoint@oncoil{2    }{ 0.555}{5}}
  {\pgfpoint@oncoil{2    }{ 0    }{6}}
  }
  \state{final}
  {}
}

\def\pgfpoint@oncoil#1#2#3{%
  \pgf@x=#1\pgfdecorationsegmentamplitude%
  \pgf@x=\pgfdecorationsegmentaspect\pgf@x%
  \pgf@y=#2\pgfdecorationsegmentamplitude%
  \pgf@xa=0.083333333333\pgfdecorationsegmentlength%
  \advance\pgf@x by#3\pgf@xa%
}

\makeatother

\begin{document}

\begin{tikzpicture}
   \draw [thin, decorate, decoration={coildown,
     amplitude=3, segment length=1}, color=black]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0); 
   \draw [double distance = 5, thin, double=white, color=white]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0);
   \draw [thin, decorate, decoration={coilup,
     amplitude=3, segment length=1}, color=black]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0); 
\end{tikzpicture}
\begin{tikzpicture}
   \draw [thin, decorate, decoration={coildown,
     amplitude=3, segment length=1}, color=black]
   (0,0) to (2,0);
   \draw [double distance = 5, rounded corners, thin, double=white, color=white] (0,0) to (2,0);
   \draw [thin, decorate, decoration={coilup,
     amplitude=3, segment length=1}, color=black]
   (0,0) to (2,0);
\end{tikzpicture}

\begin{tikzpicture}
   \draw [thin, decorate, decoration={coildown,
     amplitude=3, segment length=1}, color=green!40!yellow]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0); 
   \draw [double distance = 5, thin, double=black!50!green,
   color=black!50!green]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0);
   \draw [thin, decorate, decoration={coilup,
      amplitude=3, segment length=1}, color=green!40!yellow]
   (0,0) .. controls++(1,1) and (1,-1).. (2,0); 
\end{tikzpicture}
\begin{tikzpicture}
   \draw [thin, decorate, decoration={coildown,
     amplitude=3, segment length=1}, color=green!40!yellow]
   (0,0) to (2,0);
   \draw [double distance = 5, rounded corners, thin,
   double=black!50!green, color=black!50!green] (0,0) to (2,0);
   \draw [thin, decorate, decoration={coilup,
     amplitude=3, segment length=1}, color=green!40!yellow]
   (0,0) to (2,0);
\end{tikzpicture}

\end{document}

If you use a white background it looks nice IMHO, but when using a colored background it looks a bit strange. Also, I didn't succeed to make the coil start from the bottom, as it would look nicer that way.

You need to comment/uncomment the parts indicated in the code if you want the las loop to be closed or not.

I hope this helps.

share|improve this answer
    
I know that this answer is almost identical to the one I cited. I decided to post it as maybe the OP can get some idea by seeing the pictures of what can he achieve with this method and decide wether he would like to spend some time perfectig it or not. –  Gustavo Aug 4 '12 at 21:40
    
You also can get a nice effect by only using half of the coil, something like (((((((((, but if the lines are close enough it looks good. –  Gustavo Aug 4 '12 at 21:44
2  
Nice pictures. But never suggest to modify the original files of a package. Create your own TikZ library (as in the answer that you cite) or directly integrate this code in the preamble of a document (via \makeatletter ... \makeatother if necessary). –  Paul Gaborit Aug 5 '12 at 6:53
    
Thanks for the suggestion, I will correct my answer. –  Gustavo Aug 5 '12 at 7:10
    
If you prefix each of your states with \pgfsetcornersarced{\pgfpoint{0mm}{0mm}}, you can use path like [rounded corners=10mm] (0,0) -- (1,1) -- (2,-1) -- (3,0). –  Paul Gaborit Aug 5 '12 at 7:18

A promising alternative:

enter image description here

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-solides3d}
\begin{document}
    \psset{unit=0.75}
    \begin{pspicture}(-3,-3)(3,4)
    \psset[pst-solides3d]{viewpoint=20 10 15,Decran=20,
    lightsrc=20 10 10}
    % Parametric Surfaces
    \defFunction{helix}(u,v)
    {1 .4 v Cos mul sub u Cos mul 2 mul}
    {1 .4 v Cos mul sub u Sin mul 2 mul}
    {.4 v Sin mul u .3 mul add}
    \psSolid[object=surfaceparametree,linewidth=0.5\pslinewidth,
    base=-10 10 0 6.28,fillcolor=yellow!50,incolor=green!50,
    function=helix,
    ngrid=60 0.4]%
\end{pspicture}

\end{document}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.