Tikz 中的弯曲箭头装饰

Tikz 中的弯曲箭头装饰

这是我最近的问题的后续使用 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}

在此处输入图片描述

我想要实现的是up oriented arrowdown oriented arrow样式创建的装饰随边缘弯曲。可以实现吗?

答案1

这是一个元帖子方法,使用宏来制作半箭头。宏的参数是路径和颜色。箭头是通过移动路径的各段然后将它们连接起来而制作的。

在此处输入图片描述

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.

路径可以是任意曲线,但直线或平缓弯曲的线条可能效果最佳,例如:

在此处输入图片描述

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;

答案2

我最终想出了一个 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,
      shorten >= 0.2ex,
      shorten <= 0.2ex,
      line cap=round,
      decoration={
        markings,
        mark=at position 1ex with
         {
          \coordinate (T) at (0,0);
         },
        mark=between positions 2ex and -2ex step 1ex with
         {
          \pgfkeysgetvalue{/pgf/decoration/mark info/sequence number}{\j}
          \pgfmathtruncatemacro{\i}{\j-1}
          \coordinate (A\i) at (0,0);
          \coordinate (B\i) at (0,.1);
          \coordinate (C\i) at (0,.15);
         },
        mark=at position -1ex with
         {
          \pgfkeysgetvalue{/pgf/decoration/mark info/sequence number}{\j}
          \pgfmathtruncatemacro{\marks}{\j-2}
          \coordinate (H) at (0,0);
          \filldraw[#1,#2] (H) -- (C\marks)
            foreach \i in {\marks,...,1}
             { -- (B\i) }
            -- (T)
            foreach \i in {1,...,\marks}
             { -- (A\i)}
            -- cycle;
         }
        },
      preaction = {decorate},
     },
    down oriented arrow/.default={draw=black}{fill=black!30}
   }
\tikzset
   {
    up oriented arrow/.style 2 args = {
      thick,
      shorten >= 0.2ex,
      shorten <= 0.2ex,
      line cap=round,
      decoration={
        markings,
        mark=at position 1ex with
         {
          \coordinate (T) at (0,0);
         },
        mark=between positions 2ex and -2ex step 1ex with
         {
          \pgfkeysgetvalue{/pgf/decoration/mark info/sequence number}{\j}
          \pgfmathtruncatemacro{\i}{\j-1}
          \coordinate (A\i) at (0,0);
          \coordinate (B\i) at (0,-.1);
          \coordinate (C\i) at (0,-.15);
         },
        mark=at position -1ex with
         {
          \pgfkeysgetvalue{/pgf/decoration/mark info/sequence number}{\j}
          \pgfmathtruncatemacro{\marks}{\j-2}
          \coordinate (H) at (0,0);
          \filldraw[#1,#2] (H) -- (C\marks)
            foreach \i in {\marks,...,1}
             { -- (B\i) }
            -- (T)
            foreach \i in {1,...,\marks}
             { -- (A\i)}
            -- 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] {\color{green} $\vec{e}$} (b);
  \draw[down oriented arrow={draw=blue!90}{fill=blue!30}] (b) to node [midway, sloped, below = 1pt] {\color{blue} $\vec{f}$} (a);
  \draw[up oriented arrow={draw=orange!90}{fill=orange!30}] (b) to node [midway, sloped, above = 2pt] {\color{orange} $\vec{g}$} (c);
  \draw[up oriented arrow={draw=red!90}{fill=red!30}] (c) to node [midway, sloped, below = 1pt] {\color{red} $\vec{h}$} (b);
  \draw[down oriented arrow] (d) to[bend right] (b);
\end{tikzpicture}

\end{document}

结果: 在此处输入图片描述

相关内容