.png)
Annahmediese Antwortwurde das folgende Signalflussdiagramm durch die Darstellung der folgenden Zustandsgleichungen erstellt:
Ich möchte:
1- wissen, wie mein Code optimiert und verallgemeinert werden kann, um robuster zu sein, wenn die Anzahl der Knoten und ihre Verbindungssignale unterschiedlich sind, ohne ihn manuell bearbeiten zu müssen.
2. Machen Sie die aktuelle Ausgabe wenn möglich sauberer.
\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}
Antwort1
Dieser Beitrag beschäftigt sich nicht mit der Frage, wie man ein besseres Layout erreichen kann. Ziel ist es, den Graphen automatisch aus einer Matrix zu generieren. Sie können eine Matrix definieren über
\edef\mmat{{2,-5,3,2},{-6,-2,2,5},{1,-3,-4,7},{-4,6,9,0}}
und dann wird der Graph über foreach-Schleifen erstellt. Im Code gibt es einige Anmerkungen. Die vielleicht wichtigsten neuen Zutaten sind der pmark
Stil, der die Beschriftungen aus den Matrixeinträgen erhält, d. h. seine Argumente sind der Zeilen- und Spaltenindex, und der semicircle
Stil, der einen Halbkreis einfügt, der in Kanten verwendet werden kann.
\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}