使用自动机和叠加光束样式更改接受状态,而无需节点移动

使用自动机和叠加光束样式更改接受状态,而无需节点移动

我正在尝试使用 TikZ 和自动机包绘制自动机,我正在使用 overlay-beamer-styles 逐张修改该自动机。我正在更改的一件事是将哪些节点标记为接受状态。但是,更改此设置会导致所有内容略微移动,这在从一张幻灯片切换到另一张幻灯片时看起来很糟糕。我该如何解决这个问题?我希望所有边缘、节点标签等都保持在相同的位置,并且只有节点的边框发生变化,最好通过添加/删除内线来实现。

这是一个最小工作示例:

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{
    automata,
    overlay-beamer-styles}
    
\tikzset{
    accepting on/.style={alt=#1{accepting}{}}
}


\begin{document}

\begin{frame}{}
    \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}

输出如下:

在此处输入图片描述

答案1

自动机样式accepting by double定义为

\tikzset{accepting by double/.style= {double,outer sep=.5\pgflinewidth+.3pt}} % .3pt is half double width distance

这意味着不仅增加了双线,而且由于的不同,节点的大小也会发生变化outer sep

outer sep如果在不接受的覆盖上也增加,则可以避免节点在覆盖之间跳转:

\documentclass{beamer}

\usepackage{tikz}
\usetikzlibrary{
    automata,
    overlay-beamer-styles}
    
\tikzset{
    accepting on/.style={alt=#1{accepting}{accepting, double=none}}
}

\begin{document}

\begin{frame}
    \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}

在此处输入图片描述

答案2

ingdouble会改变节点大小,这会导致整个 TikZ 图片有点宽和高的典型问题(跳跃的第一个实例),但在这种情况下,它也会改变循环和沿循环放置的节点(跳跃的第二个实例)。

尽管samcarter 的回答通过使不接受状态与接受状态一样大来补偿这一点(这将导致节点边界和箭头之间出现一点空白)这个答案试图通过使接受状态与不接受状态一样大来解决这个问题:

  1. 不是double通过路径,而是通过nfold库来偏移它。

    对于圆形,这种方法非常有效。对于其他形状,这种方法可能不太有效。形状rectangle无法通过nfold(然而?) 并且由于矩形是在另一个方向构建的,因此偏移量需要反转。

    但是我们可以添加布尔值来轻松翻转偏移量。

  2. 通过添加另一个仅绘制且没有文本的圆形节点。

    如果您的所有状态都具有相同的大小和形状,这实际上是我首选的版本,否则您需要根据状态的变化情况对此进行一些调整。(不过,我们可以轻松添加一个漂亮的界面来做到这一点。)

    就其当前形式而言,它非常不灵活,并且使用硬编码数字。(我们可以测量原始节点,并使标签的大小依赖于此。)

    不过,当你开始使用颜色、变换或其他花哨的东西时,这可能会很容易被打破。

  3. 通过原始的double方式,accepting by double但是使节点稍微小一些。

    这仅当节点足够大时才有效,即,不会因为文本太大而超出minimum width/ 。height

总的来说,我更喜欢通过 来解决nfold,特别是如果您只使用圆圈,因为如果您自定义 s,它的干扰最小state

代码

\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}

相关内容