4

Is there a way to get a "3D slant" effect on tikz-cd? I mean something like the Rightarrows in the following diagram, which I made using code from another tex.SE answer: enter image description here There are still many problems with the output, such as the α⊗id_id_T label beng crooked and misaligned, the angles not being correct, and the T⊗α (first diagram, from 2-2 to 1-3) and α (second diagram, from 4-2 to 3-3) labels having to be added manually using a phantom arrow, as slanting them together with their 2-arrows made it hard to read...

Here is the code for the above image:

\newsavebox{\BoxOne}
\savebox{\BoxOne}{
    \begin{tikzcd}[row sep=4.5em, column sep=4.5em, background color=backgroundColor, ampersand replacement=\&]
        {}
        \arrow[d, "\alpha\tcirc\biid_{\biid_{\monadT}}"{rotate=-140,description}, Rightarrow]
        \\
        {}
    \end{tikzcd}
}
\newsavebox{\BoxThree}
\savebox{\BoxThree}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, background color=backgroundColor, ampersand replacement=\&]
        {}
        \arrow[d, Leftarrow]
        \\
        {}
    \end{tikzcd}
}
    \begin{tikzcd}[row sep={4.5em,between origins}, column sep={4.5em,between origins}, background color=backgroundColor, ampersand replacement=\&]
        \monadT^{4}
        \arrow[rr, "\monadT^{2}\tcirc\mu"description]
        \arrow[dd, "\mu\tcirc\monadT^{2}"'description]
        \arrow[rd, "\monadT\tcirc(\mu\tcirc\monadT)"{name=1,description}]
        \&
        \&
        \monadT^{3}
        \arrow[rd, "\monadT\tcirc\mu"description]
        \&
        \\
        \&
        \monadT^{3}
        \arrow[rr, "\monadT\tcirc\mu"description]
        \arrow[dd, "\mu\tcirc\monadT"description]
        \&
        \&
        \monadT^{2}
        \arrow[dd, "\mu"description]
        \\
        \monadT^{3}
        \arrow[rd, "\mu\tcirc\monadT"{name=2,description}]
        \&
        \&
        \&
        \\
        \&
        \monadT^{2}
        \arrow[rr, "\mu"'description]
        \&\&
        \monadT^{1}
        % 2-Arrows
        \arrow[from=3-1,to=2-2,"\rotslant{-30}{-30}{\rotatebox{140}{\usebox{\BoxOne}}}",phantom,yshift=-0.25em]
        \arrow[from=2-2,to=1-3,"\rotslant{-22.5}{+22.5}{\rotatebox{0}{\usebox{\BoxThree}}}",phantom]
        \arrow[from=2-2,to=1-3,"\scalebox{0.75}{$\monadT\tcirc\alpha$}"description,phantom]
        \arrow[from=4-2,to=2-4,"\alpha"description,Rightarrow,shorten=3.0em]
    \end{tikzcd}
&=
\newsavebox{\BoxTwo}
\savebox{\BoxTwo}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, background color=backgroundColor, ampersand replacement=\&]
        {}
        \arrow[d, "\alpha"{rotate=-140,description}, Rightarrow]
        \\
        {}
    \end{tikzcd}
}
\newsavebox{\BoxThree}
\savebox{\BoxThree}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, background color=backgroundColor, ampersand replacement=\&]
        {}
        \arrow[d, Leftarrow]
        \\
        {}
    \end{tikzcd}
}
\begin{tikzcd}[row sep={4.5em,between origins}, column sep={4.5em,between origins}, background color=backgroundColor, ampersand replacement=\&]
    \monadT^{4}
    \arrow[rr, "\monadT^{2}\tcirc\mu"description]
    \arrow[dd, "\mu\tcirc\monadT^{2}"'description]
    \&
    \&
    \monadT^{3}
    \arrow[dd, "\mu\tcirc\monadT"description,dashed]
    \arrow[rd, "\monadT\tcirc\mu"description]
    \&
    \\
    \&
    \&
    \&
    \monadT^{2}
    \arrow[dd, "\mu"]
    \\
    \monadT^{3}
    \arrow[rr, "\monadT\tcirc\mu"description,dashed]
    \arrow[rd, "\mu\tcirc\monadT"{name=2,description}]
    \&
    \&
    \monadT^{2}
    \arrow[rd, "\mu"description,dashed]
    \&
    \\
    \&
    \monadT^{2}
    \arrow[rr, "\mu"']
    \&\&
    \monadT^{1}
    % 2-Arrows
    \arrow[from=3-3,to=2-4,"\rotslant{-30}{-30}{\rotatebox{140}{\usebox{\BoxTwo}}}",phantom,yshift=-0.25em]
    \arrow[from=4-2,to=3-3,"\rotslant{-22.5}{+22.5}{\rotatebox{0}{\usebox{\BoxThree}}}",phantom]
    \arrow[from=4-2,to=3-3,"\scalebox{0.75}{$\alpha$}"description,phantom]
    \arrow[from=3-1,to=1-3,"\alpha_{\alpha}^{-1}"description,Rightarrow,shorten=3.0em]
\end{tikzcd}

The \rotslant macro there comes from the tex.SE answer I mentioned before.

Also, is it possible to get such an effect for 2-arrows on more general curved surfaces (i.e. other than 2-arrows on faces of cubes), such as the ones in the diagram enter image description here ?

Edit: Here's a compilable code for the first image (with a slightly different output (e.g. fonts, spacing), but with the same behaviour for the 3D arrows):

\documentclass[english,11pt]{standalone}
\RequirePackage{luatex85}
\newcommand{\monadT}{\mathrm{T}}
\newcommand{\biid}{\mathsf{id}}
\newcommand{\tcirc}{\otimes}
\usepackage{tikz}
\usepackage{tikz-cd}
\usetikzlibrary{arrows.meta,calc,positioning,decorations.markings,fit,patterns,decorations.pathreplacing,3d}
\usepackage{libertine}
\usepackage[libertine]{newtxmath}
% 3D Rotate
\usepackage{fp}
\newsavebox\foobox
\newcommand\slbox[2]{%
    \FPdiv{\result}{#1}{57.296}% CONVERT deg TO rad
    \FPtan{\result}{\result}%
    \slantbox[\result]{#2}%
}%
\newcommand{\slantbox}[2][30]{%
        \mbox{%
        \sbox{\foobox}{#2}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
}}
\newcommand\rotslant[3]{\rotatebox{#1}{\slbox{#2}{#3}}}
\begin{document} 
\newsavebox{\BoxOne}
\savebox{\BoxOne}{
    \begin{tikzcd}[row sep=4.5em, column sep=4.5em, ampersand replacement=\&]
        {}
        \arrow[d, "\alpha\tcirc\biid_{\biid_{\monadT}}"{rotate=-140,description}, Rightarrow]
        \\
        {}
    \end{tikzcd}
}
\newsavebox{\BoxThree}
\savebox{\BoxThree}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, ampersand replacement=\&]
        {}
        \arrow[d, Leftarrow]
        \\
        {}
    \end{tikzcd}
}
    \begin{tikzcd}[row sep={4.5em,between origins}, column sep={4.5em,between origins}, ampersand replacement=\&]
        \monadT^{4}
        \arrow[rr, "\monadT^{2}\tcirc\mu"description]
        \arrow[dd, "\mu\tcirc\monadT^{2}"'description]
        \arrow[rd, "\monadT\tcirc(\mu\tcirc\monadT)"{name=1,description}]
        \&
        \&
        \monadT^{3}
        \arrow[rd, "\monadT\tcirc\mu"description]
        \&
        \\
        \&
        \monadT^{3}
        \arrow[rr, "\monadT\tcirc\mu"description]
        \arrow[dd, "\mu\tcirc\monadT"description]
        \&
        \&
        \monadT^{2}
        \arrow[dd, "\mu"description]
        \\
        \monadT^{3}
        \arrow[rd, "\mu\tcirc\monadT"{name=2,description}]
        \&
        \&
        \&
        \\
        \&
        \monadT^{2}
        \arrow[rr, "\mu"'description]
        \&\&
        \monadT^{1}
        % 2-Arrows
        \arrow[from=3-1,to=2-2,"\rotslant{-30}{-30}{\rotatebox{140}{\usebox{\BoxOne}}}",phantom,yshift=-0.25em]
        \arrow[from=2-2,to=1-3,"\rotslant{-22.5}{+22.5}{\rotatebox{0}{\usebox{\BoxThree}}}",phantom]
        \arrow[from=2-2,to=1-3,"\scalebox{0.75}{$\monadT\tcirc\alpha$}"description,phantom]
        \arrow[from=4-2,to=2-4,"\alpha"description,Rightarrow,shorten=3.0em]
    \end{tikzcd}
=
\newsavebox{\BoxTwo}
\savebox{\BoxTwo}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, ampersand replacement=\&]
        {}
        \arrow[d, "\alpha"{rotate=-140,description}, Rightarrow]
        \\
        {}
    \end{tikzcd}
}
\newsavebox{\BoxFour}
\savebox{\BoxFour}{
    \begin{tikzcd}[row sep=3.6em, column sep=3.6em, ampersand replacement=\&]
        {}
        \arrow[d, Leftarrow]
        \\
        {}
    \end{tikzcd}
}
\begin{tikzcd}[row sep={4.5em,between origins}, column sep={4.5em,between origins}, ampersand replacement=\&]
    \monadT^{4}
    \arrow[rr, "\monadT^{2}\tcirc\mu"description]
    \arrow[dd, "\mu\tcirc\monadT^{2}"'description]
    \&
    \&
    \monadT^{3}
    \arrow[dd, "\mu\tcirc\monadT"description,dashed]
    \arrow[rd, "\monadT\tcirc\mu"description]
    \&
    \\
    \&
    \&
    \&
    \monadT^{2}
    \arrow[dd, "\mu"]
    \\
    \monadT^{3}
    \arrow[rr, "\monadT\tcirc\mu"description,dashed]
    \arrow[rd, "\mu\tcirc\monadT"{name=2,description}]
    \&
    \&
    \monadT^{2}
    \arrow[rd, "\mu"description,dashed]
    \&
    \\
    \&
    \monadT^{2}
    \arrow[rr, "\mu"']
    \&\&
    \monadT^{1}
    % 2-Arrows
    \arrow[from=3-3,to=2-4,"\rotslant{-30}{-30}{\rotatebox{140}{\usebox{\BoxTwo}}}",phantom,yshift=-0.25em]
    \arrow[from=4-2,to=3-3,"\rotslant{-22.5}{+22.5}{\rotatebox{0}{\usebox{\BoxFour}}}",phantom]
    \arrow[from=4-2,to=3-3,"\scalebox{0.75}{$\alpha$}"description,phantom]
    \arrow[from=3-1,to=1-3,"\alpha_{\alpha}^{-1}"description,Rightarrow,shorten=3.0em]
\end{tikzcd}
\end{document}
Emily
  • 211
  • 1
    The pastebin doesn't exist anymore, please add code directly to your question, instead of using external sites. – Torbjørn T. Jul 09 '20 at 21:50
  • @TorbjørnT. Oh that was unexpected! (I thought pastebin was more reliable :/) Thanks for letting me know; I have added the code to the question now. – Emily Jul 09 '20 at 22:15
  • Could you provide complete example that can compile? – ZhiyuanLck Jul 10 '20 at 05:03
  • @ZhiyuanLck Sure! I have added it to the question too. (The output is slightly different (e.g. the spacing around ⊗'s and fonts), but the important parts are the same) – Emily Jul 10 '20 at 05:23

1 Answers1

5

UPDATE

Simplify plane style

ANSWER

I define a key plane={<coord-1> and <coord-2>} to let the path be put on specific plane that depends on x unit vector (0, 0) --> <coord-1> and y unit vector (0, 0) --> <coord-2>.

In your case, row sep and column sep are both between origins, so you can calculate a precise result of two vectors. enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3d, cd}
\newcommand{\monadT}{\mathrm{T}}
\newcommand{\biid}{\mathsf{id}}
\newcommand{\tcirc}{\otimes}
\makeatletter
\tikzset{
  plane/.style args={#1and#2}{
    plane x={#1},
    plane y={#2},
    canvas is plane,
  }
}
\makeatother

\begin{document} \begin{tikzcd}[row sep={4.5em,between origins}, column sep={4.5em,between origins}, ampersand replacement=&amp;] \monadT^{4} \arrow[rr, "\monadT^{2}\tcirc\mu"description] \arrow[dd, "\mu\tcirc\monadT^{2}"'description] \arrow[rd, "\monadT\tcirc(\mu\tcirc\monadT)"{name=1,description}] &amp; &amp; \monadT^{3} \arrow[rd, "\monadT\tcirc\mu"description] &amp; \ &amp; \monadT^{3} \arrow[rr, "\monadT\tcirc\mu"description] \arrow[dd, "\mu\tcirc\monadT"description] &amp; &amp; \monadT^{2} \arrow[dd, "\mu"description] \ \monadT^{3} \arrow[rd, "\mu\tcirc\monadT"{name=2,description}] &amp; &amp; &amp; \ &amp; \monadT^{2} \arrow[rr, "\mu"'description] &amp;&amp; \monadT^{1} % 2-Arrows \arrow[from=3-1,to=2-2,"\alpha\tcirc\biid_{\biid_{\monadT}}"{description, plane={(2^.5/2, -2^.5/2) and (0, 1)}, text=red}, Rightarrow] \arrow[from=2-2,to=1-3,"\monadT\tcirc\alpha"{description, plane={(1, 0) and (-2^.5/2, 2^.5/2)}, text=red}] \end{tikzcd} \end{document}

As for putting a piece of text on curved surface, I did not get a good way to do this. Following code is just for fun.

enter image description here

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{calc, 3d, cd, decorations.markings}
\makeatletter
\newcounter{tangent}
\tikzset{
  tangent/.style args={#1:#2:#3}{
    postaction=decorate,
    decoration={
      markings,
      mark=at position 0 with {
        \setcounter{tangent}{0}
        \pgfmathparse{(#2-#1)/(#3-1)}
        \global\let\mystep\pgfmathresult
      },
      mark=between positions #1 and #2 step \mystep with {
        \stepcounter{tangent}
        \edef\index{\number\value{tangent}}
        \typeout{xxx \index}
        \coordinate (t-o-\index) at (0, 0);
        \coordinate (t-x-\index) at (1, 0);
        \coordinate (t-y-\index) at (0, 1);
      }
    },
  },
  plane/.style args={#1and#2}{
    plane x={#1},
    plane y={#2},
    canvas is plane,
  }
}
\makeatother

\begin{document} \begin{tikzpicture}[thick] \draw (0, 0) -- (0, 2) (11, 0) -- (11, 2); \path[tangent=.1:.9:11] (0, 0) arc (180:360:5.5cm and 2cm); \draw (0, 0) arc (180:360:5.5cm and 2cm) \foreach \i in {1,...,11} { node[plane={($(t-x-\i)-(t-o-\i)$) and (0, 1)}, above, align=center] at (t-o-\i) {\i\\i\\i\\i} }; \coordinate (a) at (5.5, 16); \draw (a) -- (0, 2) (a) -- (11, 2); \path[tangent=.1:.9:11] (0, 2) arc (180:360:5.5cm and 2cm); \draw (0, 2) arc (180:360:5.5cm and 2cm) \foreach \i in {1,...,11} { node[ plane={($(t-x-\i)-(t-o-\i)$) and ($(t-o-\i)!1cm!(a)-(t-o-\i)$)}, above, align=center, inner sep=0pt, ] at (t-o-\i) {\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\\i\} }; \end{tikzpicture} \end{document}

ZhiyuanLck
  • 4,516
  • My sincere congratulations for your nice code. +1 – Sebastiano Jul 10 '20 at 09:05
  • Thanks for your appretiation! – ZhiyuanLck Jul 10 '20 at 11:59
  • 1
    You're very nice user also. – Sebastiano Jul 10 '20 at 12:01
  • Wow! I second Sebastiano on both accounts! This is very impressive and you're very nice! :)) – Emily Jul 10 '20 at 22:36
  • Would it be okay to ask another question on doing 3d stuff with tikz? I'm thinking about making (on the long run) something like a 3d-tikz-cd, by which I mean something that would also work for 3d grids, rather than just tikz-cd's 2d grid made with &'s and \'s. (E.g. i'd want the code A & B \ C & D \3d A' & B' \ C' & D' to produce a cube with faces ABCD and A'B'C'D'.) Do you have any recommendations of packages or libraries that could get me started at figuring out how to build such a function in tikz-cd? – Emily Jul 10 '20 at 22:41
  • E.g. I hear that tikz-3dplot is great for working in 3D with tikz; do you think that would be a good way to go? – Emily Jul 10 '20 at 22:42
  • You can open another question, I'll give an examplt if I have time. But if you want it to be as powerful as tikz-cd, it will be a big work. – ZhiyuanLck Jul 11 '20 at 04:26
  • @ZhiyuanLck Thank you! I opened a question here. I do plan to make it as powerful as tikz-cd, so it would indeed be a big undertaking (hence the "on the long run" :P) – Emily Jul 11 '20 at 23:22
  • 1
    I thought things again and I think a 3d tikz-cd is probably overkill, so I deleted the question. Again, thank you very much for your awesome answer, @ZhiyuanLck! – Emily Jul 12 '20 at 04:50