# TikZ finishes a morphed path with a straight segment

When, in TikZ, I apply a path morphing decoration (say, "snake") and specify the segment length option, I often finish up with a straight segment at the end of the path, such as

which often is not the desired behavior. It happens in case there is no room for the whole decoration segment at the end of path. If I do not specify the segment length, it's all right, but I want to have some control over the decoration parameters.

Do you know if there is a way to set the segment length softly in such a way that it is modified a bit automatically in order to get rid of these straight segments?

The picture was produced with the following code:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}
\begin{tikzpicture}
\draw[decorate, decoration = {snake, segment length = .4cm}] (0,0) -- (2,0);
\end{tikzpicture}
\end{document}

-
I think it might be easier to modify the decoration so that the last part is just missed off (maybe according to some key which would help with diagnostics). The reason being that there's a lot of computation going on "under the bonnet" for these decorations of dubious accuracy so getting the right segment length is going to involve some horrendous incantations and only work if you're standing on one leg and singing the hedgehog song. –  Loop Space Sep 27 '11 at 10:03
(Forgot to say: so would such a solution be acceptable to you?) –  Loop Space Sep 27 '11 at 10:04
I've done something similar in my answer to Nicer wavy line with TikZ: The modified decoration always draws complete waves right to the end of the decoration, stretching the waves slightly if needed. Is that what you are looking for? –  Jake Sep 27 '11 at 10:19
Dear @AndrewStacey, unfortunately, just dropping the last segment off is not suitable for me (the gaps are not desired). –  Andrey Popov Sep 27 '11 at 11:39

This is a slightly adapted version of my answer to Nicer wavy line with TikZ. This version doesn't insist on drawing a full sine wave, but will be happy with half periods as well (i.e. it can start and end with an upward arch, while the previous version would always start with an upward and end with a downward arch):

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
\begin{document}

\pgfdeclaredecoration{complete sines}{initial}
{
\state{initial}[
width=+0pt,
next state=upsine,
persistent precomputation={\pgfmathsetmacro\matchinglength{
\pgfdecoratedinputsegmentlength / int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength)}
\setlength{\pgfdecorationsegmentlength}{\matchinglength pt}
}] {}
\state{upsine}[width=\pgfdecorationsegmentlength,next state=downsine]{
\pgfpathsine{\pgfpoint{0.25\pgfdecorationsegmentlength}{0.5\pgfdecorationsegmentamplitude}}
\pgfpathcosine{\pgfpoint{0.25\pgfdecorationsegmentlength}{-0.5\pgfdecorationsegmentamplitude}}
}
\state{downsine}[width=\pgfdecorationsegmentlength,next state=upsine]{
\pgfpathsine{\pgfpoint{0.25\pgfdecorationsegmentlength}{-0.5\pgfdecorationsegmentamplitude}}
\pgfpathcosine{\pgfpoint{0.25\pgfdecorationsegmentlength}{0.5\pgfdecorationsegmentamplitude}}
}
\state{final}{}
}

\begin{tikzpicture}[
every path/.style={
decoration={
complete sines,
segment length=1cm,
amplitude=1cm
},
decorate,
thick
}]
\draw (0,0) -- (2,0);
\draw [yshift=-1.2cm] (0,0) -- (2.5,0);
\draw [yshift=-2.4cm] (0,0) -- (3,0);
\draw [yshift=-3.6cm] (0,0) -- (3.5,0);
\end{tikzpicture}
\end{document}

-
Hello @Jake. Many thanks for your answer. I guess it totally suits me. –  Andrey Popov Sep 27 '11 at 11:41
There is some strange error. When I use \draw (0,0) -- (2,0);, it does draw full sine, but only between (0,0) and (1,0)? –  Pygmalion Sep 22 '14 at 7:51