3

I'm trying to draw a diagram for an interacting field theory. The diagram essentially just needs to consist of a loop connected to two external lines. The problem is that I need the loop to be made up of a dashed and solid line. So far, I have:

\documentclass{article}
\usepackage{tikz}
\usepackage[compat=1.1.0]{tikz-feynman}

\begin{document}

\feynmandiagram [horizontal=a to b, layered layout] {
  a -- [scalar] b [dot] -- [out=125, in=55, loop, min distance=2cm] b -- c,
};

\end{document}

which yields

enter image description here

I need the right-half of the loop to be dashed. Is this possible?

3 Answers 3

5

You can superimpose another dash pattern over the scalar option (which is equivalent to dashed. You need to adjust the pattern, however, in order to have exactly the left half of the loop drawn:

\documentclass{article}
\usepackage[compat=1.1.0]{tikz-feynman}

\begin{document}

\feynmandiagram [horizontal=a to b, layered layout] {
  a -- [scalar] b [dot] -- [out=125, in=55, loop, min distance=2cm, scalar, postaction={draw, dash pattern=on 1.5cm off 1.5cm}] b -- c,
};

\end{document}

enter image description here


A maybe more elegant approach would be to use decorations to re-draw the first half of the loop path:

\documentclass{article}
\usepackage[compat=1.1.0]{tikz-feynman}

\pgfdeclaremetadecoration{draw first half}{initial}{
    \state{initial}[width={\pgfmetadecoratedpathlength/2}, next state=final]{
        \decoration{curveto}
    }
    \state{final}{}
}

\begin{document}

\feynmandiagram [horizontal=a to b, layered layout] {
  a -- [scalar] b [dot] -- [out=125, in=55, loop, min distance=2cm, scalar, postaction={decorate, draw, decoration={draw first half}}] b -- c,
};

\end{document}

A variation of this approach would be to include the dash pattern in the decoration:

\documentclass{article}
\usepackage[compat=1.1.0]{tikz-feynman}

\pgfdeclaremetadecoration{half dashed}{initial}{
    \state{initial}[width={\pgfmetadecoratedpathlength/2}, next state=final]{
        \decoration{curveto}
        \afterdecoration{
            \pgfusepath{stroke}
        }
    }
    \state{final}{
        \beforedecoration{
            \pgfsetdash{{3pt}{3pt}}{0pt}
        }
        \decoration{curveto}
    }
}

\begin{document}

\feynmandiagram [horizontal=a to b, layered layout] {
  a -- [scalar] b [dot] -- [out=125, in=55, loop, min distance=2cm, decorate, decoration={half dashed}] b -- c,
};

\end{document}

The output of these two code snippets look the same as above.

5
  • That works, thanks!
    – Rossana
    Sep 26, 2022 at 22:08
  • Your first approach could be done in one path with dash pattern=on 1.5cm off 3pt on 3pt off 3pt … on 3pt off 3pt which gets annoying to write. (Though, we could write a macro that helps repeat stuff.) The draw first half decoration is much more simpler. :) Sep 26, 2022 at 23:31
  • @Qrrbrbirlbel I needed to dive into the decoration stuff first. It should actually also be possible to use just a decoration to continue the dash pattern after the fully-drawn part of the path ... Sep 26, 2022 at 23:35
  • 1
    Have you tried a second state with \pgfsetdash{3pt}{3pt}\decoration{curve to}? Could be that you have to imitate the dash pattern with the decoration, though. Sep 26, 2022 at 23:49
  • @Qrrbrbirlbel Yes, this works! However, one needs to add \afterdecoration{ \pgfusepath{stroke} } probably to tell PGF to draw several individual segments. Sep 27, 2022 at 0:08
4
  1. A dirty (?) trick to use \pgfpathcurvebetweentime which I recently used in a different context but I don't want to mess with the to paths that handle the whole out and in stuff.

    \pgfpathcurvebetweentime uses \pgfpathcurveto internally which is why we need to restore it right away again.

    This also draws the path twice, one for the first half and another time for the second half but we need to specify it twice in the code (which is why I defined a key for the loop above a node).

  2. Same as 2. but with its own graphs key that may help remove redundancy.

Code

\documentclass{article}
\usepackage[compat=1.1.0]{tikz-feynman}
\makeatletter
\let\pgfpathcurveto@orig\pgfpathcurveto
\tikzset{
  curve from/.code args={#1 to #2}{%
    \let\pgfpathcurveto@orig\pgfpathcurveto
    \def\pgfpathcurveto{\let\pgfpathcurveto\pgfpathcurveto@orig
      \pgfpathcurvebetweentime{#1}{#2}{\tikz@timer@start}}}}
\makeatother
\begin{document}
\feynmandiagram [horizontal=a to b, layered layout,
  la/.style={out=125, in=55, loop, min distance=2cm}]{
  a -- [scalar] b [dot]
  -- [la, curve from=0 to .5] b
  -- [la, curve from=.5 to 1, scalar] b
  -- c,
};
\feynmandiagram [horizontal=a to b, layered layout,
  la/.style={out=125, in=55, loop, min distance=2cm}][
  /tikz/graphs/halfsies/.style n args={6}{% #1 = start, #2 = target,
    % #3 = common, #4 = "half"way point, #5 = first half, #6 = second half
    parse={#1 -- [#3,curve from=0 to #4, #5] #2;
           #1 -- [#3,curve from=#4 to 1, #6] #2;}}]{
  a -- [scalar] b [dot] -- c,
  {[halfsies=bb{la}{.5}{}{scalar}]};
};
\end{document}

Output

enter image description here

2
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\usepackage[compat=1.1.0]{tikz-feynman}
\begin{document}
\tikzset{
half dashed/.style={
draw=none,
postaction={draw, dashed, decoration={curveto, post=moveto, post length=1/2*\pgfmetadecoratedpathlength}, decorate},
postaction={draw, decoration={curveto, pre=moveto, pre length=1/2*\pgfmetadecoratedpathlength}, decorate},
},
}
\feynmandiagram [horizontal=a to b, layered layout] {
  a -- [scalar] b [dot] -- [out=125, in=55, loop, min distance=2cm, half dashed] b -- c,
};
\end{document}

Line and loop with left side dashed

2
  • Oh, I didn't know this is possible! This is essentially the same I did, but much more elegantly, sice you directly use available option. Great! Sep 27, 2022 at 16:25
  • 1
    Thanks. Your \pgfdeclaremetadecoration with no redraw also has its advantages. -it draws everything in one go. It is not always possible to use a preaction and the path does not always survive for a postaction Sep 27, 2022 at 16:34

You must log in to answer this question.

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