24

I would like to draw a squiggly line with an arrow somewhere in the middle of it. TikZ has a pathmorphing decoration that draws a squiggly line and a markings decoration to place an arrow tip. So a solution would be to use them together:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations,decorations.pathmorphing,decorations.markings}
\begin{document}

\begin{tikzpicture}
 \draw[
         decoration={snake},
         decorate,
         postaction={decoration={markings,mark=at position 0.6 with {\arrow{>}}},decorate}
     ]
        (0,0) -- (2,0);
\end{tikzpicture}

\end{document}

Unfortunately this does not work and results in

! Dimension too large.
<to be read again> 
                   \relax 
l.11         (0,0) -- (2,0);

I suspect there is an infinite recursion going on somewhere.

Is there a workaround? If not, is there a different simple solution to the problem?

(Note: This is probably related to my previous question “Applying a postaction to every path in TikZ”)

4
  • 3
    I translated this with \tracingall on, and I got a log-file of about 6MB, wow. Does indeed look like an infinite recursion. Oct 22, 2010 at 11:11
  • 3
    Interestingly, this doesn't show up with every pathmorphing decoration. If I replace snake with coil, things are still broken; but if I instead use zigzag, lineto, or bent, your code works. Oct 23, 2010 at 16:20
  • Seems that I'm working with an updated TeX system now that gives me an 8MB log file. But it's still 3.5MB if I comment out the line with "postaction"; with "position 1" (instead of 0.6) it's 6.5MB. TikZ is really quite demanding! Oct 29, 2010 at 7:23
  • Has anybody reported this as a bug?
    – Mitar
    Apr 10, 2011 at 22:21

3 Answers 3

12
+75

The problem is not caused by wrong syntax or a recursion. If you for instance change the position to 1:

postaction={decoration={markings,mark=at position 1 with {\arrow{>}}},decorate}

your file compiles without errors and you get:

alt text

Similar for position 0. This doesn't place the arrow where it's desired but it shows that that way of nesting decorations is ok, though the calculation for TikZ seems to be too hard.

4

Yes the calculation for TikZ seems to be too hard. A possibility but the time for the compilation is very long is to use fp with fixedpointarithmetic

\documentclass{article}
\usepackage{tikz,fp}
\usetikzlibrary{decorations.markings,fixedpointarithmetic}

\usetikzlibrary{decorations,decorations.pathmorphing}
\begin{document}

\begin{tikzpicture}
 \draw[fixed point arithmetic,
         decoration={snake},
         decorate,
         postaction={decoration={markings,mark=at position 0.6 with {\arrow{>}}},decorate}
     ]
        (0,0) -- (2,0);
\end{tikzpicture}

\end{document} 

enter image description here

2
  • pgf-math needs a Lua backend...
    – Caramdir
    Jun 15, 2011 at 16:34
  • yes ! but I think this is indispensable. I hope Mark Wibrow works on this topic Jun 15, 2011 at 16:39
0

Here is a solution to your question with the following defined tikzsetand \addarrow command. To add a middle arrow, you first draw an invisible line using draw[arrowsize=10pt 0.8mm] path; (10pt is the size of the arrow, and 0.8mm, for example, compensate for the amplitude of the wiggly line). Finally, the arrow is added by \addarrow{color}; which draws 10pt arrow with the specified color for the arrow.

\tikzset{
    arrowsize/.style args={#1 #2}{ 
        decoration={
            markings,% switch on markings
            mark=
                at position 0.5
                with
                {
                    \coordinate (exy1) at (#1/-6.0,0pt+#2/2);
                    \coordinate (exy2) at (-0.5*#1,#1/3.0+#2/2);  % 3.0 adjustable 
                    \coordinate (exy3) at (0.5*#1,0pt+#2/2);
                    \coordinate (exy4) at (-0.5*#1,#1/-3.0+#2/2); % 3.0 adjustable 
                },  
        },
        postaction=decorate, opacity=0
    },
    arrowsize/.default= 6pt 0.8mm
}

\newcommand{\addarrow}[1]{
\fill[#1] (exy1) -- (exy2) -- (exy3) -- (exy4) -- cycle;
}

MWE [cfr]

[Not sure if I've understood the idea entirely as intended - Ed.]

\documentclass[border=11pt,tikz]{standalone}
\usetikzlibrary{decorations.markings,decorations.pathmorphing}
\tikzset{
    arrowsize/.style args={#1 #2}{
        decoration={
            markings,% switch on markings
            mark=
                at position 0.5
                with
                {
                    \coordinate (exy1) at (#1/-6.0,0pt+#2/2);
                    \coordinate (exy2) at (-0.5*#1,#1/3.0+#2/2);  % 3.0 adjustable
                    \coordinate (exy3) at (0.5*#1,0pt+#2/2);
                    \coordinate (exy4) at (-0.5*#1,#1/-3.0+#2/2); % 3.0 adjustable
                },
        },
        postaction=decorate,
        opacity=0
    },
    arrowsize/.default= 6pt 0.8mm
}

\newcommand{\addarrow}[1]{
  \fill[#1] (exy1) -- (exy2) -- (exy3) -- (exy4) -- cycle;
}
\begin{document}

\begin{tikzpicture}
  \draw
  [
    preaction={
      decoration={snake},
      decorate,
      opacity=1,
      draw,
    },
    arrowsize=10pt 0.8mm,
  ] (0,0) -- (3,0);
  \addarrow{blue}
\end{tikzpicture}
\end{document}

arrow on snake

1
  • Welcome! Please post complete examples. Occasionally, this really isn't needed, but it generally is. In this case, I'm still not sure whether I've understood your intention after playing around with various combinations of the OP's code and yours. Please see my edit and correct it if necessary.
    – cfr
    May 6, 2017 at 3:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.