The double
ing changes the node size which lead to the typical problem of the whole TikZ picture being a bit wider and higher (first instance of jumping) but in this case it will also change the loops and the nodes placed a long the loop a bit (second instance of jumping).
While samcarter's answer compensates this by making the non-accepting state as big as the accepting one (which will lead to a bit whitespace between the node's border and the arrow) this answer tries to solve this by making the accepting one as big as the non-accepting one:
By not double
ing the path but by offsetting it via the nfold
library.
For circles this works perfectly. For other shapes, this might not work as neatly. The rectangle
shape isn't handled correctly by nfold
(yet?) and the offset needs to be inverted since the rectangle is constructed in the other direction.
But we could add a boolean to flip/flop the offset easily.
By adding another circle node that's only drawn and has no text.
This is actually my preferred version if your states all had the same size and shape otherwise you would need to adapt this a bit depending on how your states vary. (Though, we could easily add a nice interface to do this.)
In its current form it's very inflexible and uses hard-coded numbers. (We could measure the original node and make the label's size dependent on that.)
Though, when you start using colors, transformation or other fancy stuff this might break very easily.
By the original double
ing via accepting by double
but by making the node a bit smaller.
This only works if the node is big enough, i.e. the minimum width
/height
is not exceeded because the text is too big.
Overall I'd prefer the solution via nfold
, especially if you only use circles since it has the least interference in case you customize your state
s.
Code
\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{automata,overlay-beamer-styles,nfold}
\makeatletter
\tikzset{offset/.code=\tikz@addmode{\pgfgetpath\tikz@temp\pgfsetpath\pgfutil@empty\pgfoffsetpath\tikz@temp{#1}}}
\makeatother
\tikzset{
accepting by offset/.style={postaction={path only, draw, offset=#1}},
accepting by label/.style={label={[circle,path only, draw, minimum size={1.5cm-(#1)}]center:}},
accepting by smaller/.style={
accepting by double,
minimum width/.expanded={\pgfkeysvalueof{/pgf/minimum width}-(\pgfkeysvalueof{/pgf/outer xsep})-.5\pgflinewidth},
minimum height/.expanded={\pgfkeysvalueof{/pgf/minimum height}-(\pgfkeysvalueof{/pgf/outer ysep})-.5\pgflinewidth}},
set accepting on/offset/.style={accepting on/.style={alt={##1{accepting by offset={#1}}{}}}},
set accepting on/label/.style={accepting on/.style={alt={##1{accepting by label={#1}}{}}}},
set accepting on/smaller/.style={accepting on/.style={alt={##1{accepting by smaller}{}}}},
set accepting on/offset=+1pt, % just a default
}
\begin{document}
\begin{frame}{Accepting by offset}
\begin{tikzpicture}[initial text=, auto, state/.append style={minimum size=1.5cm}]
\node[state,initial,accepting on=<2>] (z0) at (0,0) {$z_0$};
\node[state,accepting on=<1>] (z1) at (2,0) {$z_1$};
\path[->] (z0) edge [loop above] node {$a$} (z0)
edge node {$b$} (z1)
(z1) edge [loop above] node {$a,b$} (z1);
\end{tikzpicture}
\end{frame}
\begin{frame}{Accepting by label}
\tikzset{set accepting on/label=2pt}
\begin{tikzpicture}[initial text=, auto, state/.append style={minimum size=1.5cm}]
\node[state,initial,accepting on=<2>] (z0) at (0,0) {$z_0$};
\node[state,accepting on=<1>] (z1) at (2,0) {$z_1$};
\path[->] (z0) edge [loop above] node {$a$} (z0)
edge node {$b$} (z1)
(z1) edge [loop above] node {$a,b$} (z1);
\end{tikzpicture}
\end{frame}
\begin{frame}{Accepting by smaller}
\tikzset{set accepting on/smaller=.3pt+\pgflinewidth}
\begin{tikzpicture}[initial text=, auto, state/.append style={minimum size=1.5cm}]
\node[state,initial,accepting on=<2>] (z0) at (0,0) {$z_0$};
\node[state,accepting on=<1>] (z1) at (2,0) {$z_1$};
\path[->] (z0) edge [loop above] node {$a$} (z0)
edge node {$b$} (z1)
(z1) edge [loop above] node {$a,b$} (z1);
\end{tikzpicture}
\end{frame}
\end{document}
accepting
is done bydouble
which changes the size of the node (which also changes the path of the loobs very slightly resulting in a different placement of the node along the loop).