соединять узлы с цепями присоединяться

соединять узлы с цепями присоединяться

Я хотел бы изменить приведенный ниже код, чтобы использовать метод соединения цепочек вместо помещения узла между ними. Есть идеи, как это реализовать?

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows, calc,chains}

\tikzset{
    myarr/.style args={#1 -- #2}{
        insert path={let \p1=($(#1)-(#2)$) in}, 
        single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)}, 
        inner sep=0mm, single arrow head extend=1pt, 
    },
    every join/.style={->},
}

\begin{document}
\begin{tikzpicture}[start chain=going right,node distance= 2cm and 2cm]
\def\data{
    A,
    B,
    C,
    D%
   } 
\foreach \p [count=\i from 1] in \data {
    \node[draw,on chain,join,minimum width=2cm,minimum height=4cm] (P\i) {\p};
}
 % move below logic to use join method
\path (P1) -- (P2) node[midway,->,myarr={P1.east -- P2.west},single arrow] {};
\path (P2) -- (P3) node[midway,->,myarr={P2.east -- P3.west},single arrow] {};
\path (P3) -- (P4) node[midway,->,myarr={P3.east -- P4.west},single arrow] {};
\end{tikzpicture}
\end{document}

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

решение1

Вы можете разместить узел через соединение в цепочке, просто настроив , to pathкоторый делает именно это: размещает узел.

Внутри to pathу вас есть доступ к \tikztostartи \tikztotarget– а также к , \tikztonodesно мы проигнорируем это здесь… или вам нужен текст где-то?

Затем разницу можно вычислить, как и прежде veclen, а также ее направление/угол с помощью atan2. Затем результаты можно использовать с , nodeкак и прежде, который теперь является единственным (визуальным) выводом to path.

Все это сделано в myarr with anchorsстиле:

\tikzset{
  myarr with anchors/.style 2 args={
    to path={
      let \p0=($(\tikztotarget.#2)-(\tikztostart.#1)$) in
      node[myarr node,
           minimum height={veclen(\x0,\y0)},
           shape border rotate={atan2(\y0,\x0)}] at (\tikztostart.#1) {}}}}

Для простых цепей это так же просто, как

\tikz[
  start chain=going right, node distance=2cm and 2cm,
  every join/.style={myarr with anchors={east}{west}},
  every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};

Мне больше нравятся автоматические подходы, при которых система сама находит точки на границе.

Для этого я предоставляю myarrстиль, который использует edgeдля поиска точек на границе, а затем использует их в тех же вычислениях, что и раньше.

При желании он также принимает два аргумента, которые либо пусты (автоматический подход или не узел), либо содержат спецификацию якоря (с .).


Ссылка:Можно ли использовать `let` (из `TikZ`) внутри определения стиля узла?.

Код

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.arrows, calc, chains}
\tikzset{
  myarr node/.style={
    shape=single arrow, draw=black, minimum width=20mm, anchor=tail,
    shape border uses incircle, single arrow head extend=+1pt,
    inner sep=+0pt, outer sep=+0pt},
  %
  myarr with anchors/.style 2 args={
    to path={
      let \p0=($(\tikztotarget.#2)-(\tikztostart.#1)$) in
      node[myarr node,
           minimum height={veclen(\x0,\y0)},
           shape border rotate={atan2(\y0,\x0)}] at (\tikztostart.#1) {}}},
  %
  myarr/.default={}{},
  myarr/.style 2 args={
    to path={
      \expanded{
        (\tikztostart#1) edge[path only, overlay, line to]
          coordinate[at start] (@start)
          coordinate[at end]   (@end) (\tikztotarget#2)}
      let \p0=($(@end)-(@start)$) in
      node[myarr node,
           minimum height={veclen(\x0,\y0)},
           shape border rotate={atan2(\y0,\x0)}] at (@start) {}}}}
\begin{document}
\pgfmathsetseed{872607}
\tikz[
  start chain=going right, node distance=2cm and 2cm,
  every join/.style={myarr with anchors={east}{west}},
  every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};

\tikz[
  start chain=going right, node distance=2cm and 2cm,
  every join/.style=myarr,
  every on chain/.append style={draw, minimum width=2cm, minimum height=4cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};

\tikz[
  start chain=going above right, node distance=.4cm and 2cm,
  every join/.style=myarr,
  every on chain/.append style={draw, circle, minimum size=2cm}]
\node foreach \t in {A, ..., D} [on chain, join, shift={(3*rand, 3*rand)}]{\t};

\tikz[
  start chain=going above right, node distance=.4cm and 2cm,
  every join/.style={myarr={.north east}{.south west}},
  every on chain/.append style={draw, minimum width=2cm, minimum height=1cm}]
\node foreach \t in {A, ..., D} [on chain, join]{\t};
\end{document}

Выход

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

решение2

Я не совсем понимаю, что вы пытаетесь сделать, но, возможно, вы хотите что-то вроде следующего?

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows, calc,chains}

\tikzset{
    myarr/.style args={#1 -- #2}{
        insert path={let \p1=($(#1)-(#2)$) in}, 
        single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)}, 
        inner sep=0mm, single arrow head extend=1pt, 
    },
    my arr/.style={
        insert path={let \p1=(20mm,0pt) in}, 
        single arrow, draw=black, minimum width=20mm, minimum height={veclen(\x1,\y1)}, 
        inner sep=0mm, single arrow head extend=1pt, 
    },
}

\begin{document}
\begin{tikzpicture}[start chain=going right,node distance=2cm and 0cm]
\def\data{
    A,
    B,
    C,
    D%
   } 
\foreach \p [count=\i from 1,remember=\i as \ilast] in \data {
  \edef\tempa{1}\edef\tempb{\i}%
  \ifx\tempa\tempb\relax
  \else \node (A-\ilast-\i) [draw,on chain,my arr] {};
  \fi
  \node[draw,on chain,join,minimum width=2cm,minimum height=4cm] (P\i) {\p};
}
\end{tikzpicture}
\end{document}

стрелочные узлы на цепи

решение3

Небольшая вариация хорошего ответа @cfr.

  • Макрос join предназначен (судя по всему) только для рисования стрелок (любого вида) между узлами, но он не способен вставлять узлы между ними.
  • Из-за вышесказанного вы не можете вставлять узлы с single arrowформой между основными узлами в цепочке с помощью макроса join. Они могут быть вставлены только как обычные узлы в цепочке.
  • Этот single arrowузел может хорошо вписаться между двумя основными узлами в цепочке, вам необходимо соответствующим образом определить его стиль (см. MWE ниже).
  • МВЭ:
\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, chains,
                shapes.arrows}


\begin{document}
    \begin{tikzpicture}[
node distance = 0mm,
  start chain = going right,
    SA/.style = {% single arrow
                 single arrow, single arrow head extend=3mm, 
                 draw, minimum width=20mm, minimum height=20mm,
                 inner sep=0mm,
                 node contents=\vphantom{A},
                 on chain
                 },
     N/.style = {draw, semithick, on chain, 
                 minimum width=2cm, minimum height=4cm}
                        ]
\def\data{A, B, C, D}
\foreach \i [count=\j] in \data 
{
    \node[N] {\i};
\ifnum\j<4  
    \node[SA];  
\fi
}
    \end{tikzpicture}
\end{document}

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

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