如何在箭头尖端附近添加一些小文字?
细节
我有一个像
现在我希望每条边都有通常的箭头尖,并且在尖头附近还有一个小文本$\tau$。我该怎么做?
一个好的、有效的解决方案会很棒:以一致的方式自动定位,这样可以立即明显地看到所有箭头都是 类型\underset{\scriptstyle \tau}{\Longrightarrow}
。这些标准比精确定位更重要,但这里有一个例子(\tau^*
我真正需要的是 ):
更好的方法是:使用一些小于的文本\tiny
,以将其与其他文本区分开来:
我试过
(s0) edge[bend left] node[pos=0.3] {$a$} node[pos=0.9,swap] {$\tau^*$} (s1)
但这样实现良好的定位非常困难。
最小示例:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}
\begin{document}
\begin{tikzpicture}
\node[state,inner sep=0pt,minimum size=.7cm] at (0,0) (s0) {$s_0$};
\node[state,inner sep=0pt,minimum size=.7cm] at (-1,-1) (s1) {$s_1$};
\path[->]
(s0)+(-.5cm,.5cm) edge[bend right,double] (s0)
(s0) edge[bend left,double] node[pos=0.3, auto] {$a$} (s1)
(s1) edge[bend left,double] node [auto] {$\epsilon,a$} (s0)
(s0) edge[loop above,double] node {$\epsilon,a$} (s0)
(s1) edge[loop below,double] node {$\epsilon,a$} (s1)
;
\end{tikzpicture}
\end{document}
答案1
自动放置并不容易,因为对于 TikZ 来说,文本只是一个矩形黑框。我们不知道文本中哪里的空白可以被线条或箭头占据,也不知道实际文本在哪里。这意味着,对于相同的放置选项,但对于不同的角度(在路径上应放置节点的那个点),我们会得到非常不同的吸引人的结果。
一个解决方法是沿路径旋转节点,使它们相对于路径本身的位置相同。这是在示例 1使用transform shape
选项(与其他选项结合使用可能会有缺点scale
)。
无可否认,这可能难读、难理解。示例 2显示几乎相同的图片,但没有transform shape
。最右上角的节点必须是raise
d,以便它不与箭头尖端重叠。
采用了一种截然不同的方法示例 3其中,arrow text*
使用键来计算局部坐标系旋转的角度。然后设置放置节点的锚点,使该锚点最接近路径,这意味着与路径正交的所有节点内容都比该锚点更远。circle
使用形状来保证这一点(未转换的矩形形状的角可能会再次突出到路径中)。但这对大箭头没有帮助。
当然,如果另一条路径或另一个节点挡住了 TikZ 和装饰,就无法阻止任何重叠。
arrow text=<optional additional distance>;<optional additional raise>:<optional alternative text>
这显然不是一个理想的解决方案,但在某些情况下,通过使用或以其他方式可以更容易地进行调整。
代码
\documentclass[tikz,convert]{standalone}
\usetikzlibrary{automata,decorations.markings}
\makeatletter
\tikzset{
arrow text/.style={
decoration={
name=markings,
mark=at position -\pgfkeysvalueof{/tikz/arrow text distance} with {%
\node[every arrow text node/.try] {$ #1 $};
}
},
postaction=decorate
},
arrow text*/.style={
decoration={
name=markings,
mark=at position -\pgfkeysvalueof{/tikz/arrow text distance} with {%
\pgfinterruptboundingbox
\pgfnode{coordinate}{center}{}{qrr@arrowtext@origin}{}%
\pgftransformshift{\pgfpointxy{0}{1}}%
\pgfnode{coordinate}{center}{}{qrr@arrowtext@down}{}%
\endpgfinterruptboundingbox
\begingroup
\pgftransformreset
\tikz@scan@one@point\pgfutil@firstofone(qrr@arrowtext@origin)\relax
\pgf@xa\pgf@x\pgf@ya\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(qrr@arrowtext@down)\relax
\advance\pgf@xa-\pgf@x\relax
\advance\pgf@ya-\pgf@y\relax
\csname pgfmathatan2\endcsname{+\pgf@xa}{+\pgf@ya}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
\let\qrr@arrowtext@anchor\pgfmathresult
\node[every arrow text node/.try, anchor/.expanded=\qrr@arrowtext@anchor] {$ #1 $};
}
},
postaction=decorate
},
arrow text*/.default={\tau\mkern-2mu^*},
arrow text/.default={\tau\mkern-2mu^*},
arrow text distance/.initial=3pt,
arrow text raise/.style={/pgf/decoration/raise={#1}},
every arrow text node/.style={font=\scriptsize,inner sep=+0pt,anchor=center},
arrow text raise=5pt
}
\makeatother
\begin{document}
\begin{tikzpicture}[every arrow text node/.append style={transform shape}]
\node[state,inner sep=0pt,minimum size=.7cm] at (0,0) (s0) {$s_0$};
\node[state,inner sep=0pt,minimum size=.7cm] at (-1,-1) (s1) {$s_1$};
\path[->, every edge/.append style={double, arrow text}]
(s0)+(-.5cm,.5cm) edge[bend right, arrow text distance=10pt] (s0)
(s0) edge[bend left, ] node[pos=0.3, auto] {$a$} (s1)
edge[loop above,] node {$\epsilon,a$} (s0)
(s1) edge[bend left, arrow text distance=6pt] node[auto] {$\epsilon,a$} (s0)
edge[loop below,] node {$\epsilon,a$} (s1)
;
\end{tikzpicture}
\begin{tikzpicture}
\node[state,inner sep=0pt,minimum size=.7cm] at (0,0) (s0) {$s_0$};
\node[state,inner sep=0pt,minimum size=.7cm] at (-1,-1) (s1) {$s_1$};
\path[->, every edge/.append style={double, arrow text}]
(s0)+(-.5cm,.5cm) edge[bend right, arrow text distance=10pt] (s0)
(s0) edge[bend left, ] node[pos=0.3, auto] {$a$} (s1)
edge[loop above, arrow text raise=10pt] node {$\epsilon,a$} (s0)
(s1) edge[bend left, arrow text distance=6pt] node[auto] {$\epsilon,a$} (s0)
edge[loop below,] node {$\epsilon,a$} (s1)
;
\end{tikzpicture}
\begin{tikzpicture}[
every arrow text node/.append style={shape=circle},
arrow text raise=1pt
]
\node[state,inner sep=0pt,minimum size=.7cm] at (0,0) (s0) {$s_0$};
\node[state,inner sep=0pt,minimum size=.7cm] at (-1,-1) (s1) {$s_1$};
\path[->, every edge/.append style={double, arrow text*}]
(s0)+(-.5cm,.5cm) edge[bend right, arrow text distance=10pt] (s0)
(s0) edge[bend left, ] node[pos=0.3, auto] {$a$} (s1)
edge[loop above,] node {$\epsilon,a$} (s0)
(s1) edge[bend left, arrow text distance=6pt] node[auto] {$\epsilon,a$} (s0)
edge[loop below,] node {$\epsilon,a$} (s1)
;
\end{tikzpicture}
\end{document}
输出