# TikZ: How to connect nodes and specify line direction?

When drawing a line between two nodes in TikZ, you can specify the anchors on the beginning and end nodes in order to control how the line is drawn.

I would like to specify the anchor on the beginning node, and the angle at which the line is drawn, and let TikZ figure out where it will intercept the end node. The usual use case is when I'm connecting to a "big node" and I would like the lines to be vertical.

I can cheat by placing a coordinate behind the big node, drawing a line to the coordinate instead, and then drawing the big node so that it covers things up. However this won't work if I need to put an arrow on the end.

I could try to calculate the intercept coordinate on the edge of the big node manually, but that seems against the TikZ spirit.

|- doesn't work in this case.

\documentclass[10pt]{minimal}
\usepackage[active,tightpage,pdftex]{preview}
\usepackage{tikz}

\begin{document}
\begin{preview}

\tikzstyle{RectObject}=[rectangle,fill=white,draw,line width=0.5mm]
\tikzstyle{line}=[draw]
\tikzstyle{arrow}=[draw, -latex]

\begin{tikzpicture}
%%%%%%%%%%%%%%%%%%%%%%%%
%%  LEFT SIDE
%%%%%%%%%%%%%%%%%%%%%%%%
\draw (1,0) node[RectObject] (Small1A) {A};
\draw (3,0) node[RectObject] (Small1B) {B};
\coordinate (Cheat1A) at (1,2);
\coordinate (Cheat1B) at (3,2);
\path [line] (Small1A.north) -- (Cheat1A);
\path [line] (Small1B.north) -- (Cheat1B);

% need to draw Big Node last to cover up our cheating
\draw (2,2) node[RectObject, inner xsep=1cm] (Big1) {Big Node};

\draw (2,4) node[text width=4cm] (text1) {L: Cheating to control line orientation. Arrows would be hard.};

%%%%%%%%%%%%%%%%%%%%%%%%
%%  RIGHT SIDE
%%%%%%%%%%%%%%%%%%%%%%%%
\draw (7,2) node[RectObject, inner xsep=1cm] (Big2) {Big Node};
\draw (6,0) node[RectObject] (Small2A) {A};
\draw (8,0) node[RectObject] (Small2B) {B};
\path [arrow] (Small2A) -- (Big2);
\path [arrow] (Small2B) -- (Big2);

\draw (7,4) node[text width=4cm] (text2) {R: No cheating. Arrows easy. Can't control line orientation.};
\end{tikzpicture}
\end{preview}
\end{document}


Here's a side-by-side example of "cheating", which shows what I want to be able to do, and "not cheating", which does not do what I want.

The left side of this example shows what I want to be able to do, except I want to do it without cheating, and I'd like to put arrows on the end of the lines.

May be I missunderstood something but I don't see any problem with |- syntax. Using Jake's code:

\documentclass[10pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\tikzstyle{RectObject}=[rectangle,fill=white,draw,line width=0.5mm]
\tikzstyle{line}=[draw]
\tikzstyle{arrow}=[draw, -latex]

\begin{tikzpicture}
\draw (7,2) node[RectObject, inner xsep=1cm] (Big2) {Big Node};
\draw (6,0) node[RectObject] (Small2A) {A};
\draw (8,0) node[RectObject] (Small2B) {B};
\draw[arrow] (Small2A.north)--(Small2A|-Big2.south);
\draw[arrow] (Small2B.north)--(Small2B|-Big2.south);

\end{tikzpicture}
\end{document}


In case someone needs it, this syntax is explained in pgfmanual section "13.3.1 Intersections of Perpendicular Lines".

(<p> |- <q>) or (<q> -| <p>) represent a coordinate at intersection point between a vertical line passing through coordinate <p> and an horizontal passing through <q>. You can use named coordinates like (Small2B|-Big2.south) or numeric pairs like in (2,1 |- 3,4).

• Oh wow, I never thought of using the syntax inside the node specification! Much more elegant than my approach! – Jake Jul 13 '11 at 22:25
• That is slick. I didn't know you could use the |- syntax inside a node specification like that. Originally I said "|- doesn't work" because I was thinking of (Small1A) |- (Big1.south) or something like that. – andrewtinka Jul 18 '11 at 19:20
• What does the syntax (node1)--(node1|-node2.south) actually mean? Is there any documentation I might read? – LondonRob Jul 7 '15 at 13:37
• @LondonRob (node1|-node2.south) equals the coordinate at intersection point between and horizontal line through node2.south and a vertical line through node1.center (where .center can be omited). Take a look at pgfmanual, page 137. – Ignasi Jul 7 '15 at 13:51
• Fantastic. Perhaps you might add this to your answer! – LondonRob Jul 7 '15 at 13:52

Jake and Ignasi's answers are excellent for the example I gave, of wanting strictly vertical lines between nodes. I found a way of doing the same thing with arbitrary orientation of the line. The "intersection of" TikZ mechanism can be used to find the intersection of lines defined by nodes or coordinates. The "intersection" syntax is tricky; it seems that you can't use the "calc" syntax inside an "intersection" specification, so you have to create a new coordinate and do the calculations there.

\documentclass[10pt]{minimal}
\usepackage[active,tightpage,pdftex]{preview}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\begin{document}
\begin{preview}

\tikzstyle{RectObject}=[rectangle,fill=white,draw,line width=0.5mm]
\tikzstyle{line}=[draw]
\tikzstyle{arrow}=[draw, -latex]

\begin{tikzpicture}
\draw (2,2) node[RectObject, inner xsep=1cm] (Big1) {Big Node};
\draw (1,0) node[RectObject] (Small1A) {A};
\draw (3,0) node[RectObject] (Small1B) {B};

% Method 1: use positioning library to put a coordinate at a special place
% on the target node.  Doesn't really satisfy my criteria for setting the
% line's orientation directly.
\coordinate[left=1.4cm of Big1.south] (Small1AatBig1);
\path [arrow] (Small1A) -- (Small1AatBig1);

% Method 2: set a phantom coordinate using polar coordinates, then draw
% a line to the intersection of the target node and the phantom line
% Intersection syntax is tricky: no parentheses and no spaces around --
\coordinate (Phantom) at ($(Small1B) + (115:5cm)$);
\path [arrow] (Small1B) -- (intersection of Big1.south--Big1.south east and Small1B--Phantom);

\end{tikzpicture}
\end{preview}


Two approaches, both using the TikZ calc library: Either use the syntax ($(A)!(C)!(B)$), which specifies the projection of (C) on the line from (A) to (B), or use the let \p1 = (<coordinate>) in ... syntax, which stores a coordinate in a macro \p1 and lets you access its x and y coordinates separately with \x1 and \y1:

\documentclass[10pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\tikzstyle{RectObject}=[rectangle,fill=white,draw,line width=0.5mm]
\tikzstyle{line}=[draw]
\tikzstyle{arrow}=[draw, -latex]

\begin{tikzpicture}
\draw (7,2) node[RectObject, inner xsep=1cm] (Big2) {Big Node};
\draw (6,0) node[RectObject] (Small2A) {A};
\draw (8,0) node[RectObject] (Small2B) {B};
\path [arrow]  let \p1=(Small2A), \p2=(Big2.south) in (Small2A) -- (\x1,\y2);
\path [arrow] (Small2B) -- ($(Big2.south east)!(Small2B)!(Big2.south)$);

\end{tikzpicture}
\end{document}