使用 Tikz 将未对齐的块分组到容器中

使用 Tikz 将未对齐的块分组到容器中

我创建了一个框图,其中我想将块分组到两个不同的标签容器中,如下图所示。

在此处输入图片描述

我可以使用类似以下方法将左上角的四个块分组:\node (client) [draw, fit= (disp) (dec) (head) (track)] {};如所述答案,但我无法找到一种简单的方法来对不完全对齐的块进行分组。

这是一个 MWE(没有所需的分组和标签):

\documentclass[tikz,border=4mm]{standalone}
\usetikzlibrary{positioning, arrows.meta, fit, calc, shapes}  
\tikzset{  
    line/.style={-latex},   
    N/.style={draw, thick, text width=2cm, minimum height=1cm, align=center, font=\sffamily},  
    arr/.style = {draw, -{Triangle}}, 
    arr2/.style = {draw, thick, -{Triangle}},
}  
\begin{document}  
\begin{tikzpicture}[node distance = 3mm and 15mm]
\node (net) [N,rounded corners=2mm, minimum size=28mm] {Network}; 
\node (track) [N, above left=of net.south west]  {Tracking}; 
\node (head) [N, left=of track] {Head movement};  
\node (dec) [N, below left=of net.north west]  {Video decoder}; 
\node (disp) [N, left=of dec]  {Display}; 
\node (render) [N, above right=of net.south east] {Renderer};
\node (enc) [N, below right=of net.north east] {Video encoder};
%\node (client) [draw, fit= (disp) (dec) (head) (track)]  {};
\coordinate[right=of render] (aux);
\draw[arr]  
(head) edge node[above] {$x_k$} (track) 
(track) edge node[above] {$z_k$} (track -| net.west) 
(dec -| net.west) edge (dec)
(dec) edge (disp)
(enc)  edge  (enc -| net.east)
(render) -- (aux) |- (enc);
\node (update) [N, below of=net, yshift=-3.5cm]  {Measurement update};
\node (model) [N, label=$\mathrm{H_k}$, left=of update] {Measurement model};
\node (estimate) [N, label=$\mathrm{F_k}$, left=of model] {State \\ estimation $\mathrm{F_k}$};
\node (pred) [N, right=of update, xshift=0.3cm] {Prediction};
\node (lat) [text centered, below=of pred, yshift=-0.7cm]  {$t_{\mathrm{LAT}}$};
\node (updateout) [coordinate, node distance=8mm, right=of update]  {};
\node (delay) at ($(model)+(0,-1.5)$) [N]  {Delay};
\draw[arr] 
(model) edge node[above] {$\hat{z}_{k}$} (update)
(estimate) edge node[above] {$\hat{x}_{k}^-$} (model)
(net.south) edge  node [right,pos=0.5] {$z_k$} (update.north)
(update) edge node[above] {$\hat{x}_{k}^+$} (pred)
(updateout) |- node [above,pos=0.8] {} (delay)
(delay) -| node [above,pos=0.25] {$\hat{x}_{k-1}$} (estimate)
(lat.north) edge (pred.south)
(pred.north) -- node [right,pos=0.5] {$\hat{x}_{k+N}$} (render.south);
\end{tikzpicture}  
\end{document}  

答案1

自动选项fit不会用于获得这些形状的总和,您将得到的是一个包含所有位于它们之间的几何中心的节点,但示例所需的超出了拟合的可能性,至少是我所知道的,例如,边的偏移不是对称的,它必须包括箭头路径所占据的空间,因此您只需手动执行此操作,但为此它具有库calc,它将允许您找到相对于其他现有点的点($(node_name.node_specific_point)+(x_shift,y_shift)$),移动或查找直线中的重心点($(node_A)!K!(node_B)$)

附录:您还应该注意,(render)(pred)节点不会垂直对齐,因此连接它们的箭头不会是垂直的,要解决这个问题,您必须找到一个投影的正交点(pred.south|-render.south)

结果:添加了一些修改,希望它们的风格不错,并使用不透明度控制来避免一些附带损害。

在此处输入图片描述

梅威瑟:

\documentclass[tikz,border=4mm]{standalone}
\usetikzlibrary{positioning, arrows.meta, fit, calc, shapes}  
\tikzset{  
    line/.style={-latex},   
    N/.style={draw, thick, text width=2cm, minimum height=1cm, align=center, font=\sffamily},  
    arr/.style = {draw, -{Triangle}}, 
    arr2/.style = {draw, thick, -{Triangle}},
}  
\begin{document}  
    \begin{tikzpicture}[node distance = 3mm and 15mm]
    \node (net) [N,rounded corners=2mm, minimum size=28mm] {Network}; 
    \node (track) [N, above left=of net.south west]  {Tracking}; 
    \node (head) [N, left=of track] {Head movement};  
    \node (dec) [N, below left=of net.north west]  {Video decoder}; 
    \node (disp) [N, left=of dec]  {Display}; 
    \node (render) [N, above right=of net.south east] {Renderer};
    \node (enc) [N, below right=of net.north east] {Video encoder};
    \coordinate[right=of render] (aux);
    \draw[arr]  
    (head) edge node[above] {$x_k$} (track) 
    (track) edge node[above] {$z_k$} (track -| net.west) 
    (dec -| net.west) edge (dec)
    (dec) edge (disp)
    (enc)  edge  (enc -| net.east)
    (render) -- (aux) |- (enc);
    \node (update) [N, below of=net, yshift=-3.5cm]  {Measurement update};
    \node (model) [N, label=$\mathrm{H_k}$, left=of update] {Measurement model};
    \node (estimate) [N, label=$\mathrm{F_k}$, left=of model] {State \\ estimation $\mathrm{F_k}$};
    \node (pred) [N, right=of update, xshift=0.3cm] {Prediction};
    \node (lat) [text centered, below=of pred, yshift=-0.7cm]  {$t_{\mathrm{LAT}}$};
    \node (updateout) [coordinate, node distance=8mm, right=of update]  {};
    \node (delay) at ($(model)+(0,-1.5)$) [N]  {Delay};
    \draw[arr] 
    (model) edge node[above] {$\hat{z}_{k}$} (update)
    (estimate) edge node[above] {$\hat{x}_{k}^-$} (model)
    (net.south) edge  node [right,pos=0.5] {$z_k$} (update.north)
    (update) edge node[above] {$\hat{x}_{k}^+$} (pred)
    (updateout) |- node [above,pos=0.8] {} (delay)
    (delay) -| node [above,pos=0.25] {$\hat{x}_{k-1}$} (estimate)
    (lat.north) edge (pred.south)
    (pred.north) -- node [right,pos=0.5] {$\hat{x}_{k+N}$} (pred.south|-render.south); % Give a point straight from pred.south in Renderer node.
    %Structure using a single \draw instruction...
    \draw[blue!50!cyan,dashed,fill,fill opacity=0.05,text opacity=1]%Get points using calc lib
    ($(disp.north west)+(-4pt,+5pt)$)
        rectangle ($(track.south east)+(15pt,-3pt)$)
    ($(head)!0.5!(track)$)++(0,-25pt)
        node[N,blue!50!cyan,draw=none]{Client}
    ($(estimate.north west)+(-5pt,+15pt)$) coordinate (temp1)
        -| ($(enc.north west)+(-10pt,+5pt)$) coordinate (temp2)
        -| ($(pred.south east)+(+50pt,-50pt)$)
        -| cycle
    ($(temp1)!0.5!(temp1-|temp2)$)++(0,6pt)
        node[N,blue!50!cyan,draw=none]{Server};
    \end{tikzpicture}  
\end{document}

相关内容