Вот изображение, которое выдает мой существующий код: Я надеюсь, что FFFFF ромба может быть прямо над C и прямо справа от E. Как мне это сделать? Ниже мой минимальный рабочий случай:
\documentclass[tikz,border=2pt]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes,snakes}
\usepackage{siunitx} %SI单位
%\usepackage{xparse}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[rectangle,draw, very thick, minimum size=10mm] (A) {
A};
\node[rectangle,draw, very thick, minimum size=10mm] (B) [below=of A]{B};
\node[rectangle,draw=red, very thick, minimum size=10mm] (C) [right=of B]{C};
\node[rectangle,draw, very thick, minimum size=10mm] (D) [right=of C]{D};
\node[rectangle,draw, very thick, minimum size=10mm] (E) [above=of D] {E};
\node[diamond,draw, very thick, minimum size=10mm] (F) [above=of C] {FFFFFfF};
%Lines
\draw[->] (A) -> (B);
\draw[->] (B) -> (C);
\draw[->] (C) -> (D);
\draw[->] (D) -> (E);
\draw[->] (E) -> (F);
\draw[->] (F) -> (C);
\end{tikzpicture}
\end{document}
И то, что я в итоге надеюсь получить, это вот это, то есть мне нужно добавить очень большую пунктирную рамку. Как это реализовать?
решение1
Вам нужна опция on grid=true
, которая будет использовать центры узлов (вместо их границ) для позиционирования. Но тогда вам нужно будет увеличить node distance
.
Для пунктирной рамки я предлагаю использовать fit
библиотеку.
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes,snakes}
\usepackage{siunitx} %SI单位
%\usepackage{xparse}
\usetikzlibrary{positioning, fit}
\begin{document}
\begin{tikzpicture}[on grid=true, node distance=3cm]
\node[rectangle,draw, very thick, minimum size=10mm] (A) {
A};
\node[rectangle,draw, very thick, minimum size=10mm] (B) [below=of A]{B};
\node[rectangle,draw=red, very thick, minimum size=10mm] (C) [right=of B]{C};
\node[rectangle,draw, very thick, minimum size=10mm] (D) [right=of C]{D};
\node[rectangle,draw, very thick, minimum size=10mm] (E) [above=of D] {E};
\node[diamond,draw, very thick, minimum size=10mm] (F) [above=of C] {FFFFFfF};
%Lines
\draw[->] (A) -> (B);
\draw[->] (B) -> (C);
\draw[->] (C) -> (D);
\draw[->] (D) -> (E);
\draw[->] (E) -> (F);
\draw[->] (F) -> (C);
\node[draw, dashed, fit = {(B)(D)}, text height=2cm]{for $i=1,2,\dots,N$};
\end{tikzpicture}
\end{document}
решение2
- Сначала вы можете определить стиль узлов и ребер в
tikzpicture
параметрах, а затем написать короткий код изображения. - Пунктирный прямоугольник нарисован как узел, который охватывает узлы B ... D:
\documentclass[border=3.141592]{standalone}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, % new
fit, % new
positioning,
shapes}
\begin{document}
\begin{tikzpicture}[% nodes, edges styles
node distance = 10mm and 10mm,
D/.style = {diamond, aspect=1.3,
inner xsep=0mm, draw, thick},
F/.style = {draw, dashed, inner ysep=3ex, yshift=-1ex,
fit=#1},
N/.style = {draw=#1, thick, minimum size=10mm},
N/.default = black,
every edge/.append style = {draw, -Straight Barb}
]
\node (A) [N] {A};
\node (B) [N, below=of A] {B};
\node (C) [N=red,
right=of B] {C};
\node (D) [N, right=of C] {D};
\node (E) [N, above=of D] {E};
\path (E) -- node (F) [D] {FFFFFfF} (A); % <---
% dashed rectangle
\node[F=(B) (D),
label={[anchor=south]below:{for $i=1,2,\dotsc,N$}}] {};
% arrows
\draw (A) edge (B)
(B) edge (C)
(C) edge (D)
(D) edge (E)
(E) edge (F)
(F) edge (C);
\end{tikzpicture}
\end{document}
решение3
Вы можете разместить узел F вПерекрестоквертикальной линии, проходящей через C
и горизонтальной линии, проходящей через A
или E
:
\node[diamond] (F) at (C|-E) {FFFFFfF};
С помощью calc
библиотеки вы можете разместить его посередине между (центрами) A
и E
:
\node[diamnond] (F) at ($(A)!.5!(E)$) {FFFFFfF};
или на полпути между границами A
и E
с узлом вдоль пути:
\path (A) -- node[diamond] (F) {FFFFFfF} (E);
Хотя в последнем случае вы также можете использовать A.center
и , E.center
а в первом — , ($(A.east)!.5!(E.west)$)
но поскольку ваши узлы A
и E
имеют одинаковую ширину, то нет никакой разницы между размещением узла посередине между их центрами и посередине между их границами.
Конечно, во всех этих случаяхnode distance
больше не будет наблюдаться, но для F
узла это было уже слишком поздно.
Вы можете использоватьon grid
вариантбиблиотеки positioning
, чтобы она измеряла расстояние между центрами узлов, для чего вам необходимо тщательно задать соответствующее расстояние между узлами. (→Ответ Сэнди Джи)
Вы можете поместить узлы в , matrix of nodes
что разместит их на сетке, но обеспечит соблюдение минимального расстояния между узлами, представленного row sep
и column sep
. Используя ключевое словоbetween origins
и row sep
/или column sep
аналогичный алгоритм позиционирования, который on grid
может быть использован для матрицы.
\matrix[
matrix of nodes,
row sep=1cm,
column sep=1cm,
cells={nodes={draw, very thick, minimum size=10mm}}]{
|(A)| A & |[diamond] (F)| FFFFFfF & |(E)| E \\
|(B)| B & |[draw=red] (C)| C & |(D)| D \\};
Код
\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{fit, graphs, matrix, positioning, shapes.geometric}
\begin{document}
\begin{tikzpicture}
\begin{scope}[nodes={draw, very thick, minimum size=10mm}]
\node (A) {A};
\node (B) [below=of A] {B};
\node[draw=red] (C) [right=of B] {C};
\node (D) [right=of C] {D};
\node (E) [above=of D] {E};
\node[diamond] (F) at (C|-E) {FFFFFfF};
% with calc
% \node[diamnond] (F) at ($(A)!.5!(E)$) {FFFFFfF};
% or without
% \path (A) -- node[diamond] (F) {FFFFFfF} (E);
\end{scope}
\graph[path, ->, use existing nodes] {A, B, C, D, E, F -> C};
\node[
fit={(B)(D)([yshift=+-1em]C.south)}, dashed, inner sep=+.5em, thick, draw,
label={[above, inner sep=+.2em]south:for $i = 1, 2, \dots, N$}]{};
\end{tikzpicture}
\begin{tikzpicture}
\matrix[
matrix of nodes,
row sep=1cm,
column sep=1cm,
cells={nodes={draw, very thick, minimum size=10mm}}]{
|(A)| A & |[diamond] (F)| FFFFFfF & |(E)| E \\
|(B)| B & |[draw=red] (C)| C & |(D)| D \\};
\graph[path, ->, use existing nodes] {A, B, C, D, E, F -> C};
\node[
fit={(B)(D)([yshift=+-1em]C.south)}, dashed, inner sep=+.5em, thick, draw,
label={[above, inner sep=+.2em]south:for $i = 1, 2, \dots, N$}]{};
\end{tikzpicture}
\end{document}