![复杂图表中的箭头交叉](https://linux22.com/image/397763/%E5%A4%8D%E6%9D%82%E5%9B%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E7%AE%AD%E5%A4%B4%E4%BA%A4%E5%8F%89.png)
我使用 tikzpicture 绘制了一个图表,但其中的箭头相互交叉。如何保持每个级别的水平箭头完整并在交叉点处断开其他箭头?
这是我的代码:
%\documentclass[reqno]{amsart}
\documentclass[border=5mm]{standalone}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm,amsxtra}
\usepackage{cite}
\usepackage{enumerate}
\usepackage[mathscr]{eucal}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{tikz-cd}
\usepackage{tkz-graph}
\usepackage{tkz-berge}
\usetikzlibrary{positioning,arrows,shapes.geometric,trees,matrix}
\usepackage{graphicx}
\usepackage{mathtools}
\usetikzlibrary{positioning}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{caption}
\begin{document}
\begin{tikzpicture}
\matrix (m) [matrix of math nodes, row sep=1.6cm,
column sep=0.4cm]{
&&Level(1,3)&&&&\\
&Level(2,2)&Level(2,3)&& Level(2,5)&&Level(2,7)\\
&&Level(3,3)&& Level(3,5)&&Level(3,7)\\
Level(4,1)&Level(4,2)&& Level(4,4)&&Level(4,6)& \\
&Level(5,2)&& Level(5,4)&&Level(5,6)& \\
Level(6,1)&& Level(6,3)&& Level(6,5)&&\\
Level(7,1) && Level(7,3)&& Level(7,5)&&\\};
\path[-stealth]
(m-7-1) edge (m-7-3) edge (m-6-1)
(m-7-3) edge (m-7-5)
edge (m-6-3)
(m-7-5) edge (m-6-5)
edge (m-5-6)
(m-6-1) edge (m-6-3)
edge (m-4-1)
(m-6-3) edge (m-6-5)
edge (m-4-4)
(m-6-5) edge (m-4-6)
(m-5-2) edge (m-5-4)
edge (m-4-2)
edge (m-3-3)
(m-5-4) edge (m-4-4)
edge (m-5-6)
edge (m-3-5)
(m-5-6) edge (m-3-7)
(m-4-2) edge (m-4-4)
edge (m-2-2)
edge (m-2-3)
(m-4-4) edge (m-4-6)
edge (m-2-5)
(m-3-3) edge (m-2-3)
edge (m-3-5)
(m-3-5) edge (m-3-7)
(m-2-2) edge (m-1-3)
(m-2-3) edge (m-1-3)
(m-2-5) edge (m-2-7)
;
\path[>=stealth,-,thick]
(m-7-1) edge [double, minimum width=3cm] (m-5-2)
(m-6-1) edge [double, minimum width=3cm] (m-4-2)
(m-5-6) edge [double, minimum width=3cm] (m-4-6)
(m-4-1) edge [double, minimum width=3cm] (m-2-2)
(m-4-6) edge [double, minimum width=3cm] (m-2-7)
(m-3-5) edge [double, minimum width=3cm] (m-2-5)
(m-3-7) edge [double, minimum width=3cm] (m-2-7)
(m-2-3) edge [double, minimum width=3cm] (m-2-5)
;
\end{tikzpicture}
\end{document}
答案1
标准技巧是在下面画一条粗白线,可以使用 来实现preaction
。此答案带有样式on top
,可以像 一样使用(m-6-5) edge[on top] (m-4-6)
。您需要最后绘制最顶部的连接。目前,白线的默认线宽为,4pt
但您可以根据需要进行调整。
\documentclass[border=5mm]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[on top/.style={preaction={draw=white,-,line width=#1}},
on top/.default=4pt]
\matrix (m) [matrix of math nodes, row sep=1.6cm,
column sep=0.4cm]{
&&Level(1,3)&&&&\\
&Level(2,2)&Level(2,3)&& Level(2,5)&&Level(2,7)\\
&&Level(3,3)&& Level(3,5)&&Level(3,7)\\
Level(4,1)&Level(4,2)&& Level(4,4)&&Level(4,6)& \\
&Level(5,2)&& Level(5,4)&&Level(5,6)& \\
Level(6,1)&& Level(6,3)&& Level(6,5)&&\\
Level(7,1) && Level(7,3)&& Level(7,5)&&\\};
\path[-stealth]
(m-7-1) edge (m-7-3) edge (m-6-1)
(m-7-3) edge (m-7-5)
edge (m-6-3)
(m-7-5) edge (m-6-5)
edge (m-5-6)
(m-6-1) edge (m-4-1)
(m-6-3) edge (m-6-5)
(m-5-4) edge (m-4-4)
(m-5-2) edge (m-5-4)
edge (m-4-2)
edge (m-3-3)
(m-5-4) edge (m-5-6)
edge (m-3-5)
(m-5-6) edge (m-3-7)
(m-4-2) edge (m-2-2)
edge (m-2-3)
(m-3-3) edge (m-2-3)
edge (m-3-5)
(m-3-5) edge (m-3-7)
(m-2-2) edge (m-1-3)
(m-2-3) edge (m-1-3)
(m-2-5) edge (m-2-7)
(m-4-2) edge[on top] (m-4-4)
(m-4-4) edge[on top] (m-4-6)
(m-6-5) edge[on top] (m-4-6)
(m-4-4) edge[on top] (m-2-5)
(m-6-3) edge[on top] (m-4-4)
;
\path[>=stealth,-,thick]
(m-7-1) edge [double] (m-5-2)
(m-6-1) edge [double] (m-4-2)
(m-5-6) edge [double] (m-4-6)
(m-4-1) edge [double] (m-2-2)
(m-3-5) edge [double] (m-2-5)
(m-3-7) edge [double] (m-2-7)
(m-2-3) edge [double] (m-2-5)
(m-4-6) edge [double,on top=5pt] (m-2-7)
;
\path[-stealth] (m-6-1) edge[on top] (m-6-3) ;
\end{tikzpicture}
\end{document}
@egreg 称此代码“尴尬”。然而,在我看来,最多余的事情是必须手动添加条目的位置(但我不喜欢使用“尴尬”这样的词)。无论如何,这可以像定义样式一样容易地实现
level/.style={
execute at begin node={\text{Level}(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}
}
它会用到以下代码中,其中还包含一些绘制箭头的循环。
\documentclass[border=5mm]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[on top/.style={preaction={draw=white,-,line width=#1}},
on top/.default=4pt,level/.style={
execute at begin node={\text{Level}(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}
}]
\matrix (m) [matrix of math nodes,nodes=level,row sep=1.6cm,
column sep=0.4cm]{
&&{}&&&&\\
&{}&{}&& {}&&{}\\
&&{}&& {}&&{}\\
{}&{}&& {}&&{}& \\
&{}&& {}&&{}& \\
{}&& {}&& {}&&\\
{} && {}&& {}&&\\};
\path[-stealth]
(m-6-1) edge (m-4-1) (m-4-2) edge (m-2-2) (m-2-3) edge (m-1-3)
(m-4-2) edge (m-2-3) (m-5-2) edge (m-3-3)
(m-5-4) edge (m-3-5) (m-7-5) edge (m-5-6) (m-5-6) edge (m-3-7)
(m-2-2) edge (m-1-3);
\path[-stealth,every edge/.append style={on top}]
foreach \Y [count=\Z] in {3,5,7}{
foreach \X in {1,3,5}
{(m-\Y-\the\numexpr\X+3-\Z\relax) edge (m-\the\numexpr\Y-1\relax-\the\numexpr\X+3-\Z\relax)
\ifnum\X<5
(m-\Y-\the\numexpr\X+3-\Z\relax) edge (m-\Y-\the\numexpr\X+5-\Z\relax)
\ifnum\the\numexpr\Y*10+\X=31
\else
(m-\the\numexpr\Y-1\relax-\the\numexpr\X+3-\Z\relax) edge (m-\the\numexpr\Y-1\relax-\the\numexpr\X+5-\Z\relax)
\fi
\fi
}} (m-4-4) edge (m-2-5) (m-6-3) edge (m-4-4);
\path[thick,every edge/.append style={double,on top=5pt}]
(m-4-1) edge (m-2-2) (m-6-1) edge (m-4-2) (m-7-1) edge (m-5-2)
(m-2-3) edge (m-2-5) (m-2-7) edge (m-3-7)
(m-2-7) edge (m-4-6) (m-4-6) edge (m-6-5);
\path[-stealth,every edge/.append style={on top}] (m-6-1) edge (m-6-3);
\end{tikzpicture}
\end{document}
这些信息,连同这个答案,可以简化 egreg 的答案并纠正那里的箭头(以便有一个 3D 印象)。
\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{tikz-cd}
\usetikzlibrary{backgrounds}
\newcommand{\level}{\text{level}(\the\pgfmatrixcurrentrow,\the\pgfmatrixcurrentcolumn)}
\begin{document}
\begin{tikzcd}[column sep=1.5em,row sep=large,arrows={crossing over},
execute at end picture={
\begin{scope}[on background layer]
\path[->] (\tikzcdmatrixname-6-2) edge (\tikzcdmatrixname-6-4)
(\tikzcdmatrixname-6-4) edge (\tikzcdmatrixname-6-6)
(\tikzcdmatrixname-4-5) edge (\tikzcdmatrixname-4-7);
\end{scope}}]
&&
\level
\\ \\
&
\level \arrow[uur] &
\level \arrow[uu] \arrow[rr,thick,equals] &&
\level \arrow[rr] \arrow[ddl,leftarrow] &&
\level \arrow[ddl,thick,equals]
\\
&&
\level \arrow[u] \arrow[ddl,leftarrow] &&
\level \arrow[u,thick,equals] \arrow[ddl,leftarrow] &&
\level \arrow[u,thick,equals]
\\
\level \arrow[uur,thick,equals] &
\level \arrow[uu] \arrow[rr] \arrow[uur] &&
\level \arrow[rr] \arrow[ddl,leftarrow] &&
\level \arrow[ddl,leftarrow]
\\
&
\level \arrow[u] \arrow[ddl,leftarrow] &&
\level \arrow[u] &&
\level \arrow[u,thick,equals] \arrow[uur]
\\
\level \arrow[uu] \arrow[uur,thick,equals] \arrow[rr] &&
\level \arrow[rr] &&
\level
\\
\level \arrow[u] \arrow[rr] &&
\level \arrow[u] \arrow[rr] &&
\level \arrow[u] \arrow[uur]
\end{tikzcd}
\end{document}
答案2
对于crossing over
稍后绘制的箭头,擦除与其相交的部分箭头。
\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{tikz-cd}
\newcommand{\level}{\mathrm{Level}}
\begin{document}
\begin{tikzcd}[column sep=1.5em,row sep=large,arrows={crossing over}]
&&
\level(1,3)
\\ \\
&
\level(2,2) \arrow[uur] &
\level(2,3) \arrow[uu] \arrow[rr,thick,equals] &&
\level(2,5) \arrow[rr] \arrow[ddl,leftarrow] &&
\level(2,7) \arrow[ddl,thick,equals]
\\
&&
\level(3,3) \arrow[u] \arrow[rr] \arrow[ddl,leftarrow] &&
\level(3,5) \arrow[u,thick,equals] \arrow[rr] \arrow[ddl,leftarrow] &&
\level(3,7) \arrow[u,thick,equals]
\\
\level(4,1) \arrow[uur,thick,equals] &
\level(4,2) \arrow[uu] \arrow[rr] \arrow[uur] &&
\level(4,4) \arrow[rr] \arrow[ddl,leftarrow] &&
\level(4,6) \arrow[ddl,leftarrow]
\\
&
\level(5,2) \arrow[u] \arrow[rr] \arrow[ddl,leftarrow] &&
\level(5,4) \arrow[u] \arrow[rr] &&
\level(5,6) \arrow[u,thick,equals] \arrow[uur]
\\
\level(6,1) \arrow[uu] \arrow[uur,thick,equals] \arrow[rr] &&
\level(6,3) \arrow[rr] &&
\level(6,5)
\\
\level(7,1) \arrow[u] \arrow[rr] &&
\level(7,3) \arrow[u] \arrow[rr] &&
\level(7,5) \arrow[u] \arrow[uur]
\end{tikzcd}
\end{document}