我目前正在使用 Tikz 绘制有限自动机。我需要从一段文本向有限自动机的一个节点添加一个箭头,如示例所示。
我尝试使用“draw=none”创建节点。但是,这引发了两个问题。我无法在两行上写入所需的文本,而且,虽然创建了节点的边界框,但并未显示,因此箭头看起来非常糟糕,因为如此长的文本的边界框非常大。
\documentclass[11pt]{report}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows, automata}
\begin{document}
(not important stuff)
\begin{tikzpicture}[->,>=stealth', shorten >=1pt, auto, node distance=2.8cm, semithick]
\node[state] (A) {$Alarm$};
\node[state] (B) [above of=A] {$Reset$};
\node[state] (C) [above right of=A] {$S1$};
\node[state] (D) [right of=A] {$S2$};
\node[state] (E) [below right of=A] {$S3$};
\node[state] (F) [below of=A] {$S4$};
\node[state] (G) [left of=A] {$Open$};
\node[statem, draw=none] (H) [above left of=B] {Reset input(from any state)};
\path (A) edge [loop left] node {0, 1} (A)
(B) edge [bend left] node {1} (C)
edge node {0} (A)
(C) edge [bend left] node {0} (D)
edge node {1} (A)
(D) edge [bend left] node {1} (E)
edge node {0} (A)
(E) edge [bend left] node {1} (F)
edge node {0} (A)
(F) edge [bend left] node {0} (G)
edge node {1} (A)
(G) edge [bend left] node {0} (B)
edge [loop left] node {1} (G)
(H) edge node {} (B);
\end{tikzpicture}
(more not important stuff)
\end{document}
PS 如果知道如何将箭头移动到边缘的中间也会很感激(目前它们位于边缘的末端)。
答案1
以下是使用automata
库和装饰将箭头放置在边缘中间的一种可能性:
代码:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata,decorations.markings,positioning,arrows}
\begin{document}
\begin{tikzpicture}[
midarr/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {\arrow[xshift=3.333pt]{triangle 45} \node[#1] {#2};},
},
postaction=decorate,
},
state/.append style={minimum size=35pt},
node distance=1.3cm and 1.3cm
]
\node[state]
(open) {Open};
\node[state,right=of open]
(alarm) {Alarm};
\node[state,right=of alarm]
(s1) {S1};
\node[state,above=of alarm,xshift=10pt]
(reset) {Reset};
\node[state,below=of alarm,xshift=10pt]
(s2) {S2};
\node[left=of reset,align=right,yshift=20pt]
(resetany) {Reset input\\ (from any state)};
\draw[-triangle 45]
(resetany.east) -- (reset);
\draw[midarr={right=2pt}{1}]
(s2) -- (alarm);
\draw[midarr={right=2pt}{0}]
(reset) -- (alarm);
\draw[midarr={below=1pt}{0}]
(s1) -- (alarm);
\draw[midarr={below left}{0}]
(s2) to[bend left] (open);
\draw[midarr={above left}{0}]
(open) to[bend left] (reset);
\draw[midarr={above right}{1}]
(reset) to[bend left] (s1);
\draw[midarr={below right}{1}]
(s1) to[bend left] (s2);
\draw[midarr={left}{$0,1$}]
(alarm) to[out=230,in=130,looseness=2.5] (alarm);
\draw[midarr={left}{1}]
(open) to[out=230,in=130,looseness=2.5] (open);
\end{tikzpicture}
\end{document}
有一种initial
样式(参考文档),但我选择了一种\node
具有一些属性的简单样式来放置“重置输入(从任何状态)”文本。
这是问题代码的修改版本,使用与以前相同的想法:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata,decorations.markings,positioning,arrows}
\begin{document}
\begin{tikzpicture}[
midarr/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {\arrow[xshift=3.333pt]{stealth'} \node[#1] {#2};},
},
postaction=decorate,
},
state/.append style={minimum size=35pt},
node distance=1.6cm and 1.6cm,
semithick,
>=stealth',
shorten >=1pt
]
\node[state]
at (0,0)
(alarm) {Alarm};
\node[state,left=of alarm]
(open) {Open};
\node[state]
at (45:2.8cm)
(s1) {S1};
\node[state,right=of alarm]
(s2) {S2};
\node[state,above=of alarm]
(reset) {Reset};
\node[state]
at (-45:2.8cm)
(s3) {S3};
\node[state,below=of alarm]
(s4) {S4};
\draw[midarr={right=2pt}{0}]
(reset) -- (alarm);
\draw[midarr={below right=1pt}{1}]
(s1) -- (alarm);
\draw[midarr={below=1pt}{0}]
(s2) -- (alarm);
\draw[midarr={below left}{0}]
(s3) -- (alarm);
\draw[midarr={left=2pt}{1}]
(s4) -- (alarm);
\draw[midarr={below left}{0}]
(s4) to[bend left] (open);
\draw[midarr={above left}{0}]
(open) to[bend left] (reset);
\draw[midarr={above right}{1}]
(reset) to[out=0,in=132] (s1);
\draw[midarr={right=2pt}{0}]
(s1) to[out=-45,in=90] (s2);
\draw[midarr={right=2pt}{1}]
(s2) to[out=-90,in=45] (s3);
\draw[midarr={below right}{1}]
(s3) to[out=-135,in=0] (s4);
\draw[midarr={left}{$0,1$}]
(alarm) to[out=230,in=130,looseness=2.5] (alarm);
\draw[midarr={left}{1}]
(open) to[out=230,in=130,looseness=2.5] (open);
\node[left=of reset,align=right,yshift=30pt,xshift=10pt]
(resetany) {Reset input\\ (from any state)};
\draw[-stealth']
(resetany.east) -- (reset);
\end{tikzpicture}
\end{document}