
Я хочу сделать диаграмму flowcart с циклом while и некоторыми действиями внутри него. Я написал следующий код latex:
\documentclass[12pt, a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
chains,
positioning,
quotes,
shapes.geometric,
shapes.multipart,
babel
}
\oddsidemargin=-15.4mm
\textwidth=190mm
\headheight=-32.4mm
\textheight=277mm
\tolerance=100
\parindent=0pt
\parskip=8pt
\pagestyle{empty}
\makeatletter
\tikzset{FlowChart/.style={ % <--- corrected, new
base/.style = {draw,
minimum width=3cm, minimum height=1cm, align=center,
outer sep=0pt,
on chain, join=by arrow},
startstop/.style = {base, rounded corners, fill=blue!30},
process/.style = {base, fill=orange!30},
decision/.style = {base, diamond, aspect=1.3, fill=green!30},
io/.style = {base, trapezium, trapezium stretches body,
trapezium left angle=70, trapezium right angle=110,
fill=red!30,
text width =\pgfkeysvalueof{/pgf/minimum width} - 2*\pgfkeysvalueof{/pgf/inner xsep}
},
loop/.style = {base, rectangle split, rectangle split parts=2,
fill=gray!50},
arrow/.style = {thick,-Triangle},
% suspend
suspend join/.code={\def\tikz@after@path{}}
}
}% end of tikzset
\makeatother
\begin{document}
{\textbf{Задача 2.}}
\\
Схема алгоритма:
\\
\begin{center}
\begin{tikzpicture}[FlowChart,
node distance = 1cm and 3cm,
start chain = A going below
]
\node (start) [startstop] {Start};
\node (input) [io] {Input n};
\node (for) [loop]{
\nodepart{one} for i = 1; i<len(n); i++
\nodepart{two} Output n[i].
};
\node (stop) [startstop, below of=for] {End of programm};
\end{tikzpicture}
\end{center}
\end{document}
На данный момент я получаю это:
Как мне поместить "выходной узел" внутрь узла цикла for? Кроме того, для другой программы мне нужно поместить целый узел решения в цикл for. Это вообще возможно?
решение1
второй (чуть более сложный) пример:
\documentclass[12pt, a4paper]{article}
\usepackage[russian]{babel}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
chains,
fit, % new
positioning,
quotes,
shapes.geometric,
shapes.multipart,
babel
}
\usepackage[margin=10mm]{geometry}
\tolerance=100
\parindent=0pt
\parskip=8pt
\pagestyle{empty}
\makeatletter
\tikzset{FlowChart/.style={
base/.style = {draw,
minimum width=3cm, minimum height=1cm, align=center,
outer sep=0pt},
startstop/.style = {base, rounded corners, fill=blue!30},
process/.style = {base, fill=orange!30},
decision/.style = {base, diamond, aspect=1.3, fill=green!30},
FIT/.style = {base, semithick, inner sep=3mm, fit=##1}, % new
io/.style = {base, trapezium, trapezium stretches body,
trapezium left angle=70, trapezium right angle=110,
fill=red!30,
text width =\pgfkeysvalueof{/pgf/minimum width} - 2*\pgfkeysvalueof{/pgf/inner xsep}
},
loop/.style = {base, rectangle split, rectangle split parts=2,
fill=gray!50},
arrow/.style = {thick,-Triangle},
% suspend
suspend join/.code={\def\tikz@after@path{}}
}
}% end of tikzset
\makeatother
\begin{document}
\begin{center}
\begin{tikzpicture}[FlowChart,
node distance = 5mm and 7mm,
start chain = going below
]
\node (d1) [decision] {$n>0$};
\node (d2) [process,
below right=of d1.south] {n=n+1};
\coordinate[below=of d1 |- d2.south] (aux1);
\node (d3) [io,
below=of aux1] {output};
%
\draw (d1) -| node[pos=0.25,above] {Yes} (d2) |- (aux1)
(d1.west) -- node[pos=0.25,above] {No} ++
(-1,0) coordinate (aux2) |- (aux1);
\draw[arrow] (aux1) -- (d3);
% fit
\node (f1) [FIT=(d1) (aux2) (d2) (d3)] {};
\node (f2) [FIT=(f1.north west) (f1.north east),
inner sep=0pt,
above=0pt of f1]
{for $j=1$; $j<\mathrm{len}(r)$; $j+1$};
\end{tikzpicture}
\end{center}
\end{document}
Примечание:
- для этого изображения я меняю
FlowChart
стиль. Соответственно, он теперь исправлен/адаптирован к этой новой версии. Смотрите ваш предыдущий вопрос. - первый эскиз вы можете нарисовать так же, как указано выше. Главное отличие в том, что он содержит только один узел (
io
)
Приложение:
Предполагая, что у вас есть только одно такое составное изображение, вы можете начать рисовать с его композиции и к ней добавлять узлы выше узла f2
и ниже f1
. Для этого необходимо заменить старый стиль
arrow/.style = {thick,-Triangle},
с двумя новыми, у которых стрелки направлены в противоположные стороны:
arr/.style = {thick,-Triangle},
arl/.style = {thick,Triangle-},
Полная МВЭ:
\documentclass[12pt, a4paper]{article}
\usepackage[russian]{babel}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
chains,
fit, % new
positioning,
quotes,
shapes.geometric,
shapes.multipart,
babel
}
\usepackage[margin=10mm]{geometry}
\tolerance=100
\parindent=0pt
\parskip=8pt
\pagestyle{empty}
\makeatletter
\tikzset{FlowChart/.style={
base/.style = {draw,
minimum width=3cm, minimum height=1cm, align=center,
outer sep=0pt},
startstop/.style = {base, rounded corners, fill=blue!30},
process/.style = {base, fill=orange!30},
decision/.style = {base, diamond, aspect=1.3, fill=green!30},
FIT/.style = {base, semithick, inner sep=3mm, fit=##1}, % new
io/.style = {base, trapezium, trapezium stretches body,
trapezium left angle=70, trapezium right angle=110,
fill=red!30,
text width =\pgfkeysvalueof{/pgf/minimum width} - 2*\pgfkeysvalueof{/pgf/inner xsep}
},
loop/.style = {base, rectangle split, rectangle split parts=2,
fill=gray!50},
arr/.style = {thick,-Triangle},
arl/.style = {thick,Triangle-},
% suspend
suspend join/.code={\def\tikz@after@path{}}
}
}% end of tikzset
\makeatother
\begin{document}
\begin{center}
\begin{tikzpicture}[FlowChart,
node distance = 5mm and 13mm,
start chain = A going above,
start chain = B going below
]
% nodes in node
\node (d1) [decision] {$n>0$};
\node (d2) [process,
below right=of d1.south] {n=n+1};
\coordinate[below=of d1 |- d2.south] (aux1);
\node (d3) [io,
below=of aux1] {output};
%
\draw (d1) -| node[pos=0.25,above] {Yes} (d2) |- (aux1)
(d1.west) -- node[pos=0.25,above] {No} ++
(-1,0) coordinate (aux2) |- (aux1);
\draw[arr] (aux1) -- (d3);
% fit
\begin{scope}[nodes={on chain=B, join= by arr}]
\node (f1) [FIT=(d1) (aux2) (d2) (d3)] {};
% nodes below f1
\node (output) [io,
below=of f1] {Вывод pow};
\node (stop) [startstop] {Конец программы};
\end{scope}
\begin{scope}[nodes={on chain=A, join= by arl}]
\node (f2) [FIT=(f1.north west) (f1.north east),
inner sep=0pt,
above=0pt of f1]
{for $j=1$; $j<\mathrm{len}(r)$; $j+1$};
% nodes above f2
\node (ds1) [decision,
above=of f2] {$n = 0?$};
\node (input) [io] {Ввод n};
\node (start) [startstop] {Начало};
\end{scope}
\node (y-case) [process,right=of ds1] {pow = 1};
%
\draw[arr] (ds1) to ["Yes"] (y-case);
\draw[arr] (y-case) |- (f2);
\draw[arr] (ds1.west) to [pos=0.2, "No" '] ++ (-3,0) |- (f2); % new
\end{tikzpicture}
\end{center}
\end{document}
Конечно, выше представлен только один из возможных способов решения вашей проблемы. Один из других может быть таким, что вы рисуете изображение для внутреннего узла отдельно, сохраняете его в каком-то \savebox
и используете в выбранном узле как \node [...] {\usebox{˙<\saveboxname>}
. Для показа этого варианта мне нужно немного больше свободного времени.