I am drawing curved arrows in tikz-cd, using the method devised by @AndréC in this answer. There are situations where I want to shorten these arrows, proportional to their arc length. However, the naïve solution (using shorten) is not suitable, as it creates distorted curves (as discussed, for instance, in this question). As an example (Example 1), the following two curves have the same input path, but the red curve has been shortened. What should happen is the red curve should overlay the black curve.
Note that it is not just the position of the shortened curve that is incorrect: the shape is incorrect too: in the example (Example 2) below, I've positioned the curves so they have the same apex, but the shortened curve does not overlay the original (the amount of distortion depends on the curve width and height).
The other issue with shorten is that it requires an absolute length to shorten by, whereas I want to specify it proportionally with respect to the length of the curve itself.
I attempted to manually draw an arrow head with decorations.markings, but this does not properly calculate the right size for the arrowhead (or take into account the existing style of the head or tail). In the example below (Example 3), the arrow head further up the curve should be the same size as the one at the tip.
My idea was to shorten this arrow using a custom dash pattern, but this seems like a hack that is likely in practice to fail in edge cases. Ideally, the curve path itself should be changed, which would handle the existing style/arrowheads/tails/etc. The option pgfpathcurvebetweentime seemed like a possible solution, but I could not figure out how to integrate it with the custom curve style in the two examples.
How might one add an option to the custom curve style to allow the curve to be shortened (e.g. curve={height=-40pt, shorten=0.2})? In practice, shortening symmetrically from both ends is usually sufficient, but having options to shorten the start and end differently would be even better if it doesn't add much extra complexity.
For a demonstration of what I intend by "shortening a curved arrow", see @Thruston's example.
Example 1
\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\begin{document}
{\tikzset{curve/.style={settings={#1},to path={(\tikztostart)
.. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
.. (\tikztotarget)\tikztonodes}},
settings/.code={\tikzset{quiver/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
quiver/.cd,pos/.initial=0.35,height/.initial=0}
[\begin{tikzcd}
{\bullet} & {\bullet}
\arrow[from=1-1, to=1-2, curve={height=-40pt}, shorten <= 30pt, shorten >= 30pt, color=red]
\arrow[from=1-1, to=1-2, curve={height=-40pt}]
\end{tikzcd}]}
\end{document}
Example 2
\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\begin{document}
{\tikzset{curve/.style={settings={#1},to path={(\tikztostart)
.. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
.. (\tikztotarget)\tikztonodes}},
settings/.code={\tikzset{quiver/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
quiver/.cd,pos/.initial=0.35,height/.initial=0}
[\begin{tikzcd}
{\bullet} &&& {\bullet}
\arrow[from=1-1, to=1-4, curve={height=-60pt}, shorten <= 30pt, shorten >= 30pt, color=red, yshift=-11pt]
\arrow[from=1-1, to=1-4, curve={height=-60pt}]
\end{tikzcd}]}
\end{document}
Example 3
\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\begin{document}
{\tikzset{curve/.style={settings={#1},to path={(\tikztostart)
.. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
.. (\tikztotarget)\tikztonodes},
% Arrow head and tail
decoration={
markings,
mark=at position 0.8 with {\arrow{>}}}
, postaction={decorate}},
%
settings/.code={\tikzset{quiver/.cd,#1}
\def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
quiver/.cd,pos/.initial=0.35,height/.initial=0}
[\begin{tikzcd}
{\bullet} & {\bullet}
\arrow[Rightarrow, from=1-1, to=1-2, curve={height=-40pt}]
\end{tikzcd}]}
\end{document}











yshift=5pt? – AndréC Oct 28 '20 at 12:02tikz-cd. Can you use this way or shortening to anything: https://tex.stackexchange.com/questions/577430/is-there-an-empty-arrow-relative-length-to-sep-option – hpekristiansen Jan 03 '21 at 20:11sepused like that. I think if you receive an answer to your question (e.g. about passing a relative length tosep), it may also apply to my question. – varkor Jan 03 '21 at 22:36