[Tex/LaTex] Bend arrow decorations in Tikz

tikz-arrowstikz-pgftikz-styles

This is a follow-up to my recent question Half arrows in graph using TikZ.

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix,arrows,arrows.meta,bending,decorations.pathreplacing,
                decorations.pathmorphing,decorations.markings,fit,patterns,
                shapes,intersections,calc}

\begin{document}

\tikzset
   {
    down oriented arrow/.style 2 args = {
      thick,
      decoration={
        markings,
        mark=at position 0.01 with
         {
          \coordinate (A) at (0,0);
          \coordinate (B) at (.125,.125);
         },
        mark=at position 0.99 with
         {
          \coordinate (C) at (-.25,.125);
          \coordinate (D) at (-.25,.25);
          \coordinate (E) at (0,0);
          \filldraw[#1,#2]
            (A) -- (B) -- (C) -- (D) -- (E) -- cycle;
         }
       },
      preaction = {decorate},
     },
    down oriented arrow/.default={draw=black}{fill=black!30}
   }
\tikzset
   {
    up oriented arrow/.style 2 args = {
      thick,
      decoration={
        markings,
        mark=at position 0.01 with
         {
          \coordinate (A) at (0,0);
          \coordinate (B) at (.125,-.125);
         },
        mark=at position 0.99 with
         {
          \coordinate (C) at (-.25,-.125);
          \coordinate (D) at (-.25,-.25);
          \coordinate (E) at (0,0);
          \filldraw[#1,#2]
            (A) -- (B) -- (C) -- (D) -- (E) -- cycle;
         }
       },
      preaction = {decorate},
     },
    up oriented arrow/.default={draw=black}{fill=black!30}
   }

\begin{tikzpicture}[align=center,node distance=3cm]
  \node[draw,circle] (a) {};
  \node[draw,circle,right of=a] (b) {};

  \node[draw,circle,below of=a] (c) {};
  \node[draw,circle,right of=c] (d) {};

  \draw[down oriented arrow={draw=green!90}{fill=green!30}] (a) to node [midway,sloped,above = 2pt] {$\vec{e}$} (b);
  \draw[down oriented arrow={draw=blue!90}{fill=blue!30}] (b) to (a);
  \draw[up oriented arrow={draw=orange!90}{fill=orange!30}] (b) to node [midway,sloped,above = 2pt] {$\vec{e}$} (c);
  \draw[up oriented arrow={draw=red!90}{fill=red!30}] (c) to (b);
  \draw[down oriented arrow] (d) to[bend right] (b);
\end{tikzpicture}

\end{document}

enter image description here

What I would like to achieve is that the decorations created by the up oriented arrow and down oriented arrow styles bend with the edge. Is it possible to achieve this?

Best Answer

Here's a Metapost approach, using a macro to do the half-arrow. The arguments to the macro are a path and a colour. The arrow is made by moving segments of the path and then joining them up.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

vardef do_half_arrow(expr p, shade) = 
   save base, shaft, outline, barb; path base, shaft, outline; pair barb;
   base  = subpath(1/10 length p, 9/10 length p) of p;
   shaft = subpath(3/20 length p, 8/10 length p) of p 
           shifted (unitvector(direction 1/2 length p of p rotated 90) scaled 4);
   barb  = unitvector(direction 8/10 length p of p rotated 90) scaled 6 shifted point 8/10 length p of p;
   outline = base -- barb -- reverse shaft -- cycle;
   fill outline withcolor .8[shade, background];
   draw outline withcolor .4[shade, background];

enddef;

beginfig(1);

u = 3cm;

z0 = origin;
z1 = (u,0);
z2 = (u,u);
z3 = (0,u);

do_half_arrow(z3 -- z2, 1/2 green);
do_half_arrow(z2 -- z3, blue);
do_half_arrow(z0 -- z2, red + 1/2 green);
do_half_arrow(z2 -- z0, red);

draw z0--z2;
draw z2--z3;

path arc; arc = z1 {dir 60} .. z2;

do_half_arrow(arc,black);

draw arc;

forsuffixes $ = range 0 thru 3: 
  fill fullcircle scaled .12u shifted z$ withcolor background;
  draw fullcircle scaled .12u shifted z$;
  endfor

picture e;
e = thelabel(btex $\vec{e}$ etex, origin);
draw e shifted 10 up            shifted .5[z3,z2];
draw e shifted 10 up rotated 45 shifted .5[z0,z2];

endfig;
end.

The path can be any arbitrary curve, but it will probably work best with straight or gently curved lines, like this for example:

enter image description here

beginfig(2);
path p; 
p = origin .. (50,15) .. (100,-5) .. (140,10);

do_half_arrow(p, .67 blue);
do_half_arrow(reverse p, .53 red);
drawarrow p;

endfig;