# Special connexion with a node (TikZ)

I want to connect a rectangle with a circular node using an arrow, as in the picture below (to the right).

The problem is that I have to specify very arbitrary coordinates (e.g. -2.97 in the code below) so that the tip of the arrow is at the right height. This is why I thought to use a node to connect the tip of the arrow to the circle. I obtain, however, what is shown to the left of the picture above... How can I get the desired result (to the right) without specifying a height manually?

\documentclass{article}

\usepackage[letterpaper,textwidth=8.5in,textheight=11in]{geometry}
\usepackage{lscape}

\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\begin{document}
\pagestyle{empty}
\begin{landscape}
\begin{figure}
\centering
\begin{tikzpicture}[scale=1]

\coordinate(A) at (1.5,4);
\coordinate(B) at (2,0.5);
\coordinate(C) at (8,0.5);

\node (C1) at (B) [circle, inner sep=5pt, draw, thick, fill=white] {};
\node (C2) at (C) [circle, inner sep=5pt, draw, thick, fill=white] {};

\foreach \x in {0,1}
\draw [thick, fill=white] ([shift=(A)]6*\x,0) rectangle +(1,-0.35);

\draw [thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (A) ++(0.3,-0.35) -- (C1);
\draw [thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (7.5,4) ++(0.3,-0.35) -- +(0,-2.97);

\end{tikzpicture}
\end{figure}
\end{landscape}
\end{document}

• So... do you want to draw an arrow that stops at the node but is still perpendicular? Jun 6 '15 at 23:30
• What are you planning on doing with the rectangles? Maybe you can use nodes for the rectangles as well? In that case it's fairly easy
– user49901
Jun 6 '15 at 23:36
• Alenanno: Yes. But I want the arrow to be shifted to the left relative to the vertical line passing through the center of the circle. Jun 6 '15 at 23:39
• (C1.north west) worked for me. Jun 7 '15 at 15:41

Another solution using and a rectangular node (and a quick and dirty fill=white). Alenanno's solution is closer to your original code though, so it is probably more useful.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate(A) at (1.5,4);
\coordinate(B) at (2,0.5);
\coordinate(C) at (8,0.5);
\node (C2) at (C) [circle, inner sep=5pt, draw, thick, fill=white] {};
\draw [thick, fill=white] ([shift=(A)]6,0) rectangle +(1,-0.35);
\draw [thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (7.5,4) ++(0.3,-0.35) -- +(0,-2.97);
\end{tikzpicture}
\begin{tikzpicture}
\node[rectangle,thick,minimum width=1cm,minimum height=.35cm,draw=black] (B) at (0,4) {};
\node[yshift=-3.5cm] (C1) at (B) [circle, inner sep=5pt, draw, thick, fill=white] {};
\draw [thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (B)  -| (C1.north west);
\node[rectangle,thick,fill=white,minimum width=1cm,minimum height=.35cm,draw=black] (B) at (0,4) {};
\end{tikzpicture}
\end{document}


The code creates the rectangle B twice, the second time to hide part of the drawn arrow (using fill=white). I've included your picture for comparison.

These are indeed special connections which are not very easy to deal with.

Are these connections only to connect circles with straight lines, you can use the intersection cs (or its implicit variant intersection of). Of course, you could also use the intersections library but then you need to name paths and those path have to actually intersect.
(Due to a bug in the implementation of the calculation of intersections between circles and lines, it is not possible to use the second solution (solution=2 or intersection 2 of). But one can use the direction of the line for this (in our case, just use y shift=-1).)

I am using also nodes for the rectangle parts, the Rectangle=<width>x<height> key is used to add a rectangle that has the dimensions in the xy coordinate system. (For circles, something similar can be done, for example with the through library.)

## Code

\documentclass[tikz]{standalone}
\makeatletter
\tikzset{
Rectangle/.style args={#1x#2}{
shape=rectangle,
/utils/exec=\pgfpointxy{#1}{#2},% in TikZ: (#1,#2)
minimum width/.expanded=\the\pgf@x,
minimum height/.expanded=\the\pgf@y}}
\makeatother
\tikzset{
x shift/.style={shift={(0:#1)}},
y shift/.style={shift={(90:#1)}}}
\begin{document}
\begin{tikzpicture}[
thick,
c/.style={circle, inner sep=5pt, draw, node contents=},
r/.style={Rectangle=1 x .35, draw, anchor=north west, node contents=},
myTip/.tip={Stealth[length=8pt, width=8pt, inset=2pt]}
]
\node (C1) at (2,.5)  [c]; \node (C2) at (4,.5)    [c];
\node (R1) at (1.5,4) [r]; \node (R2) at (2+1.5,4) [r];

\draw[-myTip] ([x shift=.3]R1.south west) coordinate (aux) --
(intersection of C1 and aux--{[y shift=1]aux});
\draw[-myTip] ([x shift=.6]R2.south west) coordinate (aux) --
(intersection cs: first line={(aux)--([y shift=1]aux)}, second node=C2);
\end{tikzpicture}
\end{document}


I defined a new coordinate F in your example (A + the relative coordinates), because it's easier without using relative coordinates like you did, then you can use the following syntax.

(F) -- (F|-C1.north);


What it does is: start from F and then go up to C1.north but still perpendicular to F. I coloured the arrow red so you see it.

By the way, when possible use nodes including your rectangle. This would be much easier with nodes because I could just use the rectangle node instead of defining a new coordinate.

## Code

\documentclass{article}
\usepackage[letterpaper,textwidth=8.5in,textheight=11in,landscape]{geometry}
%\usepackage{lscape} % use landscape in the geometry package!
\usepackage{tikz}

\begin{document}
\pagestyle{empty}
\begin{figure}
\centering
\begin{tikzpicture}[scale=1]

\coordinate(A) at (1.5,4);
\coordinate(B) at (2,0.5);
\coordinate(C) at (8,0.5);
\coordinate(F) at (1.8,3.65);

\node (C1) at (B) [circle, inner sep=5pt, draw, thick, fill=white] {};
\node (C2) at (C) [circle, inner sep=5pt, draw, thick, fill=white] {};

\foreach \x in {0,1}
\draw [thick, fill=white] ([shift=(A)]6*\x,0) rectangle +(1,-0.35);

\draw [red, thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (F) -- (F|-C1.north);
\draw [thick, -{Stealth[length=8pt, width=8pt, inset=2pt]}] (7.5,4) ++(0.3,-0.35) -- +(0,-2.97);

\end{tikzpicture}
\end{figure}
\end{document}

• Actually, I would want the tip of the arrow to touch the circle, as in the black arrow to the right. Jun 6 '15 at 23:42
• @Melian Touch how? That would require the circle nodes to possess negative outer sep, because by default the value is positive. Add this to the circle node options outer sep=.5pt, and then add C1.north west to the end coordinate of the arrow. The red arrow will touch the node, the black one will not. Jun 6 '15 at 23:50