我有一个带有开放(白色)箭头的图形。我绘制的路径可能会与 TikZ 先前绘制的箭头重叠,因此被放置在前景中。我不喜欢这种外观,我希望所有箭头都放置在前景中,这样就不会将路径放置在箭头之上。
这个描述很模糊,但希望通过 MWE 能够理解。
平均能量损失
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat = newest}
\usetikzlibrary{arrows.meta}
\tikzset{%
state/.style = {%
draw, circle, minimum size = 4, inner sep = 0, fill = black
}%
}%
\tikzset{%
dashedarrow/.style = {%
draw, densely dashed, > = {Latex[width = 1.7mm, length = 2.2mm, open, fill = white]}, ->
}%
}%
\begin{document}%
\begin{tikzpicture}%
\node[state] (0) at (0,0) {};
\node[state] (1) at (1,0) {};
\node[state] (2) at (0,1) {};
\path[dashedarrow] (1) edge[bend left = 20] (2);
\path[dashedarrow] (2) edge[bend left = 20] (0);
\end{tikzpicture}%
\end{document}%
MWE 制作
通过简单地改变两行的顺序\path[dashedarrow] ...
我得到了我想要的结果:
但是,当我增加箭头的数量时,不能保证这个解决方案有效:可能不存在每个箭头在前景中的顺序。
有什么方法可以强制将所有箭头绘制在前景上,以致于没有任何东西绘制在它们上面?您可以假设箭头之间的距离不会太近以至于它们可能会接触或重叠。
答案1
使用该markings
库,您可以指示 tikz 在顶层绘制箭头。这需要将符号更改edge
为to
(因为edge
似乎没有添加到路径中,因此无法应用标记)。
\documentclass{standalone}
\usepackage{tikz}
\pgfplotsset{compat = newest}
\usetikzlibrary{arrows.meta, decorations.markings}
\pgfdeclarelayer{arrowlayer}
\pgfsetlayers{main,arrowlayer}
\tikzset{%
state/.style = {%
draw, circle, minimum size = 4, inner sep = 0, fill = black
}%
}%
\tikzset{%
dashedarrow/.style = {%
draw, densely dashed, > = {Latex[width = 1.7mm, length = 2.2mm, open, fill = white]},
decoration={markings, mark=at position 1 with {\begin{pgfonlayer}{arrowlayer}\arrow{>}\end{pgfonlayer}}},
postaction={decorate}
}%
}%
\begin{document}%
\begin{tikzpicture}%
\node[state] (0) at (0,0) {};
\node[state] (1) at (1,0) {};
\node[state] (2) at (0,1) {};
\path[dashedarrow] (1) to[bend left = 20] (2);
\path[dashedarrow] (2) to[bend left = 20] (0);
\end{tikzpicture}%
\end{document}%
答案2
更新
经过一些源代码检查后,我终于搞定了。考虑将这些行添加到您的代码中。
\pgfdeclarelayer{foreground}
\pgfsetlayers{main,foreground}
\makeatletter
\let\pgf@arrow@draw@arrow@old\pgf@arrow@draw@arrow
\def\pgf@arrow@draw@arrow#1#2{
\begin{pgfonlayer}{foreground}
\pgf@arrow@draw@arrow@old{#1}{#2}
\end{pgfonlayer}
}
\makeatother
例子
请注意,虽然箭头相互覆盖,但它们并没有被其他任何东西覆盖。
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\makeatletter
\let\pgf@arrow@draw@arrow@old\pgf@arrow@draw@arrow
\def\pgf@arrow@draw@arrow#1#2{
\begin{pgfonlayer}{foreground}
\pgf@arrow@draw@arrow@old{#1}{#2}
\end{pgfonlayer}
}
\makeatother
\begin{document}
\tikz[scale=10]{
\foreach\i in{1,...,100}{
\draw[->,>={Latex[length=30,open,fill=yellow]}](rnd,rnd)--(rnd,rnd);
}
}
\end{document}
旧答案
以下的想法是,通过设置较大的值,dash phase
可以隐藏路径,只绘制箭头。如果您想重复每个\draw
命令两次:一次用于路径,一次用于箭头,则不需要图层系统。
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\tikzset{%
state/.style = {%
draw, circle, minimum size = 4, inner sep = 0, fill = black
}%
}%
\tikzset{%
dashed only/.style = {
draw, densely dashed
},
arrow only/.style = {%
draw, >={Latex[width = 1.7mm, length = 2.2mm, open, fill = white]}, ->,
dash pattern=on 0 off1000, dash phase=500
}%
}%
\begin{document}
\begin{tikzpicture}[]%
\node[state] (0) at (0,0) {};
\node[state] (1) at (1,0) {};
\node[state] (2) at (0,1) {};
\path[dashed only] (1) to[bend left = 20] (2);
\path[dashed only] (2) to[bend left = 20] (0);
\path[arrow only] (1) to[bend left = 20] (2);
\path[arrow only] (2) to[bend left = 20] (0);
\end{tikzpicture}%
\end{document}%