使用 TikZ 合并自由箭头

使用 TikZ 合并自由箭头

我从 TikZ 开始,基本上我想要实现的是绘制下图中红色所示的内容:

在此处输入图片描述

我认为解决方案是使用帮助网格来将线指向我想要与其他线合并的坐标,我尝试了几个小时,但似乎对我来说是不可能的:(有人可以帮帮我吗?请查看附件我的代码:

\documentclass[a4paper,12pt,twoside]{book}
\usepackage[bottom=25mm,top=25mm, left=30mm, right=25mm]{geometry}
\usepackage[utf8x]{inputenc}
\usepackage[spanish, es-tabla, es-noshorthands, es-nosectiondot]{babel}
\usepackage{tikz}
\usetikzlibrary{shapes, arrows}

\makeatletter
\pgfdeclareshape{datastore}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \backgroundpath{
    %  store lower right in xa/ya and upper right in xb/yb
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
    \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@yb}}
    \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
 }
}
\makeatother

\begin{document}

\begin{center}
\begin{tikzpicture}[
  font=\sffamily,
  every matrix/.style={ampersand replacement=\&,column sep=2cm,row sep=2cm},
  subsistema/.style={draw,thick,rounded corners,fill=white!20,inner sep=.3cm},
  adpredect/.style={rectangle split,rectangle split parts = 3,draw,thick,rounded corners,fill=white!20,inner sep=.3cm},
  click_OK/.style={draw,thick,circle,fill=green!20},
  click_NOK/.style={draw,thick,circle,fill=red!20},
  bypass/.style={subsistema,fill=yellow!20},
  datastore/.style={draw,very thick,shape=datastore,inner sep=.3cm},
  dots/.style={gray,scale=2},
  to/.style={->,>=stealth',shorten >=1pt,semithick,font=\sffamily\footnotesize},
  every node/.style={align=center}]

  % Position the nodes using a matrix layout
  \matrix{
    \node[subsistema] (preparobox) {bla\\ bla};
      \& \node[subsistema] (lectmot) {blablablablablablabla\\ blablablabla}; \& \\

    \& \node[datastore] (colamot) {blabla}; \& \\

    \node[subsistema] (parobox) {blablablabla\\ blablabla};
      \& \node[adpredect] (subs) {%
                      blablablablablablabla     \nodepart{two}
                      blablablablablablabla    \nodepart{three}
                      blablablablablablabla   \nodepart{four}
                      }; 
      \& \node[click_OK] (clickdetectado) {OK}; \\
      \& \node[click_NOK] (clicknodetectado) {NOK}; \& \node[bypass] (acc_bypass) {BYPASS}; \\
  };

  % Draw the arrows between the nodes and label them.
  \draw[to] (preparobox) -- node[midway,above] {blabla}
      node[midway,below] {blablablabla} (lectmot);
  \draw[to] (lectmot) -- node[midway,right] {bla} (colamot);
  \draw[to] (lectmot) to[bend left=50] node[midway,below] {bla} (preparobox);
  \draw[to] (colamot) --
      node[midway,right] {blablabla\\bla} (subs);
   \draw[to] (parobox) -- node[midway,above] {bla}
      node[midway,below] {blabla} (subs);
    \draw[to] (subs) -- node[midway,above] {blabla}
     node[midway,below] {blabla} (clickdetectado);
     \draw[to] (subs) -- node[midway,left] {blablabla\\blablablabla}
     (clicknodetectado);
     \draw[to] (clicknodetectado) -- node[midway,above] {blablablabla} node[midway,below] {blablabla} (acc_bypass);
     \draw[to] (clickdetectado) to [out = -50, in = -90, looseness=2.2] node[midway,above] {blablabla} node[midway,below] {blablabla} (parobox);
     %\draw[to] (acc_bypass) to [out = -50, in = -90, looseness=1.2] (parobox);
\end{tikzpicture}
\end{center}

\end{document}

答案1

结果

\documentclass[a4paper,12pt,twoside]{book}
\usepackage[bottom=25mm,top=25mm, left=30mm, right=25mm]{geometry}
\usepackage[utf8x]{inputenc}
\usepackage[spanish, es-tabla, es-noshorthands, es-nosectiondot]{babel}
\usepackage{tikz}
\usetikzlibrary{shapes, arrows, calc, intersections}

\makeatletter
\pgfdeclareshape{datastore}{
  \inheritsavedanchors[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \backgroundpath{
    %  store lower right in xa/ya and upper right in xb/yb
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
    \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
    \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@yb}}
    \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
 }
}
\makeatother

\begin{document}

\begin{center}
\begin{tikzpicture}[
  font=\sffamily,
  every matrix/.style={ampersand replacement=\&,column sep=2cm,row sep=2cm},
  subsistema/.style={draw,thick,rounded corners,fill=white!20,inner sep=.3cm},
  adpredect/.style={rectangle split,rectangle split parts = 3,draw,thick,rounded corners,fill=white!20,inner sep=.3cm},
  click_OK/.style={draw,thick,circle,fill=green!20},
  click_NOK/.style={draw,thick,circle,fill=red!20},
  bypass/.style={subsistema,fill=yellow!20},
  datastore/.style={draw,very thick,shape=datastore,inner sep=.3cm},
  dots/.style={gray,scale=2},
  to/.style={->,>=stealth',shorten >=1pt,semithick,font=\sffamily\footnotesize},
  every node/.style={align=center}]

  % Position the nodes using a matrix layout
  \matrix{
    \node[subsistema] (preparobox) {bla\\ bla};
      \& \node[subsistema] (lectmot) {blablablablablablabla\\ blablablabla}; \& \\

    \& \node[datastore] (colamot) {blabla}; \& \\

    \node[subsistema] (parobox) {blablablabla\\ blablabla};
      \& \node[adpredect] (subs) {%
                      blablablablablablabla     \nodepart{two}
                      blablablablablablabla    \nodepart{three}
                      blablablablablablabla   \nodepart{four}
                      }; 
      \& \node[click_OK] (clickdetectado) {OK}; \\
      \& \node[click_NOK] (clicknodetectado) {NOK}; \& \node[bypass] (acc_bypass) {BYPASS}; \\
  };

  % Draw the arrows between the nodes and label them.
  \draw[to] (preparobox) -- node[midway,above] {blabla}
      node[midway,below] {blablablabla} (lectmot);
  \draw[to] (lectmot) -- node[midway,right] {bla} (colamot);
  \path (preparobox.south east) ++(-45:3pt) coordinate (preparo_se);
  \draw[semithick] (lectmot) to[bend left=50,in=135] node[midway,below] {bla}
      (preparo_se);
  \draw[semithick] ($(lectmot.south)!.6!(colamot.north)$) to[bend left=50,in=135]
      (preparo_se);
  \draw[to, shorten >=0pt] (preparo_se) -- (preparobox.south east);
  \draw[to] (colamot) --
      node[midway,right] {blablabla\\bla} (subs);
   \draw[to] (parobox) -- node[midway,above] {bla}
      node[midway,below] {blabla} (subs);
    \draw[to] (subs) -- node[midway,above] {blabla}
     node[midway,below] {blabla} (clickdetectado);
     \draw[to] (subs) -- node[midway,left] {blablabla\\blablablabla}
     (clicknodetectado);
     \draw[to] (clicknodetectado) -- node[midway,above] {blablablabla} node[midway,below] {blablabla} (acc_bypass);
     \draw[to, name path=okarc] (clickdetectado) to [out = -50, in = -90, looseness=2.2] node[midway,above] {blablabla} node[midway,below] {blablabla} (parobox);
     \path[overlay,name path=byline] (acc_bypass.south) -- ++(-120:5cm);
     \draw[semithick, line cap=round, name intersections={of=okarc and byline}]
       (acc_bypass.south) to [out=-90, in=30] (intersection-1);
     %\draw[to] (acc_bypass) to [out = -50, in = -90, looseness=1.2] (parobox);
\end{tikzpicture}
\end{center}

\end{document}

评论:

  • 两条线都以相同的输入角度结束于 的东南角preparobox。两个箭头可能看起来不太好,因此我让线条在 3 pt 之前结束,没有箭头,并从 3 pt 到东南角添加了一条箭头线。由于该框有圆角,我将其减少shorten >到 0 pt。

  • clickdetectado我使用从“OK”( )到 的线parobox与从 到 的不可见直线之间的交点作为下线的目标acc_bypass.south,其中角度为-120。然后借助库 计算交点intersections

相关内容