我有以下 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}
输出