TikZ 箭头绘制和节点位置

TikZ 箭头绘制和节点位置

我刚开始使用 TikZ,我想画出和这幅图一模一样的画,在此处输入图片描述

我尝试过,结果如下在此处输入图片描述,这不是我想要的,我该如何实现想要的结果?谢谢

我的 MWE:

\documentclass{article}
\usepackage{tikz}
\begin{document}
            \tikzstyle{block} = [draw,text centered, minimum height=2.8em,minimum width=12em]
        \tikzstyle{block1} = [text centered, minimum height=2.8em,minimum width=12em]   
    \begin{tikzpicture}
    \node [block] at (0,0) (1) {\textbf{Abstract Specification ($R_{0}$)}};
    \node [block] at (1.7,-2) (2) {\textbf{Refined Specification($R_{1}$)}};
    \node [block1] at (3.5,-3.8) (3) {.........};
    \node [block] at (6,-6) (4) {\textbf{Refined Specification ($R_{N}$)}};
    \node [block] at (7.5,-8) (5) {\textbf{Executable Program}};
        % arroows
 \draw [-latex,thick] (1.south) --  node [right] {\small{$Refinement$}} (2.north) ;
 \draw [-latex,thick] (2.south) --  node [right] {\small{$Refinement$}} (3.north) ;
  \draw [-latex,thick] (3.south) --  node [right] {\small{$Refinement$}} (4.north) ;
  \draw [-latex,thick] (4.south) --  node [right] {\small{$Refinement$}} (5.north) ;
    \end{tikzpicture}
\end{document}

答案1

第一个解决方法是去掉.north.south,这样箭头就会指向中心。(tikz 足够聪明,不会“显示”连接其中路径的箭头)

但为了得到真正平行的箭头,您需要将坐标固定为精确的步骤:

\documentclass{article}
\usepackage{tikz}

\begin{document}
            \tikzstyle{block} = [draw,text centered, minimum height=2.8em,minimum width=12em]
        \tikzstyle{block1} = [text centered, minimum height=2.8em,minimum width=12em]   
    \begin{tikzpicture}
    \node [block] at (0,0) (1) {\textbf{Abstract Specification ($R_{0}$)}};
    \node [block] at (1.7,-2) (2) {\textbf{Refined Specification($R_{1}$)}};
    \node [block1] at (3.4,-4) (3) {.........};
    \node [block] at (5.1,-6) (4) {\textbf{Refined Specification ($R_{N}$)}};
    \node [block] at (6.8,-8) (5) {\textbf{Executable Program}};
        % arroows
 \draw [-latex,thick] (1) --  node [right] {\small{$Refinement$}} (2) ;
 \draw [-latex,thick] (2) --  node [right] {\small{$Refinement$}} (3) ;
  \draw [-latex,thick] (3) --  node [right] {\small{$Refinement$}} (4) ;
  \draw [-latex,thick] (4) --  node [right] {\small{$Refinement$}} (5) ;
    \end{tikzpicture}
\end{document}

输出:

在此处输入图片描述

下一步是使用 bm 包使数学运算也加粗......

\documentclass{article}
\usepackage{tikz}
\usepackage{bm}

\begin{document}
            \tikzstyle{block} = [draw,text centered, minimum height=2.8em,minimum width=12em]
        \tikzstyle{block1} = [text centered, minimum height=2.8em,minimum width=12em]   
    \begin{tikzpicture}
    \node [block] at (0,0) (1) {\textbf{Abstract Specification ($\bm{R_{0}}$)}};
    \node [block] at (1.7,-2) (2) {\textbf{Refined Specification ($\bm{R_{1}}$)}};
    \node [block1] at (3.4,-4) (3) {.........};
    \node [block] at (5.1,-6) (4) {\textbf{Refined Specification (\bm{$R_{N}}$)}};
    \node [block] at (6.8,-8) (5) {\textbf{Executable Program}};
        % arroows
 \draw [-latex,thick] (1) --  node [right] {\small{$Refinement$}} (2) ;
 \draw [-latex,thick] (2) --  node [right] {\small{$Refinement$}} (3) ;
  \draw [-latex,thick] (3) --  node [right] {\small{$Refinement$}} (4) ;
  \draw [-latex,thick] (4) --  node [right] {\small{$Refinement$}} (5) ;
    \end{tikzpicture}
\end{document}

输出:与粗体数学相同。

最后,如果您想使箭头和矩形变得特别粗(这样通过强调流程和单独的步骤,它将更接近流程图)

\documentclass{article}
\usepackage{tikz}

\begin{document}
            \tikzstyle{block} = [draw,thick,text centered, minimum height=2.8em,minimum width=12em]
        \tikzstyle{block1} = [text centered, minimum height=2.8em,minimum width=12em]   
    \begin{tikzpicture}
    \node [block] at (0,0) (1) {\textbf{Abstract Specification ($\bm{R_{0}}$)}};
    \node [block] at (1.7,-2) (2) {\textbf{Refined Specification ($\bm{R_{1}}$)}};
    \node [block1] at (3.4,-4) (3) {.........};
    \node [block] at (5.1,-6) (4) {\textbf{Refined Specification (\bm{$R_{N}}$)}};
    \node [block] at (6.8,-8) (5) {\textbf{Executable Program}};
        % arroows
 \draw [-latex,ultra thick] (1) --  node [right] {\small{$Refinement$}} (2) ;
 \draw [-latex,ultra thick] (2) --  node [right] {\small{$Refinement$}} (3) ;
  \draw [-latex,ultra thick] (3) --  node [right] {\small{$Refinement$}} (4) ;
  \draw [-latex,ultra thick] (4) --  node [right] {\small{$Refinement$}} (5) ;
    \end{tikzpicture}
\end{document}

输出:

在此处输入图片描述

此后,这只是个人品味的问题(之前也可能如此:P)

答案2

这个答案并没有为之前的关于节点和箭头定位的答案增加任何内容。但是,只是为了好玩,我为最后一个节点添加了一个带有折叠边缘的形状。虽然,我不得不承认,对于只有一个弯曲边缘来说,这有点太多了。

新形状名为document。它基于 PGF 手册中的一个示例。折叠边可以位于节点的任意边上(选项document corner)。它具有与矩形节点相同的锚点,此外还有锚点north west cornernorth east cornersouth east corner和 ,south east corner以使线条和箭头一直延伸到弯曲角。(选项blocklast见下面的完整示例。)

\node [blocklast,shape=document,document corner=south east] (6) at (0,4) {\textbf{Executable Program}};
\node [blocklast,shape=document,document corner=south west] (7) at (5,4) {\textbf{Executable Program}};
\node [blocklast,shape=document,document corner=north west] (8) at (5,2) {\textbf{Executable Program}};
\node [blocklast,shape=document,document corner=north east] (9) at (0,2) {\textbf{Executable Program}};
\draw [latex-latex,thick] (6.south east corner) -- (8.north west corner);
\draw [latex-latex,thick] (7.south west corner) -- (9.north east corner);

在此处输入图片描述

折叠边缘本身也可以配置(图中的选项):

在此处输入图片描述

这样,图表看起来就像这样:

在此处输入图片描述

代码:

\documentclass{article}
\usepackage{tikz}

% the new shape, based on example in
% 101.5.3 Command for Declaring New Shapes
% on page 1039, pgf manual for version 3.0.1a
\makeatletter
% options
\tikzset{%
  document corner width/.store in=\dc@width,
  document corner height/.store in=\dc@height,
  document corner shift/.store in=\dc@shift,
  document corner bend/.store in=\dc@bend,
  document corner width=18pt,
  document corner height=6pt,
  document corner shift=3pt,
  document corner bend=2pt,
  document corner/.is choice,
  document corner/north west/.code={\def\dc@corner{0}},
  document corner/north east/.code={\def\dc@corner{1}},
  document corner/south east/.code={\def\dc@corner{2}},
  document corner/south west/.code={\def\dc@corner{3}},
  document corner=south east
}
\newdimen\pgf@xd
%\newdimen\pgf@yd
\newdimen\pgf@xe
\newdimen\pgf@ye
\pgfdeclareshape{document}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{south east}
  % anchors for corners
  \anchor{north west corner}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@x=\pgf@xa
    \pgf@xa=\dc@width\pgf@xa=0.5\pgf@xa
    \pgf@ya=\dc@height\pgf@ya=0.5\pgf@ya
    \advance\pgf@x by \pgf@xa
    \advance\pgf@y by-\pgf@ya
   }
  \anchor{north east corner}{
    \northeast
    \pgf@xa=\dc@width\pgf@xa=0.5\pgf@xa
    \pgf@ya=\dc@height\pgf@ya=0.5\pgf@ya
    \advance\pgf@x by-\pgf@xa
    \advance\pgf@y by-\pgf@ya
  }
  \anchor{south east corner}{
    \northeast
    \pgf@xa=\pgf@x
    \southwest
    \pgf@x=\pgf@xa
    \pgf@xa=\dc@width\pgf@xa=0.5\pgf@xa
    \pgf@ya=\dc@height\pgf@ya=0.5\pgf@ya
    \advance\pgf@x by-\pgf@xa
    \advance\pgf@y by \pgf@ya
  }
  \anchor{south west corner}{
    \southwest
    \pgf@xa=\dc@width\pgf@xa=0.5\pgf@xa
    \pgf@ya=\dc@height\pgf@ya=0.5\pgf@ya
    \advance\pgf@x by \pgf@xa
    \advance\pgf@y by \pgf@ya
  }

  \backgroundpath{%
    % store lower right in xa/ya and upper right in xb/yb
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \ifcase\dc@corner % north west
      % compute corner of ‘‘flipped page’’
      \pgf@xc=\pgf@xa \advance\pgf@xc by \dc@width
      \pgf@yc=\pgf@yb \advance\pgf@yc by-\dc@height
      \pgf@xd=\pgf@xc \advance\pgf@xd by-\dc@shift
      \pgf@xe=\dc@width \advance\pgf@xe by-\dc@shift \pgf@xe=0.5\pgf@xe % = (\dc@width-\dc@shift)/2
      \advance\pgf@xe by \pgf@xa
      \pgf@ye=\pgf@yc \advance\pgf@ye by \dc@bend
      % construct main path
      \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yc}}
      \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
      \pgfpathclose
      % add little corner
      \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yc}}
      \pgfpathquadraticcurveto{\pgfpoint{\pgf@xe}{\pgf@ye}}{\pgfpoint{\pgf@xa}{\pgf@yc}}
    \or % north east
      % compute corner of ‘‘flipped page’’
      \pgf@xc=\pgf@xb \advance\pgf@xc by-\dc@width
      \pgf@yc=\pgf@yb \advance\pgf@yc by-\dc@height
      \pgf@xd=\pgf@xc \advance\pgf@xd by \dc@shift
      \pgf@xe=\dc@width \advance\pgf@xe by-\dc@shift \pgf@xe=0.5\pgf@xe % = (\dc@width-\dc@shift)/2
      \advance\pgf@xe by \pgf@xd
      \pgf@ye=\pgf@yc \advance\pgf@ye by \dc@bend
      % construct main path
      \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
      \pgfpathclose
      % add little corner
      \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yc}}
      \pgfpathquadraticcurveto{\pgfpoint{\pgf@xe}{\pgf@ye}}{\pgfpoint{\pgf@xb}{\pgf@yc}}
    \or % south east
      % compute corner of ‘‘flipped page’’
      \pgf@xc=\pgf@xb \advance\pgf@xc by-\dc@width
      \pgf@yc=\pgf@ya \advance\pgf@yc by \dc@height
      \pgf@xd=\pgf@xc \advance\pgf@xd by \dc@shift
      \pgf@xe=\dc@width \advance\pgf@xe by-\dc@shift \pgf@xe=0.5\pgf@xe % = (\dc@width-\dc@shift)/2
      \advance\pgf@xe by \pgf@xd
      \pgf@ye=\pgf@yc \advance\pgf@ye by-\dc@bend
      % construct main path
      \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
      \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@ya}}
      \pgfpathclose
      % add little corner
      \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yc}}
      \pgfpathquadraticcurveto{\pgfpoint{\pgf@xe}{\pgf@ye}}{\pgfpoint{\pgf@xb}{\pgf@yc}}
    \or % south west
      % compute corner of ‘‘flipped page’’
      \pgf@xc=\pgf@xa \advance\pgf@xc by \dc@width
      \pgf@yc=\pgf@ya \advance\pgf@yc by \dc@height
      \pgf@xd=\pgf@xc \advance\pgf@xd by-\dc@shift
      \pgf@xe=\dc@width \advance\pgf@xe by-\dc@shift \pgf@xe=0.5\pgf@xe % = (\dc@width-\dc@shift)/2
      \advance\pgf@xe by \pgf@xa
      \pgf@ye=\pgf@yc \advance\pgf@ye by-\dc@bend
      % construct main path
      \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@yc}}
      \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
      \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@ya}}
      \pgfpathclose
      % add little corner
      \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@ya}}
      \pgfpathlineto{\pgfpoint{\pgf@xd}{\pgf@yc}}
      \pgfpathquadraticcurveto{\pgfpoint{\pgf@xe}{\pgf@ye}}{\pgfpoint{\pgf@xa}{\pgf@yc}}
    \fi
  }
}
\makeatother

\begin{document}
  \begin{tikzpicture}[%
    blocksize/.style={minimum height=2.8em,minimum width=12em},
    block/.style={blocksize,draw},
    blocklast/.style={blocksize,draw,thick},
    blockdots/.style={blocksize}
  ]
    \node [block]     at (0,0)      (1) {\textbf{Abstract Specification ($R_{0}$)}};
    \node [block]     at (2,-2)     (2) {\textbf{Refined Specification($R_{1}$)}};
    \node [blockdots] at (3.7,-3.7) (3) {\dots\dots\dots};
    \node [block]     at (5.4,-5.4) (4) {\textbf{Refined Specification ($R_{N}$)}};
    \node [blocklast,shape=document] at (7.4,-7.4) (5) {\textbf{Executable Program}};
    % arroows
    \draw [-latex,thick] (1) --  node [right] {\textit{\small Refinement}} (2) ;
    \draw [-latex,thick] (2) --  node [right] {\textit{\small Refinement}} (3) ;
    \draw [-latex,thick] (3) --  node [right] {\textit{\small Refinement}} (4) ;
    \draw [-latex,thick] (4) --  node [right] {\textit{\small Refinement}} (5) ;
  \end{tikzpicture}
\end{document}

答案3

变体科莱格尔答案。使用图书馆arrows.metachainspositioningquotes

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                chains,
                positioning,
                quotes}

\begin{document}
    \begin{tikzpicture}[
node distance = 8mm and -42mm,
  start chain = A going below right,
   box/.style = {draw, text width=48mm, align=center, minimum height=6mm,
                 inner sep=1mm, font=\sffamily\bfseries,
                 on chain=A},
every edge quotes/.style = {inner sep=2mm, font=\small\itshape, anchor=west}
                        ]
% nodes
\node   [box]   {Abstract Specification $(R_{0})$}; % A-1
\node   [box]   {Refined Specification  $(R_{1})$};
\node   [box, draw=none]    {\dots\dots};
\node   [box]   {Refined Specification  $(R_{N})$};
\node   [box]   {Executable Program};               % A-5
% arrows
\draw[-Stealth, semithick]
    (A-1) edge ["Refinement"] (A-2)
    (A-2) edge ["Refinement"] (A-3)
    (A-3) edge ["Refinement"] (A-4)
    (A-4)  to  ["Refinement"] (A-5);
    \end{tikzpicture}
\end{document}

可以看出,所有本地样式定义都移至tikzpicture选项中的样式定义。文本“细化”以斜体显示,而不是错误使用的数学节点(标签不是变量集合)。使用node distance可以简单地确定节点定位的斜率。有了这个并使用chainsedges代码变得更加清晰简洁。

附录: 节点之间的箭头可以在循环中绘制(并使代码稍微短一些):

% arrows
\foreach \i [remember=\i as \j (initially 1)] in {2,...,5}
\draw[-Stealth, semithick]
    (A-\j) to ["Refinement"] (A-\i);

在此处输入图片描述

相关内容