[Tex/LaTex] Tikz arrow starting exactly in the center

arrowstikz-pgf

I have the following problem. I am using the tikz package to draw figures. I am drawing some sort of a data structure. This includes having nodes and lines which connect nodes. Sometimes, a line has to start with a dot and end with an arrow. I have the following code (using arrows and patterns tikz libraries):

\documentclass{article}

\usepackage{verbatim}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{patterns}
\usetikzlibrary{arrows}
\begin{document}
\begin{figure}[h]

    \begin{tikzpicture}
      [internal/.style={rectangle,draw},
       bmp/.style={rectangle,draw,pattern=north east lines},
       ]
      \node(root)     at ( 0.00, 0.00)                           {\verb=root=};
      \node(in1)      at ( 0.00,-0.60)          [internal,minimum width=3mm,label=left:I1]        {};
      \draw[-stealth](root)--(in1);

      \node(cn1)      at ( 0.00,-1.2)           [internal,minimum width=6mm,label=left:C1]        {};
      \node(cn1bmp)   at (-0.15,-1.2)           [bmp,minimum width=3mm]             {};
      \node(cn1arr1)  at ( 0.15,-1.2)           [internal,minimum width=3mm]        {};
      \draw[*-stealth](in1.mid)--(cn1);

      \node(k1)       at ( 0.50,-1.8)                                               {$k_1$};
      \draw[*-stealth](cn1arr1.mid)--(k1);

      \node(cas)      at ( 0.8,-0.20)                              {\verb=CAS=};
      \draw[->, shorten >=2pt](cas)--(in1);

      \node(lab)      at (-0.70,-1.80) [internal]     {C};
    \end{tikzpicture}

\caption{Trie examples}
\label{f-tries}
\end{figure}
\end{document}

This yields the following picture:

enter image description here

Now, as you can see, the arrow pointing to k1 (corresponding to \draw[*-stealth](cn1arr1.mid)--(k1);) starts a little bit to the right. When I have more arrows, this looks nasty – they all seem to have offsets in various directions.

Is there any way to force the arrow to start in exactly the center (cn1arr1.center doesn't work – it puts it too low)?

Thanks!

Best Answer

Simple solution: Use the shorten < = <length> syntax, which will move the arrow tip (the circle in your case) a specified length along the path. Using

\draw[*-stealth,shorten <=-2.5pt](cn1arr1.center)--(k1);

works quite well in this case.

A more correct way would be to define a new arrow tip using \pgfdeclarearrow{start name}{end name}{extend code}{arrow tip code}, where the extend code (which moves the arrow tip along the line) is left empty. Here's an implementation that is based on the original * arrow tip code, so the circle diameter will be identical to the original one, but it will be centered on the start of the line:

\makeatletter
\pgfarrowsdeclare{new*}{new*}{}
{
  \pgfutil@tempdima=0.4pt%
  \advance\pgfutil@tempdima by.2\pgflinewidth%
  \pgfsetdash{}{+0pt}
  \pgfpathcircle{\pgfqpoint{0pt}{0pt}}{+4.5\pgfutil@tempdima}
  \pgfusepathqfillstroke
}
\makeatother