7

I have a tikz-cd diagram, and I would like to bend the arrows by a certain distance (so that their heights are a fixed distance from the straight line connecting the endpoints). With bend left, the height depends on the width, for example in the following diagram.

enter image description here

How can I instead specify a distance (so that I can make the arrows in the above example the same height, for instance)? The diagrams are intended to be output from a program, so it's okay if the solution involves manual calculation, but should avoid defining new macros for the purpose.

Section 52.3 of the TikZ & PGF manual seems relevant, but I couldn't work out how to use any of the options there to achieve this.

\documentclass{article}

\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, bend left]
    \arrow[from=1-2, to=1-4, bend left]
    \arrow[from=1-4, to=1-7, bend left]
\end{tikzcd}

\end{document}

I'd like to be able to control the height of arrows in any direction: e.g. the vertical and diagonal arrows below should be the same height.

enter image description here

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow[from=2-3, to=4-5, bend left]
    \arrow[from=1-1, to=2-1, bend left]
    \arrow[from=2-1, to=4-1, bend left]
    \arrow[from=1-2, to=2-3, bend left]
\end{tikzcd}
3
  • I have understood not well your question. +1. – Sebastiano Jul 31 '20 at 19:25
  • 2
    I added a new style called my curve 2 to my answer. – AndréC Aug 1 '20 at 5:16
  • 1
    See New style my curve 5 where we can control the height of the arrows in any direction. The control points are placed by default at 0.25 and 0.75 from the length of the path and at a distance of 7 mm from the path. – AndréC Aug 4 '20 at 4:52
8

Here are my proposals:

Update 6: New style my curve 7 same principle as style 5.

But with a pattern like my curve 7 = 9mm of .25

my curve 7

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

    
\tikzset{my curve 7/.style args={#1of#2}{
        to path={.. controls ($(\tikztostart)!#2!(\tikztotarget)!#1!90:(\tikztotarget)$) 
            and ($(\tikztostart)!1-#2!(\tikztotarget)!#1!90:(\tikztotarget)$) 
            .. (\tikztotarget)\tikztonodes}},
             my curve 7/.default={7mm of 0.25}}  

\begin{document}
%With the  "\textbf{my curve 7}" style you can control the height of the arrows in any direction: eg. the vertical and diagonal arrows below are the same height. 
%
% As for the previous styles, by default the control points are placed at 0.25 and 0.75 from the length of the path and at a distance of 7 mm from the path.


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow["a",blue,from=1-1, to=1-2,  my curve 7]
    \arrow["b",red,from=1-2, to=1-4,  my curve 7=7mm of .25]
    \arrow["c",violet,from=1-4, to=1-7,  my curve 7=7mm of .25]
   \end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow["d"blue,from=1-2, to=1-1,  my curve 7]
    \arrow["e"red,from=1-4, to=1-2,  my curve 7=11mm of .4]
    \arrow["f"violet,from=1-7, to=1-4,  my curve 7]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow["g",from=2-3, to=4-5,  my curve 7]
    \arrow["h",from=1-1, to=2-1,  my curve 7=11mm of .3]
    \arrow["i",from=2-1, to=4-1,  my curve 7=11mm of .3]
    \arrow["j",from=1-2, to=2-3,  my curve 7]
    \arrow["k",from=4-5, to=2-3,  my curve 7=11mm of .4]
    \arrow["l",from=2-1, to=1-1,  my curve 7]
    \arrow["m",from=4-1, to=2-1,  my curve 7]
    \arrow["n",from=2-3, to=1-2,  my curve 7=11mm of .4]
\end{tikzcd}
\end{document}

Update 5: New style my curve 6: Both arguments are now optional.

Code adapted from How to use “style n args” with three or four arguments

[enter image description here

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
%\usepackage{amsmath}

% code adapted from https://tex.stackexchange.com/questions/532341/how-to-use-style-n-args-with-three-or-four-arguments
\tikzset{my curve 6/.style={varkors settings={#1},to path={.. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!90:(\tikztotarget)$) 
            and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!90:(\tikztotarget)$$) 
            .. (\tikztotarget)\tikztonodes}},
  varkors settings/.code={\tikzset{varkor/.cd,#1}
     \def\pv##1{\pgfkeysvalueof{/tikz/varkor/##1}}},
 varkor/.cd,pos/.initial=0.25,height/.initial=7mm}
    
    

\begin{document}
%With the  "\textbf{my curve 6}"   style you can control the height of the arrows in any direction: eg. the vertical and diagonal arrows below are the same height. Both arguments are now optional. 
%
% As for the previous styles, by default the control points are placed at 0.25 and 0.75 from the length of the path and at a distance of 7 mm from the path.


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow["a",from=1-1, to=1-2,  my curve 6]
    \arrow["b",from=1-2, to=1-4,  my curve 6={pos=.25}]
    \arrow["c",from=1-4, to=1-7,  my curve 6={height=7mm}]
   \end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow["d",from=1-2, to=1-1,  my curve 6]
    \arrow["e",from=1-4, to=1-2,  my curve 6={pos=.4,height=11mm}]
    \arrow["f",from=1-7, to=1-4,  my curve 6]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow["g",from=2-3, to=4-5,  my curve 6]
    \arrow["h",from=1-1, to=2-1,  my curve 6={pos=.3,height=11mm}]
    \arrow["i",from=2-1, to=4-1,  my curve 6={pos=.3,height=11mm}]
    \arrow["j",from=1-2, to=2-3,  my curve 6]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow["k",from=4-5, to=2-3,  my curve 6={pos=.4,height=11mm}]
    \arrow["l",from=2-1, to=1-1,  my curve 6]
    \arrow["m",from=4-1, to=2-1,  my curve 6]
    \arrow["n",from=2-3, to=1-2,  my curve 6={pos=.4}]
\end{tikzcd}
\end{document}

Update 4: Style my curve 5

With the my curve 5 style you can control the height of the arrows in any direction: eg. the vertical and diagonal arrows below are the same height.

As for the previous styles, by default the control points are placed at 0.25 and 0.75 from the length of the path and at a distance of 7 mm from the path.

screenshot

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\usepackage{amsmath}

\tikzset{my curve 5/.style 2 args={
        to path={.. controls ($(\tikztostart)!#1!(\tikztotarget)!#2!90:(\tikztotarget)$) 
            and ($(\tikztostart)!1-#1!(\tikztotarget)!#2!90:(\tikztotarget)$) 
            .. (\tikztotarget)\tikztonodes}},
             my curve 5/.default={.25}{7mm}
} 

\begin{document}
%With the  "\textbf{my curve 5}"   style you can control the height of the arrows in any direction: eg. the vertical and diagonal arrows below are the same height.
%
% As for the previous styles, by default the control points are placed at 0.25 and 0.75 from the length of the path and at a distance of 7 mm from the path.


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2,  my curve 5]
    \arrow[from=1-2, to=1-4,  my curve 5]
    \arrow[from=1-4, to=1-7,  my curve 5]
   \end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-2, to=1-1,  my curve 5]
    \arrow[from=1-4, to=1-2,  my curve 5]
    \arrow[from=1-7, to=1-4,  my curve 5]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow[from=2-3, to=4-5,  my curve 5]
    \arrow[from=1-1, to=2-1,  my curve 5={.3}{11mm}]
    \arrow[from=2-1, to=4-1,  my curve 5={.3}{11mm}]
    \arrow[from=1-2, to=2-3,  my curve 5]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet \\
    \bullet && \bullet \\
    \\
    \bullet &&&& \bullet
    \arrow[from=4-5, to=2-3,  my curve 5={.3}{9mm}]
    \arrow[from=2-1, to=1-1,  my curve 5]
    \arrow[from=4-1, to=2-1,  my curve 5]
    \arrow[from=2-3, to=1-2,  my curve 5={.3}{9mm}]
\end{tikzcd}

\end{document}

Update 3: Style my curve 4 with two parameters that defaults to 0.25 and 7mm.

my curve 4

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\usepackage{amsmath}

\tikzset{my curve 4/.style 2 args={
        to path={.. controls ($(\tikztostart)!#1!(\tikztotarget)+(0,#2)$$) 
            and ($(\tikztostart)!1-#1!(\tikztotarget)+(0,#2)$$) 
            .. (\tikztotarget)\tikztonodes}},
            my curve 4/.default={.25}{7mm}
} 

\begin{document}
\begin{minipage}{.65\textwidth}

\begin{enumerate}

\item By default "$\textcolor{blue}{\text{my curve 4}}$".

The control points are placed at 0.25 and 0.75 of the path length, the height is 7 mm. 


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 4]
    \arrow[from=1-2, to=1-4, my curve 4]
    \arrow[from=1-4, to=1-7, my curve 4]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-2, to=1-1, my curve 4]
    \arrow[from=1-4, to=1-2, my curve 4]
    \arrow[from=1-7, to=1-4, my curve 4]
\end{tikzcd}

\item You can change the location of these control points.

Here \mbox{"\textcolor{blue}{$\text{my curve 4=\{.4\}\{5mm\}}$"}}.

They are located at 0.4 and 0.6, the height is 5 mm.


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 4={.4}{5mm}]
    \arrow[from=1-2, to=1-4, my curve 4={.4}{5mm}]
    \arrow[from=1-4, to=1-7, my curve 4={.4}{5mm}]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-2, to=1-1, my curve 4={.4}{5mm}]
    \arrow[from=1-4, to=1-2, my curve 4={.4}{5mm}]
    \arrow[from=1-7, to=1-4, my curve 4={.4}{5mm}]
\end{tikzcd}

\item Here: "\textcolor{blue}{$\text{my curve 4=\{.3\}\{9mm\}}$}".

They are located at 0.3 and 0.7, the height is 9 mm.


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 4={.3}{9mm}]
    \arrow[from=1-2, to=1-4, my curve 4={.3}{9mm}]
    \arrow[from=1-4, to=1-7, my curve 4={.3}{9mm}]
\end{tikzcd}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-2, to=1-1, my curve 4={.3}{9mm}]
    \arrow[from=1-4, to=1-2, my curve 4={.3}{9mm}]
    \arrow[from=1-7, to=1-4, my curve 4={.3}{9mm}]
\end{tikzcd}
\end{enumerate}
\end{minipage}
\end{document}

Update 2: Style my curve 3 with a parameter that defaults to 0.25.

my curve 3

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\usepackage{amsmath}

\tikzset{my curve 3/.style={
        to path={([xshift=-3pt]\tikztostart.north east) 
            .. controls ($(\tikztostart)!#1!(\tikztotarget)+(0,.7)$$) 
            and ($(\tikztostart)!1-#1!(\tikztotarget)+(0,.7)$$) 
            .. ([xshift=3pt]\tikztotarget.north west)\tikztonodes}},
            my curve 3/.default=.25
} 

\begin{document}
\begin{enumerate}

\item By default  "$\textcolor{blue}{\text{my curve 3}}$" the control points are placed at 0.25 and 0.75 of the path length. 


\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 3]
    \arrow[from=1-2, to=1-4, my curve 3]
    \arrow[from=1-4, to=1-7, my curve 3]
\end{tikzcd}

\item You can change the location of these control points, here \mbox{"\textcolor{blue}{$\text{my curve 3}=.4$"}} they are located at 0.4 and 0.6.

 Indeed: $1-0.4=0.6$. 

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 3=.4]
    \arrow[from=1-2, to=1-4, my curve 3=.4]
    \arrow[from=1-4, to=1-7, my curve 3=.4]
\end{tikzcd}

\item Here they are located at 0.3 and 0.7. "\textcolor{blue}{$\text{my curve 3}=.3$}"

 Indeed: \mbox{$1-0.3=0.7$}. 

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 3=.3]
    \arrow[from=1-2, to=1-4, my curve 3=.3]
    \arrow[from=1-4, to=1-7, my curve 3=.3]
\end{tikzcd}

\end{enumerate}
\end{document}

Update 1: New style my curve 2

It uses the calc library

my curve 2

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

\tikzset{my curve 2/.style={to path={([xshift=-3pt]\tikztostart.north east) .. controls ($(\tikztostart)!.25!(\tikztotarget)+(0,.7)$) and ($(\tikztostart)!.75!(\tikztotarget)+(0,.7)$) .. ([xshift=3pt]\tikztotarget.north west)\tikztonodes}}}

\begin{document}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve 2]
    \arrow[from=1-2, to=1-4, my curve 2]
    \arrow[from=1-4, to=1-7, my curve 2]
\end{tikzcd}
\end{document}

Old answer : style my curve

screenshot

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

\tikzset{my curve/.style={to path={([xshift=-3pt]\tikztostart.north east) .. controls ++(80:5ex) and ++(100:5ex) .. ([xshift=3pt]\tikztotarget.north west)\tikztonodes}}}

\begin{document}

\begin{tikzcd}
    \bullet & \bullet && \bullet &&& \bullet
    \arrow[from=1-1, to=1-2, my curve]
    \arrow[from=1-2, to=1-4, my curve]
    \arrow[from=1-4, to=1-7, my curve]
\end{tikzcd}

\end{document}
18
  • 1
    See the new style my curve 4 – AndréC Aug 3 '20 at 19:11
  • 1
    I want to improve the code, but I don't quite understand what you just said. Can you illustrate what you want to achieve with a freehand figure? – AndréC Aug 3 '20 at 21:31
  • 1
    See the new style my curve 5 – AndréC Aug 4 '20 at 4:47
  • 1
    Check out the update: all styles now support labels (unless I made a mistake). – AndréC Aug 4 '20 at 11:56
  • 1
    @varkor Yes, please do, thank you. I haven't had time to think about the following question yet (to shorten the arrow).. As soon as I have time, I will get started. Have a good evening. – AndréC Nov 10 '20 at 19:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.