# TikzCD decorated arrows (wavy) and to path produces nightmarish results

Based off of Wavy arrows in xy-pic and the snake lemma code in https://ctan.math.washington.edu/tex-archive/graphics/pgf/contrib/tikz-cd/tikz-cd-doc.pdf

% minimal working example (MWE)
\documentclass{article}

\usepackage{tikz-cd}
\usetikzlibrary{decorations.pathmorphing}

\begin{document}

\begin{center}
\begin{tikzcd}[
arrows={decorate, decoration={snake,segment length = 1.6mm,amplitude=0.2mm}}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l,rounded corners, to path={ -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget)}]
\end{tikzcd}
\end{center}

\end{document}


This produces

If I add decorate=false in the last arrow, it produces the much nicer

However, I am still interested in knowing if there's a way to decorate my to path arrow without things going haywire.

• Just a guess: The default rounded corners is bigger than the snake's wave and this screws up everything. How does it look when you remove that option? Aug 25 at 0:04
• @Qrrbrbirlbel it works! I suppose that's the best we can do
– D.R
Aug 25 at 0:08
• Related: tex.stackexchange.com/a/38995/86 Aug 25 at 6:15

## 2 Answers

Here are a few solutions, based on https://tex.stackexchange.com/a/38995/86 and https://tex.stackexchange.com/a/655154/86.

Rounded corners are implemented as the path is built, so it is enough to switch off the rounded corners key once the original path is built and before it is decorated.

The first solutions, based on https://tex.stackexchange.com/a/38995/86, work by switching off the rounded corners option at the end of the path construction. The catch is that by using a to path, any options given in the to path construction are executed inside a group and so are forgotten by the time the path is processed. One option would be to make a global version of the required sharp corners key, but it's also possible to use a bit of \aftergroup trickery to avoid making things global. This relied on the fact that the rounded corners key has an inbuilt conditional which is used to determine whether or not rounded corners should be considered.

There's then another way to exploit the grouping of a to path: put the rounded corners option inside the definition of the to path. Since the to path is the only element of this path construction, this means that rounded corners option is in place for the entirety of the path construction but is not in place when the snake decoration is applied.

The last solution, based on https://tex.stackexchange.com/a/655154/86, works by switching off the rounded corners just before the decoration starts.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/655090/86}

\usepackage{tikz-cd}
\usetikzlibrary{decorations.pathmorphing}

\makeatletter
% This is the key that disables rounded corners outside the group.
\tikzset{
disable rounded corners/.code={
\aftergroup\pgf@arccornersfalse
},
decorate with sharp corners/.style={
/pgf/every decoration/.append style={
/tikz/sharp corners
}
}
}
\makeatother

\begin{document}

% Version without decoration to show that the rounded corners *is* applied
\begin{center}
\begin{tikzcd}[
arrows={
%    decorate,
decoration={snake,segment length = 1.6mm,amplitude=0.2mm}
}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l, rounded corners, to path={ -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget) [disable rounded corners]}]
\end{tikzcd}
\end{center}

% Version with decoration to show that it isn't "wild"
\begin{center}
\begin{tikzcd}[
arrows={
decorate,
decoration={snake,segment length = 1.6mm,amplitude=0.2mm}}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l, rounded corners, to path={ -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget) [disable rounded corners]}]
\end{tikzcd}
\end{center}

% Version with rounded corners inside the group, no decoration
\begin{center}
\begin{tikzcd}[
arrows={
%    decorate,
decoration={snake,segment length = 1.6mm,amplitude=0.2mm}}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l, to path={[rounded corners] -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget)}]
\end{tikzcd}
\end{center}

% Version with rounded corners inside the group
\begin{center}
\begin{tikzcd}[
arrows={
decorate,
decoration={snake,segment length = 1.6mm,amplitude=0.2mm}}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l, to path={[rounded corners] -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget)}]
\end{tikzcd}
\end{center}

% Version which disables rounded corners just before the decoration starts
\begin{center}
\begin{tikzcd}[
arrows={
decorate,
decorate with sharp corners,
decoration={
snake,segment length = 1.6mm,amplitude=0.2mm}}
]
(L_1,\ldots, L_r) \arrow{r} & \big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & (D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)}) \arrow[l, rounded corners, to path={ -- ([xshift=2ex]\tikztostart.east)
|- ([yshift=1ex]\tikztotarget.north) -- (\tikztotarget)}]
\end{tikzcd}
\end{center}

\end{document}


(The picture was generated when I only had one solution - but all the decorated versions look the same.)

As @Qrrbrbirlbel commented, rounded corners does not work well with snake. But you can draw an arc with the snake decoration. One option is to remove the problematic arrow and replace it with ordinary TikZ commands using execute at end picture=.

Use |[alias=<name>]| to give names to the desired cells and then \draw the arrow.

I used tikzset to make a style called snakearrow since it needs to be referenced twice (once in the tikzcd and once for the \draw command).

Finally, I added post length=.5mm to make the end of the arrows look nicer.

Here is the code:

\documentclass{article}

\usepackage{tikz-cd}
\usetikzlibrary{decorations.pathmorphing}

\tikzset{snakearrow/.style={decorate, decoration={snake, segment length = 1.6mm, amplitude=0.2mm, post length=.5mm}}}

\begin{document}

\begin{center}
\begin{tikzcd}[
arrows={snakearrow},
execute at end picture={\draw[->, snakearrow](Z1.east) arc (-90:90:.25)--([yshift=1.25mm, xshift=2mm]Z2.north) arc (90:180:.2);}
]
(L_1,\ldots, L_r) \arrow{r} & |[alias=Z2]|\big((D_1,n_1),\ldots, (D_r,n_r)\big) \arrow{r} & |[alias=Z1]|(D_1^{n_i}, \ldots, D_r^{n_r}) \simeq (L_{\sigma(1)},\ldots, L_{\sigma(r)})
\end{tikzcd}
\end{center}

\end{document}