采用这个答案,通过表示以下一组状态方程,创建了以下信号流图:
我想:
1-知道当节点数量及其连接信号不同时,如何优化和推广我的代码以使其更加稳健,而无需手动编辑它。
2-如果可能的话,使当前输出更清洁。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,positioning,arrows.meta}
\newif\iflabrev
\begin{document}
\begin{tikzpicture}
[
relative = false,
node distance = 15 mm,
label revd/.is if=labrev,
%label revd/.default=true,
amark/.style = {
decoration={
markings,
mark=at position {0.5} with {
\arrow{stealth},
\iflabrev \node[below] {#1};\else \node[above] {#1};\fi
}
},
postaction={decorate}
},
terminal/.style 2 args={draw,circle,inner sep=2pt,label={#1:#2}},
]
%
%Place the nodes
\node[terminal={left}{$R(S)$}] (a) at (0,0) {};
\node[terminal={below right}{$sX_3(s)$}] (b) [right=of a] {};
\node[terminal={below right}{$X_3(S)$}] (c) [right=of b] {};
\node[terminal={[xshift=-4mm]below right}{$sX_2(s)$}] (d) [right=of c] {};
\node[terminal={[xshift=-4mm]below right}{$X_2(s)$}] (e) [right=of d] {};
\node[terminal={[xshift=-4mm]below right}{$sX_1(s)$}] (f) [right=of e] {};
\node[terminal={[xshift=-4mm]below right}{$X_1(s)$}] (g) [right=of f] {};
\node[terminal={right}{$Y(s)$}] (h) [right=of g] {};
%
%Draw the connections
\foreach \target/\bend/\text/\loose in {b/0/7/0, d/90/5/1.5, f/90/2/1.5}
\draw[amark=\text] (a) to[bend left=\bend,looseness=\loose] (\target);
\draw[amark=1/s] (b) to (c);
\foreach \source/\text/\loose in {c/-4/2, e/-3/1.5, g/1/1.5}
\draw[amark=\text] (\source) to[bend left=90, looseness=\loose] (b);
\foreach \target/\text/\loose in { d/-6/1.5, f/2/2}
\draw[amark=\text] (g) to[bend left=90, looseness=\loose] (\target);
\foreach \source/\text in {c/9, e/6}
\draw[amark=\text] (\source) to[bend left=90, looseness=1.5] (h);
\draw[amark=2] (c) to (d);
\draw[amark=3] (c) to[bend right=90, looseness=1.5] (f);
\draw[amark=1/s] (d) to (e);
\draw[amark=-5] (e) to (f);
\draw[amark=-2,label revd] (e) to[bend left=90, looseness=2] (d);
\draw[amark=1/s] (f) to (g);
\draw[amark=-4] (g) to (h);
\end{tikzpicture}
\end{document}
答案1
这篇文章不解决如何实现更好的布局的问题。目的是自动从矩阵生成图形。您可以通过以下方式定义矩阵
\edef\mmat{{2,-5,3,2},{-6,-2,2,5},{1,-3,-4,7},{-4,6,9,0}}
然后通过 foreach 循环创建图形。代码中有一些注释。也许最重要的新元素是pmark
从矩阵条目获取标签的样式,即其参数是行和列索引,以及semicircle
插入可用于边缘的半圆的样式。
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,decorations.markings,positioning,arrows.meta}
\newif\iflabrev
\begin{document}
\begin{tikzpicture}[node distance = 15 mm,
label revd/.is if=labrev,
label revd/.default=true,
amark/.style = {
decoration={
markings,
mark=at position {0.5} with {
\arrow{stealth},
\iflabrev \node[below] {#1};\else \node[above] {#1};\fi
}
},
postaction={decorate}
}, % make the mark an entry of the \mmat matrix
pmark/.style n args={2}{amark={$%
\pgfmathparse{int({\mmat}[\numexpr#1][\numexpr#2])}%
\pgfmathresult$}},
terminal/.style 2 args={draw,alias=ln,circle,inner sep=2pt,label={#1:#2}},
% semicircle path
semicircle/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$)
in \ifdim\x1>0pt
(\tikztostart.north) arc[start angle=180,end angle=0,radius=0.5*\x1]
\else
(\tikztostart.south) arc[start angle=0,end angle=-180,radius=-0.5*\x1]
\fi}}
]
% define the matrix
\edef\mmat{{2,-5,3,2},{-6,-2,2,5},{1,-3,-4,7},{-4,6,9,0}}
\pgfmathtruncatemacro{\dimy}{dim({\mmat})} % number of rows
\pgfmathtruncatemacro{\dimx}{dim({\mmat}[0])} % number of columns
% create the graph
\path % R node
node[terminal={left}{$R(S)$},alias={X-\dimy}] (R) {}
% loop over matrix entries
foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
in {1,...,\numexpr\dimy-1}
{node[right=of ln,terminal={below right}{% sX_i node
$sX_{\X}(s)$}](sX-\X){}
node[right=of ln,terminal={below right}{% X_i node
$X_{\X}(s)$}](X-\X){}
% ege from sX_i to X_i
(sX-\X) edge[amark={$\frac{1}{s}$}] (X-\X)
% edge from X_{i+1} to X_i (R had an alias)
(X-\the\numexpr\X+1) edge[pmark={\X-1}{\X}] (sX-\X)
% semicircle edge from X_i to sX_i
(X-\X) edge[semicircle,label revd,pmark={\X-1}{\X-1}] (sX-\X)
% various semicircles
\ifnum\Y>1
(R) edge[semicircle,pmark={\X-1}{\dimx-1}] (sX-\X)
foreach \Z in {1,...,\numexpr\Y-1} {
(X-\X) edge[semicircle,pmark={\X+\Z-1}{\X-1}] (sX-\the\numexpr\X+\Z)
}
\fi
}% the Y node
node[right=of ln,terminal={right}{$Y(s)$}](Y){}
(X-1) edge[pmark={\dimy-1}{0}] (Y)
% semicircles goint to Y
foreach \Y [evaluate=\Y as \X using {int(\dimy-\Y)}]
in {1,...,\numexpr\dimy-2}
{(X-\X) edge[semicircle,pmark={\dimy-1}{\X-1}] (Y)};
\end{tikzpicture}
\end{document}