我正在将一些旧图形转换为 Tikz,并且遇到了一些我确信 Tikz 能够管理的东西,但还没有弄清楚如何管理......
目标图片:在这儿:
请注意,有 12 条带标签的边,每条边也都有一个箭头。对于每条边,当我沿着边的方向行进时,我会看到右侧有箭头(与边的方向倾斜相同),左侧有标签(不倾斜)。
以下是 MWE 尝试,使用sloped
以及above
和below
:
\documentclass[tikz,border=3mm]{standalone}
\tikzset{vertex/.style={circle, draw, fill=black, inner sep=0pt, minimum width=2mm}}
\begin{document}
\begin{tikzpicture}
\foreach \x/\y [count=\i] in {0/0,3/0,1/1,2/1,1/2,2/2,0/3,3/3}
\node[vertex] at (\x,\y) (\i) {};
\foreach \s/\t [count=\i] in {1/7,7/8,8/2,2/1,4/6,6/5,5/3,3/4,5/7,2/4,8/6,3/1}
\path (\s) edge node[midway,above] {\footnotesize \i} node[sloped,midway,below] {$\longrightarrow$} (\t);
\end{tikzpicture}
\end{document}
看起来像这样:
不太对!除了边缘上的编号确实位于边缘中心点上方之外,箭头也并非全部指向正确的方向。
当然,我可以分解 for 循环并生成令人满意的图片,但 Tikz 肯定有更好的解决方案吗?
答案1
\orientation
一个使用条件的选项,根据foreach 输入中的值 0 或 1来交换箭头和文本的位置;箭头使用中间节点倾斜点(如node_name.east
、 )绘制nodename.west
;使用 -> 和 <- 符号来控制在 foreach 输入中添加其他值的方向\dir
。抱歉,这不是最优雅的,但可以控制几乎所有东西以获得所需的结果。
结果:
梅威瑟:
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{arrows.meta}
\tikzset{vertex/.style={circle, draw, fill=black, inner sep=0pt, minimum width=1.5mm}}
\begin{document}
\begin{tikzpicture}[
>={Stealth[length=3pt]}
]
\foreach \x/\y [count=\i] in {0/0,3/0,1/1,2/1,1/2,2/2,0/3,3/3}{
\node[vertex] at (\x,\y) (\i) {};
}
\foreach \s/\t/\dir/\orientation [count=\i] in {
1/7/->/1,%1
7/8/->/1,%2
2/8/<-/0,%3
1/2/<-/1,%4
4/6/<-/0,%5
6/5/<-/1,%6
5/3/->/0,%7
3/4/->/0,%8
5/7/<-/0,%9
2/4/<-/1,%10
8/6/<-/0,%11
3/1/<-/1%12
}{
\ifnum\orientation=0
\draw (\s)
-- (\t)
node[
minimum width=0.6cm,
midway,
above,
sloped,
label={[inner sep=2pt]-90:\scriptsize\i}
](temp){};
\fi
\ifnum\orientation=1
\draw (\s)
-- (\t)
node[
minimum width=0.6cm,
midway,
below,
sloped,
label={[inner sep=2pt]90:\scriptsize\i}
](temp){};
\fi
\draw[\dir] (temp.west) -- (temp.east);
}
\end{tikzpicture}
\end{document}
答案2
这只是为了好玩。箭头会根据附着的路径进行一些自我调整。
\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.markings}
\tikzset{vertex/.style={circle, draw, fill=black, inner sep=0pt, minimum
width=2mm},arrow right/.style args={#1/#2}{postaction={decorate,decoration={markings,
mark=at position 0.5 with {%
\draw[-stealth]
(-1.5mm-\pgfdecoratedpathlength/8,{-1*#2*(1mm+min(\pgfdecoratedpathlength/16,1mm)}) --
(1.5mm+\pgfdecoratedpathlength/8,{-1*#2*(1mm+min(\pgfdecoratedpathlength/16,1mm)});
\node[font=\footnotesize] at (0,#2*2mm){#1};}}}}}
\begin{document}
\begin{tikzpicture}
\foreach \x/\y [count=\i] in {0/0,3/0,1/1,2/1,1/2,2/2,0/3,3/3}
\node[vertex] at (\x,\y) (\i) {};
\foreach \s/\t/\u [count=\i] in
{1/7/1,7/8/1,8/2/1,2/1/1,6/4/1,6/5/-1,5/3/-1,3/4/-1,5/7/1,2/4/1,8/6/1,3/1/1}
\path (\s) edge[arrow right=\i/\u]
(\t);
\end{tikzpicture}
\end{document}
答案3
最简单的解决方案可能是auto=right
向节点添加数字,并向allow upside down
节点添加箭头。
这与您的示例图片并不完全相同,因为并非所有数字都在箭头的右侧。
\documentclass[tikz,border=3mm]{standalone}
\tikzset{vertex/.style={circle, draw, fill=black, inner sep=0pt, minimum width=2mm}}
\begin{document}
\begin{tikzpicture}
\foreach \x/\y [count=\i] in {0/0,3/0,1/1,2/1,1/2,2/2,0/3,3/3}
\node[vertex] at (\x,\y) (\i) {};
\foreach \s/\t [count=\i] in {1/7,7/8,8/2,2/1,4/6,6/5,5/3,3/4,5/7,2/4,8/6,3/1}
\path (\s) edge node[midway,auto=right] {\footnotesize \i} node[sloped,midway,above,allow upside down] {$\longrightarrow$} (\t);
\end{tikzpicture}
\end{document}