Hola amantes de los gráficos tex :) Estoy intentando dibujar un diagrama en TikZ lo más parecido posible a este:
Estoy usando la biblioteca dsp TikZ y creo que mi intento va en la dirección correcta; sin embargo, hay algunas cosas que no logré configurar correctamente, como puede ver en el MWE
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{dsp,chains}
\begin{document}
\begin{tikzpicture}
% Blocks and nodes
\node[dspnodeopen,dsp/label=below] (ns) {$v(t)$};
\node[dspmultiplier,left=of ns,fill=gray] (mic) {};
\node[dspadder,left=of mic,left=1.5cm] (add) {};
\node[coordinate,left=of add,left=2.35cm] (fp1) {};
\node[dspfilter,above=of fp1,above=1.5cm] (gain) {$G$};
\node[coordinate,above=of gain,above=1.5cm] (fp2) {};
\node[dspnodefull,right=of fp2,right=2.55cm] (adnode) {$u(t)$};
\node[dspfilter,right=of gain,right=1.15cm] (adfilt) {$\hat{F}$};
\node[dspsquare,right=of fp2,right=4cm] (ls) {};
\node[dspfilter,right=of gain,right=4cm] (feedback) {F};
\node[dspnodefull,left=of add] (afupd1) {};
\node[coordinate,above=of afupd1,above=1cm] (afupd2) {};
\node[coordinate,right=of adfilt,above=3.5cm,right=0.5cm] (afupd3) {};
% Connections
\draw[dspconn] (ns) -- (mic);
\draw[dspline] (mic) -- node[midway,below=0.09cm] {$y(t)$} (add);
\draw[dspline] (add) -- node[midway,below] {$d[t,\hat{\mathbf{f}}(t)]$} (fp1);
\draw[dspline,dashed] (afupd1) -- (afupd2);
\draw[dspconn,dashed] (afupd2) -- (afupd3);
\draw[dspconn] (fp1) -- (gain);
\draw[dspline] (gain) -- (fp2);
\draw[dspline] (fp2) -- (adnode);
\draw[dspline] (adnode) -- (ls);
\draw[dspconn] (adnode) -- (adfilt);
\draw[dspconn] (adfilt) -- node[midway,right] {$\hat{y}[t |\hat{\mathbf{f}}(t)]$} (add);
\draw[dspconn] (ls) -- (feedback);
\draw[dspconn] (feedback) -- (mic);
\end{tikzpicture}
\end{document}
Así es como se ve mi MWE:
Es decir, las cosas que no pude recrear correctamente son:
- los símbolos del micrófono y el altavoz (esos bloques grises)
- la alineación vertical de los bloques de filtro
- la posición correcta de la línea oblicua discontinua (debe cortar el bloque con \hat{F} justo en el medio)
- líneas curvas hacia y desde el bloque de filtro con F
- signos más y menos en el sumador.
¿Alguien está dispuesto a ayudar a este pobre usuario de TikZ?
Gracias ;)
Respuesta1
Una posibilidad:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{dsp,chains,calc,shapes.geometric}
\begin{document}
\begin{tikzpicture}
% Blocks and nodes
\node[dspnodeopen,dsp/label=below]
(ns) {$v(t)$};
\node[left=of ns,fill=gray,circle,draw]
(mic) {};
\draw ([yshift=8pt]mic.east) -- ([yshift=-8pt]mic.east);
\node[dspadder,left=of mic,left=1.5cm,label={above right:$-$},label={below right:$+$}]
(add) {};
\node[coordinate,left=of add,left=2.35cm]
(fp1) {};
\node[dspfilter,minimum height=2cm,above=of fp1,above=1.5cm]
(gain) {$G$};
\node[coordinate,above=of gain,above=1.5cm]
(fp2) {};
\node[dspnodefull,right=of fp2,right=2.55cm]
(adnode) {$u(t)$};
\node[dspfilter,minimum height=2cm,right=of gain,right=1.15cm]
(adfilt) {$\hat{F}$};
\node[draw,right= 4cm of fp2,fill=gray,trapezium,shape border rotate=90,shape border uses incircle]
(ls) {};
\draw ([yshift=-10pt]ls.west) -- ([yshift=10pt]ls.west);
\node[dspfilter,minimum height=2cm,right=of gain,right=4cm]
(feedback) {F};
\node[dspnodefull,left=of add]
(afupd1) {};
\node[coordinate,above=of afupd1,above=1cm]
(afupd2) {};
\coordinate (aux) at ([yshift=-4pt]adfilt.center);
% Connections
\draw[dspconn] (ns) -- (mic);
\draw[dspconn] (mic) -- node[midway,below=0.09cm] {$y(t)$} (add);
\draw[dspline] (add) -- node[midway,below] {$d[t,\hat{\mathbf{f}}(t)]$} (fp1);
\draw[dspline,dashed] (afupd1) -- (afupd2);
\draw[dspconn,dashed] (afupd2) -- ( $ (afupd2)!2.7cm!(aux) $ );
\draw[dspconn] (fp1) -- (gain);
\draw[dspline] (gain) -- (fp2);
\draw[dspline] (fp2) -- (adnode);
\draw[dspconn] (adnode) -- (ls);
\draw[dspconn] (adnode) -- (adfilt);
\draw[dspconn] (adfilt) -- node[midway,right] {$\hat{y}[t |\hat{\mathbf{f}}(t)]$} (add);
\draw[dspconn] (ls) to[out=0,in=90] (feedback);
\draw[dspconn] (feedback) to[out=-90,in=30] ([yshift=3pt]mic.east);
\end{tikzpicture}
\end{document}
Las respuestas a preguntas específicas:
Utilice formas estándar de TikZ. El altavoz, por ejemplo, simplemente se ha sacado
trapezium
de lashapes.geometric
biblioteca.No hay necesidad de ajustes adicionales. Puede utilizar la
minimum height
clave estándar para losdspfilter
nodos.Coloqué una coordenada auxiliar en
adfilt.center
(ligeramente desplazada hacia abajo para evitar que la línea se superponga a la "F") y luego usé la( $ (<name1>)!<length>!(<name2>) $ )
de la biblioteca de cálculo.Puedes usar
to[out=<angle1>,in=<angle2>]
.Coloqué las etiquetas deseadas en el
add
nodo.
En un comentario se mencionó algún problema con las etiquetas cortadas al incluir la figura desde un archivo externo. En este caso, le sugiero que use la standalone
clase para producir su imagen como un archivo pdf separado que luego puede incluirse fácilmente en su documento usando el \includegraphics
mecanismo estándar de graphicx
; Puedes usar la border
opción independiente para controlar el relleno alrededor de tu figura, en caso de que sea necesario:
Por ejemplo, guarde lo siguiente como, por ejemplo MyImage.tex
:
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{dsp,chains,calc,shapes.geometric}
\begin{document}
\begin{tikzpicture}
% Blocks and nodes
\node[dspnodeopen,dsp/label=below]
(ns) {$v(t)$};
\node[left=of ns,fill=gray,circle,draw]
(mic) {};
\draw ([yshift=8pt]mic.east) -- ([yshift=-8pt]mic.east);
\node[dspadder,left=of mic,left=1.5cm,label={above right:$-$},label={below right:$+$}]
(add) {};
\node[coordinate,left=of add,left=2.35cm]
(fp1) {};
\node[dspfilter,minimum height=2cm,above=of fp1,above=1.5cm]
(gain) {$G$};
\node[coordinate,above=of gain,above=1.5cm]
(fp2) {};
\node[dspnodefull,right=of fp2,right=2.55cm]
(adnode) {$u(t)$};
\node[dspfilter,minimum height=2cm,right=of gain,right=1.15cm]
(adfilt) {$\hat{F}$};
\node[draw,right= 4cm of fp2,fill=gray,trapezium,shape border rotate=90,shape border uses incircle]
(ls) {};
\draw ([yshift=-10pt]ls.west) -- ([yshift=10pt]ls.west);
\node[dspfilter,minimum height=2cm,right=of gain,right=4cm]
(feedback) {F};
\node[dspnodefull,left=of add]
(afupd1) {};
\node[coordinate,above=of afupd1,above=1cm]
(afupd2) {};
\coordinate (aux) at ([yshift=-4pt]adfilt.center);
% Connections
\draw[dspconn] (ns) -- (mic);
\draw[dspconn] (mic) -- node[midway,below=0.09cm] {$y(t)$} (add);
\draw[dspline] (add) -- node[midway,below] {$d[t,\hat{\mathbf{f}}(t)]$} (fp1);
\draw[dspline,dashed] (afupd1) -- (afupd2);
\draw[dspconn,dashed] (afupd2) -- ( $ (afupd2)!2.7cm!(aux) $ );
\draw[dspconn] (fp1) -- (gain);
\draw[dspline] (gain) -- (fp2);
\draw[dspline] (fp2) -- (adnode);
\draw[dspconn] (adnode) -- (ls);
\draw[dspconn] (adnode) -- (adfilt);
\draw[dspconn] (adfilt) -- node[midway,right] {$\hat{y}[t |\hat{\mathbf{f}}(t)]$} (add);
\draw[dspconn] (ls) to[out=0,in=90] (feedback);
\draw[dspconn] (feedback) to[out=-90,in=30] ([yshift=3pt]mic.east);
\end{tikzpicture}
\end{document}
Después de procesarlo, pdflatex
obtendrá un MyImage.pdf
archivo con el siguiente aspecto (el área gris alrededor de la figura no forma parte del pdf resultante):
Entonces puedes usar
\usepackage{graphicx}% in preamble
\includegraphics{MyImage}% in document body
en su .tex
archivo para incluir la imagen. Puede controlar los márgenes individuales con la boder
tecla (consulte la documentación independiente).
Respuesta2
Tomé el código de Gonzalo y lo modifiqué para resolver la pregunta 2 (el tamaño de los filtros).
La dsp
biblioteca contiene un comando \dspfilterwidth
que establece el ancho de los bloques de filtro (por eso parecen funcionar mal con minimum width
y minimum height
, al menos en mis pruebas).
Así que comencé haciendo algo un poco más adaptable y extendiendo el dspfilter
estilo para obtener una altura particular para los filtros:
\renewcommand{\dspfilterwidth}{8mm}
\newcommand{\dspfilterheight}{1.8cm}
\tikzset{dspfilter/.append style = {minimum height=\dspfilterheight}}
Desafortunadamente, esto estropea el espaciado de muchos de los bloques, así que revisé el código del nodo y modifiqué algunos para que los bloques se alinearan, incluso si eliges constantes diferentes.
También agregué símbolos del modo matemático al filtro más a la derecha: debería ser $F$
en lugar de simple F
si desea que coincida con el diagrama original.
Aquí está mi código modificado:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{dsp,chains,calc,shapes.geometric}
\begin{document}
\begin{tikzpicture}
\renewcommand{\dspfilterwidth}{8mm}
\newcommand{\dspfilterheight}{1.8cm}
\tikzset{dspfilter/.append style = {minimum height=\dspfilterheight}}
\newcommand{\dspvspace}{1.2cm}
% Blocks and nodes
\node[dspnodeopen, dsp/label=below]
(ns) {$v(t)$};
\node[left=of ns, fill=gray, circle, draw]
(mic) {};
\draw ([yshift=8pt] mic.east) -- ([yshift=-8pt] mic.east);
\node[dspadder, left=of mic, left=2.35cm, label={above right:$-$}, label={below right:$+$}]
(add) {};
\node[coordinate, left=of add, left=1.8cm]
(fp1) {};
\node[dspfilter, above=of fp1, above=\dspvspace]
(gain) {$G$};
\node[coordinate, above=of gain, above=\dspvspace]
(fp2) {$fp2$};
\node[dspnodefull, above=of add, above=2*\dspvspace+\dspfilterheight-0.5*\dspoperatordiameter-\dspblocklinewidth]
(adnode) {$u(t)$};
\node[dspfilter, above=of add, above=\dspvspace-0.5*\dspoperatordiameter]
(adfilt) {$\hat{F}$};
\node[draw, above=of mic, above=2*\dspvspace+\dspfilterheight-\dspblocklinewidth-0.4cm, fill=gray, trapezium, shape border rotate=90, shape border uses incircle]
(ls) {};
\draw ([yshift=-10pt] ls.west) -- ([yshift=10pt] ls.west);
\node[dspfilter, above=of ns, above=\dspvspace]
(feedback) {$F$};
\node[dspnodefull, left=of add, left=0.8cm]
(afupd1) {};
\node[coordinate, above=of afupd1, above=\dspvspace]
(afupd2) {};
\coordinate (aux) at (adfilt.center);
% Connections
\draw[dspconn] (ns) -- (mic);
\draw[dspconn] (mic) -- node[midway,below=0.09cm] {$y(t)$} (add);
\draw[dspline] (add) -- node[midway,below] {$d[t,\hat{\mathbf{f}}(t)]$} (fp1);
\draw[dspline,dashed] (afupd1) -- (afupd2);
\draw[dspconn,dashed] (afupd2) -- ( $ (afupd2)!3cm!(aux) $ );
\draw[dspconn] (fp1) -- (gain);
\draw[dspline] (gain) -- (fp2);
\draw[dspline] (fp2) -- (adnode);
\draw[dspconn] (adnode) -- (ls);
\draw[dspconn] (adnode) -- (adfilt);
\draw[dspconn] (adfilt) -- node[midway,right] {$\hat{y}[t |\hat{\mathbf{f}}(t)]$} (add);
\draw[dspconn] (ls) to[out=0,in=90] (feedback);
\draw[dspconn] (feedback) to[out=-90,in=30] ([yshift=3pt]mic.east);
\end{tikzpicture}
\end{document}
y esto es lo que produce: