5

I wish to draw a curved arrow whose thickness changes from end to head. Such arrows are commonly used in military maps to denote the moves of forces. Below is an example.

A Military Map

Is it possible to do it in tikz? Thanks!

4
  • 1
    Although typically questions like this will get a lot of comments about "showing what you've tried", in this case, the problem is truly quite difficult with TikZ. Related: Stroke with variable thickness and possibly Is it possible to increase the line's width from its start to its end?
    – Alan Munn
    Oct 24, 2017 at 4:02
  • 1
    OTOH, if you don't think of it as an arrow, but as two curved lines with a straight line at one end and a triangle at the other... Oct 24, 2017 at 4:11
  • @JohnKormylo Yes, that's probably the simplest way to draw them, but still not totally straightforward.
    – Alan Munn
    Oct 24, 2017 at 4:15
  • @AlanMunn - The question is how to parameterize the arrow. End points aren't enough, you need the starting width, ending width and curvature. Oct 24, 2017 at 4:19

1 Answer 1

11

Not amazing, and will quite happily produce horrendous results with extreme curves or parameter values. Currently for single curveto operations only (i.e., paths consisting of a single Bézier curve).

\documentclass[tikz,margin=5]{standalone}
\usetikzlibrary{calc,decorations.pathreplacing,decorations.markings}
\tikzset{big arrow/.style={
  /tikz/big arrow/.cd, #1, /tikz/.cd,
  decoration={show path construction,
  curveto code={%
%
\path [discard, decoration={ markings, 
  mark=at position -\bigarrowlength with {\coordinate (@); }}, decorate] 
  (\tikzinputsegmentfirst) .. controls (\tikzinputsegmentsupporta)
  and (\tikzinputsegmentsupportb) .. (\tikzinputsegmentlast);
\path[big arrow/.cd,#1] 
  let \p1=(\tikzinputsegmentfirst), \p2=(\tikzinputsegmentsupporta),
  \p3=(\tikzinputsegmentsupportb), \p4=(@), \p5=(\tikzinputsegmentlast),
  \n1={atan2(\y2-\y1,\x2-\x1)}, \n2={atan2(\y4-\y3,\x4-\x3)} in
  (\p1) -- ++(\n1+90:\bigarrowstartwidth/2) 
  .. controls ++(\x2-\x1, \y2-\y1) and ++(\x3-\x4, \y3-\y4) .. 
  ($(\p4)+(\n2+90:\bigarrowendwidth/2)$) -- 
  ($(\p4)+(\n2+90:\bigarrowwidth/2)$) -- (\p5) --
  ($(\p4)+(\n2-90:\bigarrowwidth/2)$) -- 
  ($(\p4)+(\n2-90:\bigarrowendwidth/2)$)
  .. controls ++(\x3-\x4, \y3-\y4) and ++(\x2-\x1, \y2-\y1) ..
  ($(\p1)+(\n1-90:\bigarrowstartwidth/2)$) -- cycle;
%
  }}, decorate
},
big arrow/.cd,
  start width/.store in=\bigarrowstartwidth,
  end width/.store in=\bigarrowendwidth,
  length/.store in=\bigarrowlength,
   width/.store in=\bigarrowwidth,
  start width=1cm,
  end width=0.5cm,
  length=0.25cm,
  width=1cm,
  .unknown/.code=%
    {\let\searchname=\pgfkeyscurrentname\pgfkeysalso{/tikz/\searchname=#1}}%
}
\begin{document}
\begin{tikzpicture}
\draw [big arrow={fill=red}] (0,0) to [bend left] (5,5);
\draw [big arrow={fill=green, length=0.5cm}] (0,0) to [bend right] (-3,3);
\draw [big arrow={fill=blue, start width=1.5cm, end width=1cm,
  width=1.5cm, length=0.75cm}] (0,0) to [bend right] (4,0);
\end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

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