quiver
quiver copied to clipboard
Bug with `curve` when distance is too small
The following looks rather horrible:
\documentclass{article} \usepackage{quiver} \usepackage{tikz-cd} \usepackage{amsmath} \usetikzlibrary{nfold} \DeclareMathOperator{\Spaces}{Spaces}
\usepackage[english]{babel}
% Set page size and margins % Replace
letterpaper' with
a4paper' for UK/EU standard size \usepackage[letterpaper,top=2cm,bottom=2cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
% Useful packages \usepackage{amsmath} \usepackage{graphicx} \usepackage[colorlinks=true, allcolors=blue]{hyperref}
\title{Your Paper} \author{You}
\begin{document}
% https://q.uiver.app/#q=WzAsMixbMCwwLCJhIl0sWzEsMCwiYiJdLFsxLDAsImciLDAseyJjdXJ2ZSI6LTF9XSxbMCwxLCJmIiwwLHsiY3VydmUiOi0xfV0sWzMsMiwiIiwwLHsibGV2ZWwiOjEsInN0eWxlIjp7Im5hbWUiOiJhZGp1bmN0aW9uIn19XV0= [\begin{tikzcd}[ampersand replacement=&] {\Spaces} & {\Spaces_{\le n}} \arrow[""{name=0, anchor=center, inner sep=0}, "\Omega^n_+", curve={height=-6pt}, from=1-2, to=1-1] \arrow[""{name=1, anchor=center, inner sep=0}, "\Sigma^n_+", curve={height=-6pt}, from=1-1, to=1-2] \arrow["\dashv"{anchor=center, rotate=-90}, draw=none, from=1, to=0] \end{tikzcd}] \end{document}`
Presumably there is a bug in quiver.sty?
Could you put your code in a code block, so I can copy it properly, and could you include a screenshot of what the diagram looks like for you?
Sure.
\documentclass{article}
\usepackage{quiver}
\usepackage{tikz-cd}
\usepackage{amsmath}
\usetikzlibrary{nfold}
\DeclareMathOperator{\Spaces}{Spaces}
\usepackage[english]{babel}
% Set page size and margins
% Replace `letterpaper' with `a4paper' for UK/EU standard size
\usepackage[letterpaper,top=2cm,bottom=2cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
% Useful packages
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage[colorlinks=true, allcolors=blue]{hyperref}
\title{Your Paper}
\author{You}
\begin{document}
% https://q.uiver.app/#q=WzAsMixbMCwwLCJhIl0sWzEsMCwiYiJdLFsxLDAsImciLDAseyJjdXJ2ZSI6LTF9XSxbMCwxLCJmIiwwLHsiY3VydmUiOi0xfV0sWzMsMiwiIiwwLHsibGV2ZWwiOjEsInN0eWxlIjp7Im5hbWUiOiJhZGp1bmN0aW9uIn19XV0=
\[\begin{tikzcd}[ampersand replacement=\&]
{\Spaces} \& {\Spaces_{\le n}}
\arrow[""{name=0, anchor=center, inner sep=0}, "\Omega^n_+", curve={height=-6pt}, from=1-2, to=1-1]
\arrow[""{name=1, anchor=center, inner sep=0}, "\Sigma^n_+", curve={height=-6pt}, from=1-1, to=1-2]
\arrow["\dashv"{anchor=center, rotate=-90}, draw=none, from=1, to=0]
\end{tikzcd}\]
\end{document}
The output is as follows:
It can be fixed by making the spacer a little larger.
@drewheard: thanks. Here's a minimised version of the issue:
\documentclass{article}
\usepackage{quiver}
\begin{document}
\[\begin{tikzcd}
XXXXXXXXX & XXXXXXXXX
\arrow[curve, from=1-1, to=1-2]
\end{tikzcd}\]
\end{document}
Produces:
This does look like an issue with the
curve
command in the quiver.sty
package, thanks. I'll look into it.
For now, it can be addressed by increasing the spacing a little, as you pointed out.
You can easily see where the bug is by drawing out the control points. (I mean assume you come up with how to draw the control points, which is not very trivial given you're limited to use a path specification. Use a colored node suffices.)
\tikzset{curve/.style={settings={#1},to path={
node (__quiver_control1) at ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$) [red, fill, circle, inner sep=1pt] {}
node (__quiver_control2) at ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$) [blue, fill, circle, inner sep=1pt] {}
(\tikztostart)
.. controls (__quiver_control1.center) and (__quiver_control2.center)
.. (\tikztotarget)\tikztonodes}}}
Looking at the result, the problem is that the partway modifier computes the distance between the center of the nodes, instead of between the arrow endpoints as it should.
The bug comes directly from the answer https://tex.stackexchange.com/questions/556893/curve-of-fixed-height-between-two-nodes-in-tikz-cd/556902#556902 .
The only way I can think of to compute the actual distance between two nodes is the following: (draw a line between two nodes, draw nodes, then retrieve coordinate of nodes)
%! TEX program = pdflatex
\documentclass{article}
\usepackage{quiver}
\begin{document}
% A TikZ style for curved arrows of a fixed height, due to AndréC.
\tikzset{curve/.style={settings={#1},to path={
\pgfextra
\edef\quiverTmpStart{\tikztostart}
\edef\quiverTmpTarget{\tikztotarget}
\begin{pgfinterruptpath}
\draw[gray] (\quiverTmpStart) -- (\quiverTmpTarget)
node (__quiver_p1) [at start, shape=coordinate] {}
node (__quiver_p2) [at end, shape=coordinate] {}
;
\end{pgfinterruptpath}
\endpgfextra
(\tikztostart)
.. controls ($(__quiver_p1)!\pv{pos}!(__quiver_p2)!\pv{height}!270:(__quiver_p2)$)
and ($(__quiver_p1)!1-\pv{pos}!(__quiver_p2)!\pv{height}!270:(__quiver_p2)$)
.. (\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}
XXXX & XXXXXXXXX
\arrow[curve={height=3pt}, from=1-1, to=1-2]
\end{tikzcd}\]
\end{document}
While it isn't necessary to copy the \tikztostart,\tikztotarget
it seems safer to safeguard against future changes of the library.
Technically https://tex.stackexchange.com/questions/550153/how-to-get-the-length-of-an-arbitrary-path-in-tikz allows getting the length too. But that's not sufficient, we want to know what's the gap of each node.
Of course, in real code change \draw[gray]
to \path
.
Side note: if you zoom in enough you will see the arrow is not exactly symmetric. I think that's the right behavior anyway.
Or do you prefer this instead?
%! TEX program = pdflatex
\documentclass{article}
\usepackage{quiver}
\begin{document}
% A TikZ style for curved arrows of a fixed height, due to AndréC.
\tikzset{curve/.style={settings={#1},to path={
\pgfextra
\edef\quiverTmpStart{\tikztostart}
\edef\quiverTmpTarget{\tikztotarget}
\begin{pgfinterruptpath}
\draw[gray] (\quiverTmpStart) -- (\quiverTmpTarget)
node (__quiver_p1) [at start, shape=coordinate] {}
node (__quiver_p2) [at end, shape=coordinate] {}
;
\end{pgfinterruptpath}
\endpgfextra
(__quiver_p1)
.. controls ($(__quiver_p1)!\pv{pos}!(__quiver_p2)!\pv{height}!270:(__quiver_p2)$)
and ($(__quiver_p1)!1-\pv{pos}!(__quiver_p2)!\pv{height}!270:(__quiver_p2)$)
.. (__quiver_p2)\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}
XXXX & XXXXXXXXX
\arrow[curve={height=3pt}, from=1-1, to=1-2]
\end{tikzcd}\]
\end{document}
Side note: naming the style curve
seems dangerous, as the user may inadvertently also define a style named curve
and will be puzzled why quiver code break. Better name it quiver-curve
or something (although that would breaks all backwards compatibility now?)