# Modifying * and o style tikz arrows so that they are centered at the end of line

I would like to use tikz * and o arrows to indicate included/excluded endpoints in plots of piecewise functions, like for example the following one:

However, it seems that tikz always aligns the "tip" of the arrow with the end of the line, so that the code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-.1,-.1) grid (2.1,2.1);
\draw[thick,-*] (0,1.5) -- (1,.5);
\draw[thick,o-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}


produces

where I would like the circles to be vertically aligned on the grid line.

Is there a parameter or code I can modify to get the desired behavior?

-
This should be an option in tikz arrows! –  Gerhard Burger Feb 7 '13 at 9:51
A similar problem arises with the | and the [/] arrows (well, actually, all arrows are defined this way): TikZ arrow tip is displaced –  Qrrbrbirlbel May 20 '13 at 19:39

There are the shorten < and shorten > option which allow you to shorten the arrow length from the start and end of the line, respectively. It also accepts negative values which then extend the arrow head forwards:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}[shorten >=-3pt,shorten <=-3pt]
\draw[help lines] (-.1,-.1) grid[step=.5] (2.1,2.1);
\draw[thick,-*] (0,1.5) -- (1,.5);
\draw[thick,o-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}


The 3pt was just a lucky guess, but seems to be the correct value for this arrow heads.

Result:

-
Thank you, I somehow missed the shorten > option. –  Jan Hlavacek Feb 24 '11 at 3:58
The exact value is 1.8pt+1.4\pgflinewidth which is 2.92pt for a thick line. –  Luigi May 20 '13 at 17:48
@Luigi: Where did you get the information about the exact value? –  Manuel Kuehner May 21 '13 at 12:32
@ManuelKuehner from the code of the arrowhead. The radius of the circle line included is 4.5\pgfutil@tempdima + 0.5\pgflinewidth (see Jake's answer for the code), hence you have to move the center by this quantity taking into account that thick means line width=0.8pt. –  Luigi May 21 '13 at 17:51

If you want to avoid having to guess the value for the shorten < key, you can define new arrow heads that will place the circles precisely at the specified coordinate:

\documentclass[]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepgflibrary{arrows}

\makeatletter
\pgfarrowsdeclare{center*}{center*}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}
\pgfutil@tempdima=0.4pt%
\pgfarrowsrightextend{4.5\pgfutil@tempdima}
}
{
\pgfutil@tempdima=0.4pt%
\pgfsetdash{}{+0pt}
\pgfpathcircle{\pgfqpoint{4.5\pgfutil@tempdima}{0bp}}{4.5\pgfutil@tempdima}
\pgfusepathqfillstroke
}

\pgfarrowsdeclare{centero}{centero}
{
\pgfarrowsleftextend{+-.5\pgflinewidth}
\pgfutil@tempdima=0.4pt%
\pgfarrowsrightextend{4.5\pgfutil@tempdima}
}
{
\pgfutil@tempdima=0.4pt%
\pgfsetdash{}{+0pt}
\pgfpathcircle{\pgfqpoint{4.5\pgfutil@tempdima}{0bp}}{4.5\pgfutil@tempdima}
\pgfusepathqstroke
}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw[help lines] (-.1,-.1) grid (2.1,2.1);
\draw[thick,-center*] (0,1.5) -- (1,.5);
\draw[thin,centero-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}

-
I think it's not as simple as you imagine. –  Luigi May 20 '13 at 18:24
Ok. I'm sorry. The left extend is correct, but the right extend should simply be 4.5\pgfutil@tempdima if you want the center of the circle at the end of the line (IMHO). –  Luigi May 20 '13 at 18:34
@Luigi: Yes, that seems right. Edited, thank you! –  Jake May 20 '13 at 18:40