Thinking about this mathematically, it is going to be very hard to do properly. I mean, so that \draw[->] (a) -- (b);
draws an arrow from a
towards the desired point on b
and stops at the boundary with the arrowhead. To do that, one is going to have to calculate the point on the boundary where the line from a
to the anchor of b
reaches the boundary of b
and that will depend on many parameters.
Here's a slightly different approach, which is presented more as a "proof of concept" than as usable code. The idea is that for a simple shape such as a rectangle, one can define some auxiliary nodes whose boundary coincides with the boundary of the original node when seen from certain directions but which are centred at the correct place. The trick is then to pick the right one of these auxiliary nodes upon approach (this is the main bit that I haven't thought how to do).
\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\newlength\relocate@minx
\newlength\relocate@maxx
\newlength\relocate@miny
\newlength\relocate@maxy
\def\relocatenode#1#2{%
\path (#1.south east);
\pgfgetlastxy{\relocate@east}{\relocate@south}
\path (#1.north west);
\pgfgetlastxy{\relocate@west}{\relocate@north}
\path (#1) ++(#2);
\pgfgetlastxy{\relocate@x}{\relocate@y}
\pgfmathsetlength{\relocate@minx}{2 * min(\relocate@east - \relocate@x, \relocate@x - \relocate@west)}
\pgfmathsetlength{\relocate@maxx}{2 * max(\relocate@east - \relocate@x, \relocate@x - \relocate@west)}
\pgfmathsetlength{\relocate@miny}{2 * min(\relocate@north - \relocate@y, \relocate@y - \relocate@south)}
\pgfmathsetlength{\relocate@maxy}{2 * max(\relocate@north - \relocate@y, \relocate@y - \relocate@south)}
\path (#1) ++(#2) node[minimum width=\relocate@minx,minimum height=\relocate@miny] (#1-minx-miny) {};
\path (#1) ++(#2) node[minimum width=\relocate@maxx,minimum height=\relocate@miny] (#1-maxx-miny) {};
\path (#1) ++(#2) node[minimum width=\relocate@minx,minimum height=\relocate@maxy] (#1-minx-maxy) {};
\path (#1) ++(#2) node[minimum width=\relocate@maxx,minimum height=\relocate@maxy] (#1-maxx-maxy) {};
}
\makeatother
\begin{document}
\begin{tikzpicture}[every path/.style={->}]
\node[draw,align=left] (a) at (0,0) {hello world\\greetings mars};
\relocatenode{a}{1,.3}
\fill (a) circle (2pt);
\fill (a) ++(1,.3) circle (2pt);
\path (a) ++(1,.3) node (b) {};
\foreach \pt in {30,60,...,360} {
\draw (a) ++(\pt:5) -- (a);
}
\foreach \pt in {0,10,...,80} {
\draw[red] (a) ++(\pt:5) -- (a-minx-miny);
}
\foreach \pt in {90,100,...,170} {
\draw[red] (a) ++(\pt:5) -- (a-maxx-miny);
}
\foreach \pt in {180,190,...,260} {
\draw[red] (a) ++(\pt:5) -- (a-maxx-maxy);
}
\foreach \pt in {270,280,...,360} {
\draw[red] (a) ++(\pt:5) -- (a-minx-maxy);
}
\end{tikzpicture}
\end{document}
Result:
shorten >=...
syntax.[text height=1.5ex, text depth=0.25ex]
or[nodes={anchor=center}]
to the matrix, so that the arrows are not slanted, see the two example in tex.stackexchange.com/questions/3892line to
(and similar commands). For details seetexmf/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex
. Forline to
, the code is in\tikz@@lineto
, which (in v2.10) starts at line 2187.