使用 tikz 对齐流程图

使用 tikz 对齐流程图

我正在为编程课程制作一些流程图,其中一张图存在对齐问题。流程图中的线条通常从一个符号指向另一个符号。但是,我希望该线条与另一条线条相交。

我现有的 TeX 文件:

\documentclass{article}

\usepackage[margin=1.0in]{geometry}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning}

\begin{document}
\pagestyle{empty}

\tikzstyle{decision}=[diamond, draw, fill=yellow!20,
  text width=7em, text badly centered, node distance=3cm,
  inner sep=0pt]
\tikzstyle{block}=[rectangle, draw, fill=blue!20, 
  text width=10em, text badly centered, rounded corners,
  minimum height=4em]
\tikzstyle{line}=[draw, very thick, color=black!75, -latex']

\begin{center}
\begin{tikzpicture}[node distance=2cm, auto]
  % Place nodes
  \node [block] (read_first_integer) {Read first integer};
  \node [block, below of=read_first_integer] (read_second_integer)
        {Read second integer};
  \node [block, below of=read_second_integer] (read_third_integer)
        {Read third integer};
  \node [block, below of=read_third_integer] (calculate)
        {Calculate sum, product, difference};
  \node [decision, below of=calculate] (q_first_integer_smallest)
        {First integer less than second and third?};
  \node [block, on grid=false, below of=q_first_integer_smallest,
         node distance=3cm] (first_integer_smallest)
        {First integer is smallest};
  \node [decision, left of=q_first_integer_smallest,
         node distance=4.5cm] (q_second_integer_smallest)
        {Second integer less than second and third?};
  \node [block, below of=q_second_integer_smallest,
         node distance=3cm]
        (second_integer_smallest) {Second integer is smallest};
  \node [block, left of=q_second_integer_smallest,
         node distance=4.5cm] (third_integer_smallest)
        {Third integer is smallest};
  \node [decision, below of=first_integer_smallest,
         node distance=3.5cm] (q_first_integer_largest)
        {First integer larger than second and third?};

  % Draw edges
  \path [line] (read_first_integer) -- (read_second_integer);
  \path [line] (read_second_integer) -- (read_third_integer);
  \path [line] (read_third_integer) -- (calculate);
  \path [line] (calculate) -- (q_first_integer_smallest);
  \path [line] (q_first_integer_smallest) -- node [near start]
               {no} (q_second_integer_smallest);
  \path [line] (q_first_integer_smallest) -- node [near start]
               {yes} (first_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {no} (third_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {yes} (second_integer_smallest);
  \path [line] (first_integer_smallest) -- (q_first_integer_largest);
  \path [line] (second_integer_smallest) |- (q_first_integer_largest);
  \path [line] (third_integer_smallest) |- (q_first_integer_largest);
\end{tikzpicture}
\end{center}

\end{document}

结果:在此处输入图片描述

我已经完成以下解决方案,并想知道是否有更简单的方法:

\documentclass{article}

\usepackage[margin=0.5in]{geometry}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning}

\begin{document}
\pagestyle{empty}

\tikzstyle{decision}=[diamond, draw, fill=yellow!20,
  text width=7em, text badly centered, node distance=3cm,
  inner sep=0pt]
\tikzstyle{block}=[rectangle, draw, fill=blue!20, 
  text width=10em, text badly centered, rounded corners,
  minimum height=4em]
\tikzstyle{line}=[draw, very thick, color=black!75, -latex']
\tikzstyle{empty}=[]

\begin{center}
\begin{tikzpicture}[node distance=2cm, auto]
  % Place nodes
  \node [block] (read_first_integer) {Read first integer};
  \node [block, below of=read_first_integer] (read_second_integer)
        {Read second integer};
  \node [block, below of=read_second_integer] (read_third_integer)
        {Read third integer};
  \node [block, below of=read_third_integer] (calculate)
        {Calculate sum, product, difference};
  \node [decision, below of=calculate] (q_first_integer_smallest)
        {First integer less than second and third?};
  \node [block, on grid=false, below of=q_first_integer_smallest,
         node distance=3cm] (first_integer_smallest)
        {First integer is smallest};
  \node [decision, left of=q_first_integer_smallest,
         node distance=4.5cm] (q_second_integer_smallest)
        {Second integer less than second and third?};
  \node [block, below of=q_second_integer_smallest,
         node distance=3cm]
        (second_integer_smallest) {Second integer is smallest};
  \node [empty, below of=second_integer_smallest, node distance=1.25cm,
         inner sep=0pt] (e_second_integer_smallest) {};
  \node [block, left of=q_second_integer_smallest,
         node distance=4.5cm] (third_integer_smallest)
        {Third integer is smallest};
  \node [empty, below of=first_integer_smallest, node distance=1.25cm,
         inner sep=0pt] (e_first_integer_smallest) {};

  \node [decision, below of=first_integer_smallest,
         node distance=4cm] (q_first_integer_largest)
        {First integer larger than second and third?};
  \node [block, below of=q_first_integer_largest,
         node distance=3cm] (first_integer_largest)
        {First integer is largest};
  \node [decision, left of=q_first_integer_largest,
         node distance=4.5cm] (q_second_integer_largest)
        {Second integer larger than second and third?};
  \node [block, below of=q_second_integer_largest,
         node distance=3cm] (second_integer_largest)
        {Second integer is largest};
  \node [empty, below of=second_integer_largest, node distance=2cm,
         inner sep=0pt] (e_second_integer_largest) {};
  \node [block, left of=q_second_integer_largest,
         node distance=4.5cm] (third_integer_largest)
        {Third integer is largest};
  \node [block, below of=first_integer_largest,
         node distance=2cm] (output) {Output results};

  % Draw edges
  \path [line] (read_first_integer) -- (read_second_integer);
  \path [line] (read_second_integer) -- (read_third_integer);
  \path [line] (read_third_integer) -- (calculate);
  \path [line] (calculate) -- (q_first_integer_smallest);

  \path [line] (q_first_integer_smallest) -- node [near start]
               {no} (q_second_integer_smallest);
  \path [line] (q_first_integer_smallest) -- node [near start]
               {yes} (first_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {no} (third_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {yes} (second_integer_smallest);
  \path [line] (first_integer_smallest) -- (q_first_integer_largest);
  \path [line] (second_integer_smallest) -- (e_second_integer_smallest);
  \path [line] (third_integer_smallest) |- (e_first_integer_smallest);

  \path [line] (q_first_integer_largest) -- node [near start]
               {no} (q_second_integer_largest);
  \path [line] (q_first_integer_largest) -- node [near start]
               {yes} (first_integer_largest);
  \path [line] (q_second_integer_largest) -- node [near start]
               {no} (third_integer_largest);
  \path [line] (q_second_integer_largest) -- node [near start]
               {yes} (second_integer_largest);
  \path [line] (first_integer_largest) -- (output);
  \path [line] (second_integer_largest) -- (e_second_integer_largest);
  \path [line] (third_integer_largest) |- (output);
\end{tikzpicture}
\end{center}

\end{document}

结果:在此处输入图片描述

而且,为什么“第一个整数大于第二个和第三个?”和“第一个整数最大”之间的界线这么小?

答案1

无需定义新节点e_second_integer_largest。您可以使用正交坐标,例如

(second_integer_smallest |- q_first_integer_largest)

这意味着x坐标与second_integer_smallest和坐标与y相同q_first_integer_largest

\path [line] (second_integer_smallest) -- (second_integer_smallest |- q_first_integer_largest);

“第一个整数大于第二个和第三个?”和“第一个整数最大”之间的行太小,是因为多了一个文本行。您可以在节点样式text width的定义中调整,例如decisiontext width=8em,

\documentclass{article}

\usepackage[margin=0.5in]{geometry}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning}

\begin{document}
\pagestyle{empty}

\tikzstyle{decision}=[diamond, draw, fill=yellow!20,
  text width=8em, text badly centered, node distance=3cm,
  inner sep=0pt]
\tikzstyle{block}=[rectangle, draw, fill=blue!20,
  text width=10em, text badly centered, rounded corners,
  minimum height=4em]
\tikzstyle{line}=[draw, very thick, color=black!75, -latex']
\tikzstyle{empty}=[]

\begin{center}
\begin{tikzpicture}[node distance=2cm, auto]
  % Place nodes
  \node [block] (read_first_integer) {Read first integer};
  \node [block, below of=read_first_integer] (read_second_integer)
        {Read second integer};
  \node [block, below of=read_second_integer] (read_third_integer)
        {Read third integer};
  \node [block, below of=read_third_integer] (calculate)
        {Calculate sum, product, difference};
  \node [decision, below of=calculate] (q_first_integer_smallest)
        {First integer less than second and third?};
  \node [block, on grid=false, below of=q_first_integer_smallest,
         node distance=3cm] (first_integer_smallest)
        {First integer is smallest};
  \node [decision, left of=q_first_integer_smallest,
         node distance=4.5cm] (q_second_integer_smallest)
        {Second integer less than second and third?};
  \node [block, below of=q_second_integer_smallest,
         node distance=3cm]
        (second_integer_smallest) {Second integer is smallest};
%  \node [empty, below of=second_integer_smallest, node distance=1.25cm,
%         inner sep=0pt] (e_second_integer_smallest) {};
  \node [block, left of=q_second_integer_smallest,
         node distance=4.5cm] (third_integer_smallest)
        {Third integer is smallest};
  \node [empty, below of=first_integer_smallest, node distance=1.25cm,
         inner sep=0pt] (e_first_integer_smallest) {};

  \node [decision, below of=first_integer_smallest,
         node distance=4cm] (q_first_integer_largest)
        {First integer larger than second and third?};
  \node [block, below of=q_first_integer_largest,
         node distance=3cm] (first_integer_largest)
        {First integer is largest};
  \node [decision, left of=q_first_integer_largest,
         node distance=4.5cm] (q_second_integer_largest)
        {Second integer larger than second and third?};
  \node [block, below of=q_second_integer_largest,
         node distance=3cm] (second_integer_largest)
        {Second integer is largest};
%  \node [empty, below of=second_integer_largest, node distance=2cm,
%         inner sep=0pt] (e_second_integer_largest) {};
  \node [block, left of=q_second_integer_largest,
         node distance=4.5cm] (third_integer_largest)
        {Third integer is largest};
  \node [block, below of=first_integer_largest,
         node distance=2cm] (output) {Output results};

  % Draw edges
  \path [line] (read_first_integer) -- (read_second_integer);
  \path [line] (read_second_integer) -- (read_third_integer);
  \path [line] (read_third_integer) -- (calculate);
  \path [line] (calculate) -- (q_first_integer_smallest);

  \path [line] (q_first_integer_smallest) -- node [near start]
               {no} (q_second_integer_smallest);
  \path [line] (q_first_integer_smallest) -- node [near start]
               {yes} (first_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {no} (third_integer_smallest);
  \path [line] (q_second_integer_smallest) -- node [near start]
               {yes} (second_integer_smallest);
  \path [line] (first_integer_smallest) -- (q_first_integer_largest);
  \path [line] (second_integer_smallest) -- (second_integer_smallest |- e_first_integer_smallest);
  \path [line] (third_integer_smallest) |- (e_first_integer_smallest);

  \path [line] (q_first_integer_largest) -- node [near start]
               {no} (q_second_integer_largest);
  \path [line] (q_first_integer_largest) -- node [near start]
               {yes} (first_integer_largest);
  \path [line] (q_second_integer_largest) -- node [near start]
               {no} (third_integer_largest);
  \path [line] (q_second_integer_largest) -- node [near start]
               {yes} (second_integer_largest);
  \path [line] (first_integer_largest) -- (output);
  %\path [line] (second_integer_largest) -- (e_second_integer_largest);
  \path [line] (second_integer_largest) -- (second_integer_largest |- output);
  \path [line] (third_integer_largest) |- (output);
\end{tikzpicture}
\end{center}

\end{document}

在此处输入图片描述

答案2

加载positioning库您可以使用below = of <node name>代替below of = <node name>。 那么node distance=<length>意味着节点边界之间的距离。 因此不再需要node distance根据节点大小更改 。

我也已替换\tikzstyle\tikzset

\documentclass{article}
\usepackage[margin=0.5in]{geometry}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,positioning}
\tikzset{
  decision/.style={diamond,draw,fill=yellow!20,text width=6em,
    inner sep=.1em,text badly centered},
  block/.style={draw, fill=blue!20,text width=10em,
    text badly centered, rounded corners,minimum height=4em},
  line/.style={draw, very thick, color=black!75, -latex'},
  empty/.style={inner sep=0pt}
}
\begin{document}
\pagestyle{empty}
\begin{center}
\begin{tikzpicture}[node distance=.6cm, auto]
  % Place nodes
  \node [block] (read_first_integer) {Read first integer};
  \node [block, below = of read_first_integer] (read_second_integer)
        {Read second integer};
  \node [block, below = of read_second_integer] (read_third_integer)
        {Read third integer};
  \node [block, below = of read_third_integer] (calculate)
        {Calculate sum, product, difference};
  \node [decision, below = of calculate] (q_first_integer_smallest)
        {First integer less than second and third?};
  \node [block, below = of q_first_integer_smallest] (first_integer_smallest)
        {First integer is smallest};
  \node [decision, left = of q_first_integer_smallest] (q_second_integer_smallest)
        {Second integer less than second and third?};
  \node [block, below = of q_second_integer_smallest]
        (second_integer_smallest) {Second integer is smallest};
  \node [block, left = of q_second_integer_smallest] (third_integer_smallest)
        {Third integer is smallest};
  \node [empty, below = of first_integer_smallest] (e_first_integer_smallest) {};
  \node [decision, below = of e_first_integer_smallest] (q_first_integer_largest)
        {First integer larger than second and third?};
  \node [block, below = of q_first_integer_largest] (first_integer_largest)
        {First integer is largest};
  \node [decision, left = of q_first_integer_largest] (q_second_integer_largest)
        {Second integer larger than second and third?};
  \node [block, below = of q_second_integer_largest] (second_integer_largest)
        {Second integer is largest};
  \node [block, left = of q_second_integer_largest] (third_integer_largest)
        {Third integer is largest};
  \node [block, below = of first_integer_largest] (output) {Output results};
  % Draw edges
  \begin{scope}[every path/.style=line]
    \path (read_first_integer) -- (read_second_integer);
    \path (read_second_integer) -- (read_third_integer);
    \path (read_third_integer) -- (calculate);
    \path (calculate) -- (q_first_integer_smallest);
    \path (q_first_integer_smallest)
          -- node [near start]{no} (q_second_integer_smallest);
    \path (q_first_integer_smallest)
          -- node [near start]{yes} (first_integer_smallest);
    \path (q_second_integer_smallest)
          -- node [near start]{no} (third_integer_smallest);
    \path (q_second_integer_smallest)
          -- node [near start]{yes} (second_integer_smallest);
    \path (first_integer_smallest) -- (q_first_integer_largest);
    \path (second_integer_smallest)
          -- (second_integer_smallest |- e_first_integer_smallest);
    \path (third_integer_smallest) |- (e_first_integer_smallest);
    \path (q_first_integer_largest)
          -- node [near start]{no} (q_second_integer_largest);
    \path (q_first_integer_largest)
          -- node [near start]{yes} (first_integer_largest);
    \path (q_second_integer_largest)
          -- node [near start]{no} (third_integer_largest);
    \path (q_second_integer_largest)
          -- node [near start]{yes} (second_integer_largest);
    \path (first_integer_largest) -- (output);
    \path (second_integer_largest) -- (second_integer_largest |- output);
    \path (third_integer_largest) |- (output);
  \end{scope}    
\end{tikzpicture}
\end{center}
\end{document}

结果:

在此处输入图片描述


另一种可能性是使用matrix来定位节点。column sep和 是row sep节点边界之间的最小距离。

\documentclass{article}
\usepackage[margin=0.5in]{geometry}
\usepackage[latin1]{inputenc}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,matrix}
\tikzset{
  decision/.style={diamond,draw,fill=yellow!20,text width=6em,
    text badly centered,inner sep=.1em},
  block/.style={draw, fill=blue!20,text width=10em,
    text badly centered, rounded corners,minimum height=4em},
  line/.style={draw, very thick, color=black!75, -latex'},
  empty/.style={inner sep=0pt}
}
\begin{document}
\pagestyle{empty}
\begin{center}
\begin{tikzpicture}[auto]
  % Place nodes
  \matrix[matrix of nodes,row sep=6mm,column sep=6mm,nodes={anchor=center}]{
    &&|[block](read_first_integer)|Read first integer\\
    &&|[block](read_second_integer)|Read second integer\\
    &&|[block](read_third_integer)|Read third integer\\
    &&|[block](calculate)|Calculate sum, product, difference\\
    |[block](third_integer_smallest)|Third integer is smallest&
      |[decision](q_second_integer_smallest)|Second integer less than second and third?&
      |[decision](q_first_integer_smallest)|First integer less than second and third?\\
    &|[block](second_integer_smallest)|Second integer is smallest&
      |[block](first_integer_smallest)|First integer is smallest\\
    &&|[empty](e_first_integer_smallest)|\\
    |[block](third_integer_largest)|Third integer is largest?&
      |[decision](q_second_integer_largest)|Second integer larger than second and third?&
      |[decision](q_first_integer_largest)|First integer larger than second and third?\\
    &|[block](second_integer_largest)|Second integer is largest&
      |[block](first_integer_largest)|First integer is largest\\
    &&|[block](output)|Output results\\
  };
  % Draw edges
  \begin{scope}[every path/.style=line]
    \path (read_first_integer) -- (read_second_integer);
    \path (read_second_integer) -- (read_third_integer);
    \path (read_third_integer) -- (calculate);
    \path (calculate) -- (q_first_integer_smallest);
    \path (q_first_integer_smallest)
          -- node [near start]{no} (q_second_integer_smallest);
    \path (q_first_integer_smallest)
          -- node [near start]{yes} (first_integer_smallest);
    \path (q_second_integer_smallest)
          -- node [near start]{no} (third_integer_smallest);
    \path (q_second_integer_smallest)
          -- node [near start]{yes} (second_integer_smallest);
    \path (first_integer_smallest) -- (q_first_integer_largest);
    \path (second_integer_smallest)
          -- (second_integer_smallest |- e_first_integer_smallest);
    \path (third_integer_smallest) |- (e_first_integer_smallest);
    \path (q_first_integer_largest)
          -- node [near start]{no} (q_second_integer_largest);
    \path (q_first_integer_largest)
          -- node [near start]{yes} (first_integer_largest);
    \path (q_second_integer_largest)
          -- node [near start]{no} (third_integer_largest);
    \path (q_second_integer_largest)
          -- node [near start]{yes} (second_integer_largest);
    \path (first_integer_largest) -- (output);
    \path (second_integer_largest) -- (second_integer_largest |- output);
    \path (third_integer_largest) |- (output);
  \end{scope}
\end{tikzpicture}
\end{center}
\end{document}

结果:

在此处输入图片描述

相关内容