Привет любителям графического текса :) Пытаюсь нарисовать в TikZ схему, максимально похожую на эту:
Я использую библиотеку dsp TikZ и думаю, что мои усилия движутся в правильном направлении; однако есть несколько вещей, которые мне не удалось настроить должным образом, как вы можете видеть из 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}
Вот как выглядит мой MWE:
А именно, вот что я не смог должным образом воссоздать:
- символы микрофона и громкоговорителя (серые блоки)
- вертикальное выравнивание фильтрующих блоков
- правильное расположение пунктирной косой линии (она должна перерезать блок с \hat{F} прямо посередине)
- изогнутые линии к блоку фильтра и от него с F
- знаки плюс и минус в сумматоре.
Кто-нибудь готов помочь этому бедному пользователю TikZ?
Спасибо ;)
решение1
Одна из возможностей:
\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}
Ответы на конкретные вопросы:
Используйте стандартные формы TikZ. Например, динамик — это просто повернутый объект
trapezium
изshapes.geometric
библиотеки.Не нужно никаких дополнительных настроек. Можно использовать стандартный
minimum height
ключ дляdspfilter
узлов.Я поместил вспомогательную координату в
adfilt.center
(слегка сместив ее вниз, чтобы линия не перекрывала «F»), а затем использовал ее( $ (<name1>)!<length>!(<name2>) $ )
из библиотеки calc.Вы можете использовать
to[out=<angle1>,in=<angle2>]
.Я разместил нужные метки на
add
узле.
В комментарии упоминалась некоторая проблема с вырезанными метками при включении рисунка из внешнего файла. В этом случае я бы предложил вам использовать класс standalone
для создания вашего изображения в виде отдельного файла PDF, который затем можно легко включить в ваш документ с помощью стандартного \includegraphics
механизма из graphicx
; вы можете использовать border
опцию standalone для управления отступами вокруг вашего рисунка, если это необходимо:
Например, сохраните следующее как, скажем, 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}
После обработки pdflatex
вы получите MyImage.pdf
файл, выглядящий следующим образом (серая область вокруг рисунка не является частью результирующего PDF-файла):
Тогда вы можете использовать
\usepackage{graphicx}% in preamble
\includegraphics{MyImage}% in document body
в вашем .tex
файле, чтобы включить изображение. Вы можете управлять отдельными полями с помощью boder
клавиши (см. автономную документацию).
решение2
Я взял код Гонсало и подправил его, чтобы решить вопрос 2 (размер фильтров).
Библиотека dsp
содержит команду \dspfilterwidth
, которая задает ширину блоков фильтров (именно поэтому они, похоже, плохо работают с minimum width
и minimum height
, по крайней мере, в моем тестировании).
Поэтому я начал с того, что сделал это немного более удобным и расширил стиль dspfilter
, чтобы получить определенную высоту для фильтров:
\renewcommand{\dspfilterwidth}{8mm}
\newcommand{\dspfilterheight}{1.8cm}
\tikzset{dspfilter/.append style = {minimum height=\dspfilterheight}}
К сожалению, это портит расстояние между многими блоками, поэтому я просмотрел код узла и немного подправил его так, чтобы блоки выстраивались в линию, даже если вы сами выбираете другие константы.
Я также добавил символы математического режима в самый правый фильтр: они должны быть $F$
не обычными, F
если вы хотите, чтобы они соответствовали исходной диаграмме.
Вот мой измененный код:
\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}
и вот что он выдает: