5

I want to draw a bunch of smooth curves with arrow in the middle. So I have to combine decoration and smooth options. However, both options result in dimension too large error.

If I remove smooth option, it compiles. On the other hand, inappropriate marking position also causes the same error.

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{calc,decorations.markings}

\begin{document}
\begin{tikzpicture}
    \newcommand\arrowcurve[3][]{\addplot[#1,decoration={markings,mark=at position #2 with {\arrow{>}}},postaction={decorate}]   coordinates {#3} }

\begin{axis}[hide x axis, hide y axis]
\foreach \i/\j in {1/1,-1/1,-1/-1,1/-1} {
\foreach \t in {20,35,50,60,70,80} {
    \arrowcurve[smooth]{0.4}{({cos(\t)*2*\i},{sin(\t)*2*\j}) ({cos(\t*3/4+22.5)*\i},{sin(\t*3/4+22.5)*\j}) (0,0)};
}
}
\end{axis}
\end{tikzpicture}
\end{document}
  • Your example is working with smooth cycle, but that isn't the desired output... – Malipivo Apr 9 '14 at 18:20
  • @Malipivo, OK, manually ignore the error works. It's the only choice by now. – Martin Wang Apr 10 '14 at 4:55
5

When you use smooth option every point is connected to each other by Bezier curves with additional control points. At the start and the end, one of these control points become the coordinate itself hence the distance between two points is zero. That makes the decoration library complain for various reasons depending on the decoration type.

You can start the decoration late and finish early via pre length,post length keys.

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\usetikzlibrary{calc,decorations.markings}

\begin{document}
\begin{tikzpicture}
    \newcommand\arrowcurve[3][]{
    \addplot[#1,
             decoration={
                 post length=1mm,
                 pre length=1mm,
                 markings,
                 mark=at position #2 with {\arrow{>}}},
             postaction={decorate}]   coordinates {#3} }

\begin{axis}[hide x axis, hide y axis]
\foreach \i/\j in {1/1,-1/1,-1/-1,1/-1} {
\foreach \t in {20,35,50,60,70,80} {
    \arrowcurve[smooth]{0.4}{({cos(\t)*2*\i},{sin(\t)*2*\j}) ({cos(\t*3/4+22.5)*\i},{sin(\t*3/4+22.5)*\j}) (0,0)};
}
}
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

I think smooth option is abused here. You are wasting a great tool that is meant draw curves in a precise fashion. I would recommend parametrizing your curves.

  • it works, and thank you. I'd like to parametrizing the curves, however, sometimes, using control points is much easier than finding a analytic form. – Martin Wang Apr 10 '14 at 9:47
0

Highly unrecommended way of typesetting

It looks there is a bug in the code. I manually ignored all the errors (holding down the Enter key) and the result looks good. We cannot use \nonstopmode as there is more than 100 errors/points, it would result in having no PDF file. I must say my answer is horrible, I dislike it myself, but it works for now until someone finds a better way.

%! *latex mal-decorations.tex
\documentclass{article}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}
\foreach \i/\j in {1/1,-1/1,-1/-1,1/-1} {
\foreach \t in {20,35,50,60,70,80} {
\draw[
  decoration={markings, mark=at position 0.4 with {\arrow{>}}}, % \node{a};
  postaction={ decorate },
  ] plot [smooth] coordinates {
           ({cos(\t)*2*\i}, {sin(\t)*2*\j}) 
           ({cos(\t*3/4+22.5)*\i}, {sin(\t*3/4+22.5)*\j)}) 
           (0,0)
    } ;
  }
}
\end{tikzpicture}
\end{document}

mwe

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.