Tikz:从 nodeA.south 到 nodeB.north 的纯垂直箭头

Tikz:从 nodeA.south 到 nodeB.north 的纯垂直箭头

我有以下 tikz 代码

% compilation command: pdflatex --jobname=Diag-f1 Diag.tex
\documentclass{book}
\usepackage{tikz}
\pgfrealjobname{Diag}
\begin{document}
\beginpgfgraphicnamed{Diag-f1}
\begin{tikzpicture}[node distance=3em]
\node(G)[rectangle,fill=red!5,draw=red,text width=5cm]{};
\node(H)[below of=G]{H};
\node(H1)[left of=H]{H1};
\node(H2)[right of=H]{H2};
\draw[->](G.south)-|(H1.north);
\draw[->](G.south)--(H.north);
\draw[->](G.south)-|(H2.north);
\end{tikzpicture}
\endpgfgraphicnamed
\end{document}

在此处输入图片描述

但我对从 G.south 到 H1.north 和 H2.north 的两个箭头不满意。由于命令的原因-|,出现了一条虚假的水平线。如何才能在没有这条烦人的水平线的情况下实现相同的结果?\draw[->](G.south)--(H1.north);不是解决方案。有可用的技巧,但我可能错过了一个明显的解决方案。

答案1

该线正常:-|意思是:画一条水平线,然后画一条垂直线。

你可以使用这个:

\draw[->] (G.south -| H1.north) -- (H1.north)

H1.north这将计算通过的垂直线和通过的水平线之间的交点G.south,然后从它画一条线到H1.north

答案2

我喜欢使用to路径。

优点:仅需给出一次目标坐标/节点。

代码

\documentclass[tikz]{standalone}
\tikzset{
    *|/.style={
        to path={
            (perpendicular cs: horizontal line through={(\tikztostart)},
                                 vertical line through={(\tikztotarget)})
            % is the same as (\tikztostart -| \tikztotarget)
            % but just to be safe: http://tex.stackexchange.com/a/29781/16595
            -- (\tikztotarget) \tikztonodes
        }
    }
}
\begin{document}
\begin{tikzpicture}[node distance=3em]
\node(G)  [rectangle,fill=red!5,draw=red,text width=5cm] {};
\node(H)  [below of=G] {H};
\node(H1) [left of=H]  {H1};
\node(H2) [right of=H] {H2};
\draw[->,*|] (G.south) to     (H1.north);
\draw[->]    (G.south) --     (H.north);
\draw[->]    (G.south) to[*|] (H2.north);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述


对于这种可能性的各种不同(无需声明锚点),您可以定义更多类似的样式。这也是我的paths.ortho库的一部分(请参阅我的用户信息)。

请注意,这(以及原始答案,见上文)目前没有考虑当前转换,而只是使用锚点.north.south和。.east.west

代码

\documentclass[tikz]{standalone}
\makeatletter
\newif\iftikz@ortho@preflush
\tikz@ortho@preflushtrue
\let\tikz@origtotarget\pgfutil@empty
\tikzset{
  |-/.style={to path={|- (\tikztotarget) \tikztonodes}},
  -|/.style={to path={-| (\tikztotarget) \tikztonodes}},
  *|/.style={to path={%
    \pgfextra
      \iftikz@shapeborder
        \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
        \ifdim\pgf@y>\tikz@lasty\relax
          \edef\tikztostart{\tikztostart.north}%
        \else
          \edef\tikztostart{\tikztostart.south}%
        \fi
      \fi
    \endpgfextra
    (perpendicular cs: horizontal line through={(\tikztostart)},
                 vertical line through={(\tikztotarget)}) -- (\tikztotarget) \tikztonodes
  }},
  *-/.style={to path={%
    \pgfextra
      \iftikz@shapeborder
        \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
        \ifdim\pgf@x>\tikz@lastx\relax
          \edef\tikztostart{\tikztostart.east}%
        \else
          \edef\tikztostart{\tikztostart.west}%
        \fi
      \fi
    \endpgfextra
    (perpendicular cs: vertical line through={(\tikztostart)},
                     horizontal line through={(\tikztotarget)}) -- (\tikztotarget) \tikztonodes
  }},
  |*/.style={to path={%
    \pgfextra
      \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
      \iftikz@shapeborder
        \let\tikz@origtotarget\tikztotarget
        \ifdim\pgf@y>\tikz@lasty\relax
          \edef\tikztotarget{\tikztotarget.south}%
        \else
          \edef\tikztotarget{\tikztotarget.north}%
        \fi
      \fi
    \endpgfextra
    (\tikztostart) -- (perpendicular cs: vertical line through={(\tikztostart)},
                                         horizontal line through={(\tikztotarget)})
    \tikztonodes \ifx\tikz@origtotarget\pgfutil@empty\else\iftikz@ortho@preflush(\tikz@origtotarget)\fi\fi
  }},
  -*/.style={to path={%
    \pgfextra
      \tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
      \iftikz@shapeborder
        \let\tikz@origtotarget\tikztotarget
        \ifdim\pgf@x>\tikz@lastx\relax
          \edef\tikztotarget{\tikztotarget.west}%
        \else
          \edef\tikztotarget{\tikztotarget.east}%
        \fi
      \fi
    \endpgfextra
    (\tikztostart) -- (perpendicular cs: horizontal line through={(\tikztostart)},
                                         vertical line through={(\tikztotarget)})
    \tikztonodes \ifx\tikz@origtotarget\pgfutil@empty\else\iftikz@ortho@preflush(\tikz@origtotarget)\fi\fi
  }},
  node as new start/.is if=tikz@ortho@preflush
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{scope}[nodes={shape=rectangle, draw, minimum width=+1.5cm, minimum height=+1cm}]
  \node (a)                {A};
  \node (b) at (  .5, 2  ) {B};
  \node (c) at ( 2.5,- .2) {C};
  \node (d) at (- .5,-2  ) {D};
  \node (e) at (-2.5,  .2) {E};
\end{scope}
\tikzset{nodes={auto,font=\small\ttfamily}}
\path[->] (a) edge[*|]                 (b)
          (b) edge[*|] node {*|}       (a)
          (a) edge[*-]                 (c)
          (c) edge[*-] node[swap] {*-} (a)
          (a) edge[|*]                 (d)
          (d) edge[|*] node[swap] {|*} (a)
          (a) edge[-*]                 (e)
          (e) edge[-*] node       {-*} (a)
          %
          {[every edge/.append style=blue]
            {[|-]
              (e) edge (b)
                  edge (d)}
            {[-|]
              (b) edge (c)
              (d) edge (c)}}
;
\end{tikzpicture}
\begin{tikzpicture}[nodes={shape=rectangle, draw, minimum width=+1cm, minimum height=+1cm}]
  \node (a)              {A};
  \node (b) at ( .25, 2) {B};
  \node (c) at (1.25,-0) {C};
  \draw (a) to [|*] (b) to (c);

  \begin{scope}[xshift=3cm, node as new start=false]
    \node (a)              {A};
    \node (b) at ( .25, 2) {B};
    \node (c) at (1.25,-0) {C};
    \draw (a) to [|*] (b) to (c);
  \end{scope}
\end{tikzpicture}
\begin{tikzpicture}[nodes={rectangle,draw,anchor=west,minimum height=+1cm}]
\node (rechteck1)[minimum width=+3cm] at (1,5){};
\node (rechteck2)[minimum width=+2cm] at (1,3){};

\draw [->] (rechteck1) to[*|] (rechteck2);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述 在此处输入图片描述 在此处输入图片描述

相关内容