# Nicer wavy line with TikZ

My question is inspired by Feynman Diagrams with tikz.

The photon line (TikZ snake) in the answer does not look like it usually looks on a Feynman diagram: in the "reference" look, which may be obtained using the feynmp package, waves start and finish in the middle of the "wave" (one may check the difference compiling the answer given). Inside the metapost code this is realized in a dumb but effective way: it takes a line and adds "waves" based on the line length. First it computes the (integer) number of waves to put on a line to make length of one as close as possible to some given number, then it computes the length of one wave and finally draws them. The Metapost code is rather short and simple.

Is there a way to fully reproduce this feynmp behaviour in TikZ?

• Can you point out where in the metapost code this calculation is done? I'm having trouble to find it and would appreaciate the help. Dec 1, 2012 at 20:50

Here's a new decoration, complete sines, that does what you describe: It computes the number of full waves that would fit into a given path with a specified wavelength, and then stretches the wavelength so that the path can be completely filled:

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

\pgfdeclaredecoration{complete sines}{initial}
{
\state{initial}[
width=+0pt,
next state=sine,
persistent precomputation={\pgfmathsetmacro\matchinglength{
\pgfdecoratedinputsegmentlength / int(\pgfdecoratedinputsegmentlength/\pgfdecorationsegmentlength)}
\setlength{\pgfdecorationsegmentlength}{\matchinglength pt}
}] {}
\state{sine}[width=\pgfdecorationsegmentlength]{
\pgfpathsine{\pgfpoint{0.25\pgfdecorationsegmentlength}{0.5\pgfdecorationsegmentamplitude}}
\pgfpathcosine{\pgfpoint{0.25\pgfdecorationsegmentlength}{-0.5\pgfdecorationsegmentamplitude}}
\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
}]
\draw (0,0) -- (2,0);
\draw [yshift=-1.2cm] (0,0) -- (2.5,0);
\draw [yshift=-2.4cm] (0,0) -- (3,0);
\end{tikzpicture}
\end{document}


Here's an example of three paths, 2 cm, 2.5 cm and 3 cm in length, with a nominal wavelength of 1 cm. In the first case, there are two full waves with a wavelength of 1 cm, in the second there are two full waves with a wavelength of 1.25 cm, and in the third there are three full waves with a wavelength of 1 cm. If you'd use it in the example you linked to, like this:

gluon/.style={decorate, draw=black,
decoration={complete sines,amplitude=8pt, segment length=11pt}}
}


it would yield this • Thank you very much. I tried to do similar trick, but this decoration declaration was too tricky for me. Aug 14, 2011 at 15:55
• @Jake: How can this be modified for a coil decoration? It would also be great to have the option to start and finish pointing up or down. Jun 21, 2012 at 17:11
• @AndyS: There already is a version of this decoration that ends either pointing up or down: tex.stackexchange.com/a/29645/2552. The coil decoration would take a bit of work, it's probably best to open a new question for that.
– Jake
Jun 21, 2012 at 17:19