9

I'm trying to connect an edge to a node with the target point being off-center. I would like the edge to end with an arrow at the border of the node without going into the box.

It is easy to connect an edge to a side of a node:

\begin{tikzpicture}
\node (x) [draw,minimum size=1 cm] at (0,0) {x};
\node (y) [draw,minimum size=1 cm] at (2 cm,2 cm) {y};
\draw[->] (x) -- (y.west);
\end{tikzpicture}

But drawing to halfway between (x) and (x.west) continues into the node instead of stopping at the border:

\begin{tikzpicture}
\node (x) [draw,minimum size=1 cm] at (0,0) {x};
\node (y) [draw,minimum size=1 cm] at (2 cm,2 cm) {y};
\draw[->] (x) -- ($ (y.west)!0.5!(y) $);
\end{tikzpicture}

How can I make an edge with the same angle as (x) -- ($ (y.west)!0.5!(y) $) but which draws the arrow right at the border instead of entering into the node?

  • Somebody temporarily posted an answer using shorten but deleted it. It doesn't quite work for my situation, but it would be nice to leave the answer here because it might be perfect for some closely related situations. – amcnabb Nov 8 '12 at 23:58
  • As requested I have undeleted it. – user11232 Nov 9 '12 at 0:33
8

With the TikZ library intersections you can find the point on the node's rectangle quite easily.

We give the y node a path name: yborder.
We use one \path command to get the path from (x) to ($ (y.west)!0.5!(y) $) and name it xyline.

With name intersections={of=yborder and xyline} we get coordinates named intersections-1, intersections-2, …
In our case there's only one intersection, so intersection-1 will do.

(The PGF/TikZ manual shows how to deal with path intersections with more than one hit.)

Code

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{calc,intersections}
\begin{document}
\begin{tikzpicture}[every node/.style={draw,minimum size=1 cm}]
    \node                     (x) at (0cm,0cm) {x};
    \node [name path=yborder] (y) at (2cm,2cm) {y};
    \path [name path=xyline ] (x) -- ($ (y.west)!0.5!(y) $);
    \fill [red]               ($(y.west)!0.5!(y)$) circle[radius=1pt]; % Where's my point?
    \draw [name intersections={of=yborder and xyline},->]
                              (x) -- (intersection-1);
\end{tikzpicture}
\begin{tikzpicture}[every node/.style={circle,draw,minimum size=1 cm}]
    \node                     (x) at (0cm,0cm) {x};
    \node [name path=yborder] (y) at (2cm,2cm) {y};
    \path [name path=xyline ] (x) -- ($ (y.west)!0.5!(y) $);
    \fill [red]               ($(y.west)!0.5!(y)$) circle[radius=1pt]; % Where's my point?
    \draw [name intersections={of=yborder and xyline},->]
                              (x) -- (intersection-1);
\end{tikzpicture}
\end{document}

Output

rectanglescircles

| improve this answer | |
  • This is a really interesting idea, and I think I might be able to get it to work in my situation. But this won't work for non-rectangle node shapes, will it? – amcnabb Nov 8 '12 at 23:59
  • @amcnabb I've updated my answer. – Qrrbrbirlbel Nov 9 '12 at 0:10
  • I was able to use this to get the exact effect I needed. Thanks for the great answer. – amcnabb Nov 9 '12 at 0:15
  • By the way, the intersection seems to fail if it happens to go right through the southwest corner. This seems like a bug, but I might just have an old version of TikZ. Anyway, this otherwise works perfectly. – amcnabb Nov 9 '12 at 21:01
  • @amcnabb If I use ($(y.south west)!0.5!(y)$) instead of ($(y.west)!0.5!(y)$), they arrow is pointing to (y.south west). What does “seems to fail”? Is there an error message? I don't get an (intersection-1) point when I use (y) (because in this case TikZ automatically uses the outer border of y, (y.center) does work again). – Qrrbrbirlbel Nov 9 '12 at 21:09
3

You can use shorten :

\draw[->,shorten >=10pt] (x) -- ($ (y.west)!0.5!(y) $);

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\node (x) [draw,minimum size=1 cm] at (0,0) {x};
\node (y) [draw,minimum size=1 cm] at (2 cm,2 cm) {y};
\draw[->] (x) -- (y.west);
\end{tikzpicture}
\begin{tikzpicture}
\node (x) [draw,minimum size=1 cm] at (0,0) {x};
\node (y) [draw,minimum size=1 cm] at (2 cm,2 cm) {y};
\draw[->,shorten >=10pt] (x) -- ($ (y.west)!0.5!(y) $);
\end{tikzpicture}
\end{document}

enter image description here

| improve this answer | |
  • How do you programmatically determine how far to shorten by? The edges are created in a \foreach loop, and they won't all be quite the same angles. – amcnabb Nov 8 '12 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.