Как определить положение третьего узла по положению двух узлов?

Как определить положение третьего узла по положению двух узлов?

Вот изображение, которое выдает мой существующий код: 1 Я надеюсь, что 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}

И то, что я в итоге надеюсь получить, это вот это, то есть мне нужно добавить очень большую пунктирную рамку. Как это реализовать? 2

решение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}

Выход

введите описание изображения здесь введите описание изображения здесь

Связанный контент