# Combine shorten and bend option in TikZ

Is there a way to combine the bend left and shorten option to make an arc shorter while keeping its shape otherwise?

i.e., when I do

\begin{tikzpicture}
\node[] (n1) at (0,0) {1};
\node[] (n2) at (4,0) {2};
\draw[->] (n1) to [bend left, shorten >=1cm] (n2);
\draw[->] (n1) to [bend left] (n2); % original arc
\end{tikzpicture}


the shortened arrow has a different shape than the original one.

-
Sry, you are right. I fixed the example... – dcn Oct 23 '11 at 13:20
I'm not very sure I understood your problem correctly. It it that when shortened, your arcs will be less like circular arcs, but you would like to preserve it? – Count Zero Oct 23 '11 at 13:34
Exactly. They should have the same form as unshortened, just end earlier. – dcn Oct 23 '11 at 13:51
Your example does not work. The shorten > option cannot be applied to a subpath, only to the whole path, so in your example, it gets ignored. What you probably want to do is \draw[->, shorten >=1cm] (n1) to [bend left] (n2);. – Jan Hlavacek Oct 23 '11 at 13:56
You should take a look at the following question, with the accepted answer: tex.stackexchange.com/questions/18617/… – Frédéric Oct 23 '11 at 13:56

To be very precise, the curvature added to the line with bend doesn't exactly make it an arc. Or rather it looks like an arc, but mathematically speaking it is not one (it is a Bézier curve if I'm not mistaken). Hence, when shortened the way you did in the example, it will be a bit, well... different. I think shorten was implemented with really short distances in mind, little adjustments, where the difference between the original curve and the correction is (almost) imperceptible.

Beside the solution by @Jan Hlavacek, you could try the following two.

One thing is to explicitly draw a Bézier (with controls) and play around with the control points, but that can be a lot of guesswork. Instead you could try playing either with the <angle> option bend takes (see code below) - not perfect, but satisfactory, I believe - or draw a curve between the endpoints (n1 and n2 in your case) and make visible only part of it (see also below):

\begin{tikzpicture}
\node[] (n1) at (0,0) {1};
\node[] (n2) at (4,0) {2};
\draw[->] (n1) to [bend left] (n2); % original arc

% solution 1

\draw[->, blue, shorten >=1cm] (n1) to [bend left=27] (n2);

% solution 2

\pgfpathcurvebetweentime{0.05}{0.75}{\pgfpoint{0}{0}}{\pgfpointxy{1}{0.9}}{\pgfpointxy{3}{0.9}}{\pgfpointxy{4}{0}}
\pgfsetarrowsend{to}
\pgfsetstrokecolor{red}
\pgfusepath{stroke}
\end{tikzpicture}


The \pgfpathcurvebetweentime takes the parameters: visible part beginning at portion <start> of curve, visible part ending at portion <end> of curve, start of actual curve, control point 1, control point 2, end of actual curve. As you can see, this is also a Bézier curve, but since all arcs can be modeled as Béziers, the resulting curve will also look good. In any cas, you must probably fiddle a bit with the controls coordinates, but this could be calculated and also, the coordinates of the nodes could be extracted to make the result more generic.

-
Your second solution is the Right One. You can take the control points from the original curve and use them as the input to the \pgfpathcurvebetweentime call. Then you will get the right path, just shortened a little. So that does do exactly what the questioner wants. Of course, it should be nicely wrapped in a little package! – Loop Space Oct 23 '11 at 16:58

You need to play with the in and out angles. This seems to work for your specific example:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[] (n1) at (0,0) {1};
\node[] (n2) at (4,0) {2};
\draw[very thick, red, ->, shorten >=1cm]  (n1) to[out=30,in=156,relative] (n2);
\draw[->] (n1) to [bend left] (n2); % original arc
\end{tikzpicture}
\end{document}


If you actually magnify the picture a lot, it does not completely match the original path, but it is pretty close. There is probably a way to calculate the in angle, but I am not sure how, I just got there numbers by guessing and experimenting.

-