16

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

enter image description here

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}
4
  • 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. Sep 27, 2011 at 10:03
  • (Forgot to say: so would such a solution be acceptable to you?) Sep 27, 2011 at 10:04
  • 1
    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, 2011 at 10:19
  • Dear @AndrewStacey, unfortunately, just dropping the last segment off is not suitable for me (the gaps are not desired). Sep 27, 2011 at 11:39

1 Answer 1

11

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}
2
  • Hello @Jake. Many thanks for your answer. I guess it totally suits me. Sep 27, 2011 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, 2014 at 7:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .