这是我最近的问题的后续使用 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 arrow
和down 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}
结果: