[Tex/LaTex] Arrow length in tikz-cd diagrams

tikz-cd

Is there an easy way to modify the length of an arrow between two nodes in a tikz-cd diagram (while keeping the distance between the nodes fixed)?

For example, the diagonal arrow in the diagram

\begin{tikzcd}[column sep = large, row sep = large]
    * \dar \rar &* \dar \dlar[Rightarrow]{}    \\ 
    * \rar &*
\end{tikzcd}

would look a lot better for what I need (it's an arrow between the two paths in the diagram, not between the nodes) if it were, say, half as long.
This could be accomplished by changing the start and end anchor coordinates, but that's unwieldy and scales horribly if you need to do it repeatedly in diagrams of different shapes.

Best Answer

Improved version

In this improved version, you can apply a scaling factor to the arrow:

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings,intersections}

\tikzset{%
scalearrow/.style n args={3}{
  decoration={
    markings,
    mark=at position (1-#1)/2*\pgfdecoratedpathlength
      with {\coordinate (#2);},
    mark=at position (1+#1)/2*\pgfdecoratedpathlength
      with {\coordinate (#3);},
    },
  postaction=decorate,
  }
}

\begin{document}

\noindent
Scaling factor=1 (no scaling):\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={1}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)]  \\ 
C \rar & D    
\end{tikzcd}
\par\medskip

\noindent
Scaling factor=0.5:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={0.5}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)]  \\ 
C \rar & D    
\end{tikzcd}

\par\medskip

\noindent
Two arrows, each with scaling factor=0.3333:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A 
  \dar\rar 
& 
B
  \dar
  \dlar[phantom,scalearrow={0.3333}{starta}{enda}]
  \arrow[dr,Rightarrow,to path= (starta) -- (enda)] & 
C 
  \dar\lar 
\\ 
D \rar 
& 
E
& 
F
  \lar
  \ular[phantom,scalearrow={0.3333}{startb}{endb}]
  \arrow[ul,Rightarrow,to path= (startb) -- (endb)] 
\end{tikzcd}

\end{document}

enter image description here

The idea is to measure the path length using a decoration and \pgfdecoratedpathlength and to place two marks along the path such that the distance between those marks is the path length scaled by the desired factor.

This is achieved by using a "phantom" arrow with the scalearrow style; in this style you set the scaling factor (first argument for the style) and two names internally used for the start and end of the scaled path so, for example,

\dar[phantom,scalearrow={0.3333}{name1}{name2

places a downwards arrow from the current node (let's refer to it as X) to the node below it (let's refer to it as Y) and sets two internal coordinates called name1 and name2 at the exact position along the path from X to Y in such a way that now you can use those names to draw the scaled arrow (using a factor of 0.3333 for the scaling) using, for example

\arrow[d,Rightarrow,to path= (name1) -- (name2)]

First version

One option using shorten:

\documentclass{article}
\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[column sep = large, row sep = large]
    * \dar \rar &* \dar \dlar[Rightarrow,shorten >= 10pt,shorten <= 10pt]{}    \\ 
    * \rar &*
\end{tikzcd}

\end{document}

enter image description here

Related Question