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.

I am using tikz to draw Feynman diagrams, and I learned how to draw a curved snake path.

The problem is that in general line segments are present (I'd like to avoid them).

I found a couple of post with could help to solve the problem, but none of them is working properly for me. The post are:

The second method results in the figure below,

Diagram generated with the code below

\documentclass{beamer}


\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,decorations.markings,snakes}
\newif\ifstartcompletesineup
\newif\ifendcompletesineup
\pgfkeys{
    /pgf/decoration/.cd,
    start up/.is if=startcompletesineup,
    start up=true,
    start up/.default=true,
    start down/.style={/pgf/decoration/start up=false},
    end up/.is if=endcompletesineup,
    end up=true,
    end up/.default=true,
    end down/.style={/pgf/decoration/end up=false}
}
\pgfdeclaredecoration{complete sines}{initial}
{
    \state{initial}[
        width=+0pt,
        next state=upsine,
        persistent precomputation={
            \ifstartcompletesineup
                \pgfkeys{/pgf/decoration automaton/next state=upsine}
                \ifendcompletesineup
                    \pgfmathsetmacro\matchinglength{
                        0.5*\pgfdecoratedinputsegmentlength / (ceil(0.5* \pgfdecoratedinputsegmentlength / \pgfdecorationsegmentlength) )
                    }
                \else
                    \pgfmathsetmacro\matchinglength{
                        0.5 * \pgfdecoratedinputsegmentlength / (ceil(0.5 * \pgfdecoratedinputsegmentlength / \pgfdecorationsegmentlength ) - 0.499)
                    }
                \fi
            \else
                \pgfkeys{/pgf/decoration automaton/next state=downsine}
                \ifendcompletesineup
                    \pgfmathsetmacro\matchinglength{
                        0.5* \pgfdecoratedinputsegmentlength / (ceil(0.5 * \pgfdecoratedinputsegmentlength / \pgfdecorationsegmentlength ) - 0.4999)
                    }
                \else
                    \pgfmathsetmacro\matchinglength{
                        0.5 * \pgfdecoratedinputsegmentlength / (ceil(0.5 * \pgfdecoratedinputsegmentlength / \pgfdecorationsegmentlength ) )
                    }
                \fi
            \fi
            \setlength{\pgfdecorationsegmentlength}{\matchinglength pt}
        }] {}
    \state{downsine}[width=\pgfdecorationsegmentlength,next state=upsine]{
        \pgfpathsine{\pgfpoint{0.5\pgfdecorationsegmentlength}{0.5\pgfdecorationsegmentamplitude}}
        \pgfpathcosine{\pgfpoint{0.5\pgfdecorationsegmentlength}{-0.5\pgfdecorationsegmentamplitude}}
    }
    \state{upsine}[width=\pgfdecorationsegmentlength,next state=downsine]{
        \pgfpathsine{\pgfpoint{0.5\pgfdecorationsegmentlength}{-0.5\pgfdecorationsegmentamplitude}}
        \pgfpathcosine{\pgfpoint{0.5\pgfdecorationsegmentlength}{0.5\pgfdecorationsegmentamplitude}}
}
    \state{final}{}
}
\tikzset{
  % style to apply some styles to each segment of a path
  on each segment/.style={
    decorate,
    decoration={
      show path construction,
      moveto code={},
      lineto code={
        \path [#1]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
      },
      curveto code={
        \path [#1] (\tikzinputsegmentfirst)
        .. controls
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
        ..
        (\tikzinputsegmentlast);
      },
      closepath code={
        \path [#1]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
      },
    },
  },
  % style to add an arrow in the middle of a path
  mid arrow/.style={postaction={decorate,decoration={
        markings,
        mark=at position .5 with {\arrow[#1]{stealth}}
      }}},
}

\begin{document}
\begin{frame}
  \frametitle{Field and Mass Renormalization}
\begin{center}
      \begin{tikzpicture}[thick,scale=.6]
        \path [draw=blue,postaction={on each segment={mid arrow=blue}}]
        (-4,0) -- (-2,0) -- (2,0) -- (4,0);
        \draw[draw=blue,decorate, decoration=complete sines] (2,0) arc (0:180:2cm);
      \end{tikzpicture}
    \end{center}
\end{frame}
\end{document}

Any fresh ideas on this respect?

share|improve this question
    
Welcome to TeX.sx! We usually do not include greetings or thanks in the questions. Please visit the faq and meta.tex.stackexchange.com/q/1436/19384 for more information on the site. –  Peter Jansson Jan 2 '13 at 17:52
1  
Ah yes, I'd like to see this solved as well! –  Jake Jan 2 '13 at 18:16

1 Answer 1

up vote 7 down vote accepted

Here's a different approach that does not use a decoration, but rather a to path together with a plot statement that connects two points using a semicircle with a superimposed sine wave.

The number of complete periods to be drawn is specified using the key wave count. Another half period is added to this number so that the wave starts and ends on the outside (I think this looks better than starting on the inside or asymmetrically).

The amplitude of the wave is set using wave amplitude, and the semicircle can be flipped to the opposite side of the path using mirror semicircle=true.

This approach could reasonably easily be adapted to allow for circle sectors different from 180° (I don't know if that's ever needed in Feynman diagrams, though).

\documentclass[border=5mm]{standalone}


\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,calc}

\newif\ifmirrorsemicircle

\tikzset{
    wave amplitude/.initial=0.2cm,
    wave count/.initial=8,
    mirror semicircle/.is if=mirrorsemicircle,
    mirror semicircle=false,
    wavy semicircle/.style={
        to path={
            let \p1 = (\tikztostart),
            \p2 = (\tikztotarget),
            \n1 = {veclen(\y2-\y1,\x2-\x1)},
            \n2 = {atan2(\y2-\y1,\x2-\x1))} in
            plot [
                smooth,
                samples=(\pgfkeysvalueof{/tikz/wave count}+0.5)*8+1, % Calculate the number of samples needed, so the samples are in sync with the wave and fall on the extrema
                domain=0:1,
                shift={($(\p1)!0.5!(\p2)$)}
            ] ({ % Polar coordinates: Angle...
                (\x*180-\n2 + 180 + \ifmirrorsemicircle 1 \else -1 \fi * 90%
            }:{ % ... and radius
                (%
                    \n1/2+\pgfkeysvalueof{/tikz/wave amplitude} * %
                    sin(
                        \x * 360 * (\pgfkeysvalueof{/tikz/wave count} + 0.5%
                    )%
                )%
            })
        } (\tikztotarget)
    }
}

\begin{document}
      \begin{tikzpicture}[thick,scale=.6]
        \draw [blue] (-4,0) -- (-2,0) -- (2,-1) -- (4,-2);
        \draw [red] (-2,0) to [wavy semicircle] (2,-1)
                to [
                    wavy semicircle,
                    wave amplitude=0.1cm,
                    wave count=15,
                    mirror semicircle
                ] (4,-2);
      \end{tikzpicture}
\end{document}
share|improve this answer
1  
Man you totally rule! It is a marvellous solution to the problem. Thank you so much. :-) –  Dox Jan 3 '13 at 12:36

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.