.png)
Adoptandoesta respuesta, se ha creado el siguiente diagrama de flujo de señales representando el siguiente conjunto de ecuaciones de estado:
Me gustaría:
1- saber cómo se puede optimizar y generalizar mi código para que sea más robusto cuando la cantidad de nodos y sus señales de conexión difieren sin tener que editarlo manualmente.
2- haga que la salida actual sea más limpia si es posible.
\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}
Respuesta1
Esta publicación no aborda la cuestión de lograr un mejor diseño. El propósito es generar el gráfico a partir de una matriz automáticamente. Puede definir una matriz mediante
\edef\mmat{{2,-5,3,2},{-6,-2,2,5},{1,-3,-4,7},{-4,6,9,0}}
y luego el gráfico se crea mediante bucles foreach. Hay algunas anotaciones en el código. Los nuevos ingredientes quizás más importantes son el pmark
estilo que obtiene las etiquetas de las entradas de la matriz, es decir, sus argumentos son el índice de fila y columna, y el semicircle
estilo que inserta un semicírculo que puede usarse en los bordes.
\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}