10

I would like to recreate the following image in tikz, without the d partModular S and T transformation taken from source: https://www.researchgate.net/figure/Modular-transformations-for-the-Torus-shown-in-a-generated-by-b-the-T-matrix-and_fig1_341341811, where the torus a is up in the middle and the torus b and c are under a to the left and right with the T and S arrows pointing to them.

What i got so far is that (based on Drawing Torus with semi-dashed line on it):

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{0}
\tikzset{declare function={torusx(\u,\v,\R,\r)=cos(\u)*(\R + \r*cos(\v)); 
torusy(\u,\v,\R,\r)=(\R + \r*cos(\v))*sin(\u);
torusz(\u,\v,\R,\r)=\r*sin(\v);
vcrit1(\u,\th)=atan(tan(\th)*sin(\u));% first critical v value
vcrit2(\u,\th)=180+atan(tan(\th)*sin(\u));% second critical v value
disc(\th,\R,\r)=((pow(\r,2)-pow(\R,2))*pow(cot(\th),2)+% 
pow(\r,2)*(2+pow(tan(\th),2)))/pow(\R,2);% discriminant
umax(\th,\R,\r)=ifthenelse(disc(\th,\R,\r)>0,asin(sqrt(abs(disc(\th,\R,\r)))),0);
}}

\begin{tikzpicture}[tdplot_main_coords]
\pgfmathsetmacro{\R}{4}
\pgfmathsetmacro{\r}{1}
 \draw[thick,fill=white,even odd rule,fill opacity=0.2] plot[variable=\x,domain=0:360,smooth,samples=71]
 ({torusx(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit1(\x,\tdplotmaintheta),\R,\r)}) 
 plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)}:{-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)})
 plot[variable=\x,
 domain={umax(\tdplotmaintheta,\R,\r)}:{180-umax(\tdplotmaintheta,\R,\r)},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \draw[thick] plot[variable=\x,
 domain={-180+umax(\tdplotmaintheta,\R,\r)/2}:{-umax(\tdplotmaintheta,\R,\r)/2},smooth,samples=51]
 ({torusx(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusy(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)},
 {torusz(\x,vcrit2(\x,\tdplotmaintheta),\R,\r)});
 \foreach \X  in {200}  
 {\draw[thick,dashed] 
  plot[smooth,variable=\x,domain={360+vcrit1(\X,\tdplotmaintheta)}:{vcrit2(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)});
 \draw[thick] 
  plot[smooth,variable=\x,domain={vcrit2(\X,\tdplotmaintheta)}:{vcrit1(\X,\tdplotmaintheta)},samples=71]   
 ({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)})
 node[below]{$a$};
 }
\end{tikzpicture}
\end{tikzpicture}
\end{document}

2 Answers 2

14

Purely for comparison (or, more honestly, for my own mindfulness exercise) here is a version in Metapost, which might be of interest to some users. This is wrapped up in luamplib so you need to compile it with lualatex.

enter image description here

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

    path o, u, a;
    o = fullcircle rotated 45 xscaled 89 yscaled 55;
    u = subpath (4.1, 7.9) of fullcircle xscaled 45 yscaled 26 shifted 7 up; 
    a = subpath (0, 4) of fullcircle xscaled 45 yscaled 26 shifted 3 down 
        cutbefore subpath (2, 4) of u cutafter subpath (0, 2) of u;
    path f, g; 
    f  = buildcycle(point 1 of a {direction 1 of a} .. point 1/16 of u, u, reverse a);
    g = buildcycle(o scaled 33/32 rotated 4 shifted (-2, 2), reverse o);

    path ring, loop, twist;

    ring = o xscaled 0.8 yscaled 0.65 shifted 7.5 up;
    loop = reverse fullcircle rotated 90 xscaled 23.25 yscaled 14 rotated 47;
    loop := loop shifted (point 4 of o - point 6 of loop);

    picture torus; torus = image(
        fill f withcolor 7/8;
        fill g withcolor 7/8;
        draw o;
        draw u;
        draw a;
    );

    picture A, B, C;
    interim ahangle := 30;
    interim ahlength := 3;
    A = image(
        draw subpath (2, 6) of loop withcolor 7/8[2/3 red, white];
        draw subpath (0, 2) of loop withcolor 2/3 red;
        drawarrow subpath (6, 8) of loop withcolor 2/3 red;
        label.lft("$\scriptstyle a$", point 0 of loop) withcolor 2/3 red;
        draw subpath (3.6, 4.3) of ring withpen pencircle scaled 4 withcolor white;
        drawarrow subpath (-2, 6) of ring withcolor 2/3 blue;
        label.bot("$\scriptstyle b$", point 6 of ring) withcolor 2/3 blue;
        draw torus;
    );
    C = image(
        draw subpath (2, 6) of loop withcolor 7/8[2/3 blue, white];
        drawarrow subpath (6, -2) of ring withcolor 2/3 red;
        label.bot("$\scriptstyle a$", point 6 of ring) withcolor 2/3 red;
        draw subpath (0, 1) of loop withpen pencircle scaled 4 withcolor white;
        draw subpath (0, 2) of loop withcolor 2/3 blue;
        drawarrow subpath (6, 8) of loop withcolor 2/3 blue;
        label.lft("$\scriptstyle b$", point 0 of loop) withcolor 2/3 blue;
        draw torus;
    ) shifted 68 down;
    twist = subpath (-1.5, 4.2) of ring ... point 4.9 of o {direction 4.9 of o}
      .. point 2.8 of u {direction 2.8 of u} .. {direction -1.5 of ring} cycle;
    B = image(
        draw subpath (2, 6) of loop withcolor 7/8[2/3 red, white];
        draw subpath (0, 2) of loop withcolor 2/3 red;
        drawarrow subpath (6, 8) of loop withcolor 2/3 red;
        label.lft("$\scriptstyle a$", point 0 of loop) withcolor 2/3 red;
        draw subpath (3.6, 4.3) of ring withpen pencircle scaled 4 withcolor white;
        drawarrow subpath (0, 2) of twist withcolor 2/3 blue;
        drawarrow subpath (2, 7.5) of twist withcolor 2/3 blue;
        draw subpath (7.5, 8) of twist withcolor 2/3 blue;
        drawarrow subpath (8, 8.6) of twist withcolor 7/8[2/3 blue, white];
        draw subpath (8.6, 9) of twist withcolor 7/8[2/3 blue, white];
        draw subpath (9, length(twist)) of twist withcolor 2/3 blue;
        label.urt("$\scriptstyle b$", point 7.4 of twist) withcolor 2/3 blue;
        draw torus;
    ) shifted 110 right;

    draw A;  
    draw B;
    draw C;

    bboxmargin := -2;
    path a[]; 
    a1 = point 1.75 of bbox A {dir 20} .. point 3.25 of bbox B;
    a2 = point 0.2 of bbox A {dir 250} .. point 2.8 of bbox C;

    drawarrow a1; label.top("$T$", point arctime 1/2 arclength a1 of a1 of a1);
    drawarrow a2; label.lft("$S$", point arctime 1/2 arclength a2 of a2 of a2);

    bboxmargin := 4;
    label("\small\textbf{(a)}", point 3 of bbox A);
    label("\small\textbf{(b)}", point 2.8 of bbox B);
    label("\small\textbf{(c)}", point 3.2 of bbox C);

endfig;
\end{mplibcode}
\end{document}

This is not a very flexible approach -- which is why for example I had to resort to setting the labels in \scriptstyle. To make it more general, I would have to avoid having so many "magic numbers" and try to scale all the subcomponents relative to the outer ring.

1
  • 1
    Also your code...it is very impressive.
    – Sebastiano
    Commented Nov 28, 2021 at 21:41
12

Welcome to TeX.SE!!!

That is what I'd do: a \pic for the torus in which I'e add the relevant coordinates (using the calc library). The rest is fine tuning, drawing elliptic arcs or curves (only for c). I use also the decorations.markings library for the arrows at mid-path.

This is my code:

\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{calc,decorations.markings}

\tikzset
{%
  my arrow/.style={% 
      decoration={markings,mark=at position #1 with {\arrow{latex}}},
      postaction={decorate}
      },
  pics/torus/.style={
      code={%
        \coordinate (-O) at (0,0.75);
        \coordinate (-A) at ($(-O)+(195:1.75cm and 1cm)$);
        \coordinate (-B) at ($(-O)+(210:1.75cm and 1cm)$);
        \coordinate (-C) at ($(-O)+(330:1.75cm and 1cm)$);
        \coordinate (-D) at (250:3cm and 2cm);
        \coordinate (-E) at ($(-O)+(225:1.75cm and 1cm)$);
        \coordinate (-F) at (220:3cm and 2cm);
        \coordinate (-G) at ($(-O)+(290:1.75cm and 1cm)$);
        \coordinate (-H) at (260:3cm and 2cm);
        \coordinate (-I) at ($(-O)+(220:2.25cm and 1.125cm)$);
        \fill[gray!20] (-A) arc (195:210:1.75cm and 1cm) to [out=35,in=145] (-C) to [out=140,in=30] (-A);
        \fill[gray!20] (-D) arc (250:365:3cm and 2cm)    to [out=250,in=10]  cycle; 
        \draw[very thick,black] (0,0) ellipse (3cm and 2cm);
        \draw[very thick,black] (-B) to [out=35,in=145] (-C);
        \draw[very thick,black] (-O) + (345:1.75cm and 1cm) arc (345:195:1.75cm and 1cm);
        \draw[very thick, opacity=0.3] (-E) to[out=330,in=330] (-F);
        \draw[very thick,my arrow=0.6] (-F) to[out=150,in=150] node [pos=0.6,xshift=-4mm] {$#1$} (-E) ;
% uncomment this to see the coordinates:
%        \foreach\i in {A,B,C,D,E,F,G,H,O,I}
%          \fill (-\i) circle (1pt) node [below] {$\i$};
      }}
}

\begin{document}
\begin{tikzpicture}[line cap=round]
  % torus (a)
  \node at (-3,2) {\bfseries (a)};
  \pic[draw=red,text=red] (a) at  (0,0) {torus={a}};
  \fill[white] (a-I) circle (1mm);
  \draw[blue,very thick,my arrow=0.75] (a-O) ellipse (2.25 cm and 1.125 cm) node [pos=0.75,yshift=-6mm] {$b$};
  % torus (b)
  \node at (4,2) {\bfseries (b)};
  \pic[draw=red,text=red]  (b) at  (7,0) {torus={a}};
  \fill[white] (b-I) circle (1mm);
  \draw[very thick,blue, opacity=0.3] (b-H) to [out=-10,in=190] (b-G);
  \draw[very thick,blue,my arrow=0.4] (b-G) to [out=10,in=270]  ($(b-O)+(0:2.25cm and 1.125cm)$) 
    arc (0:180:2.25cm and 1.125cm) node [pos=0.4,below] {$b$} to [out=270,in=150] (b-I) to[out=330,in=160] (b-H);
  % torus (c)
  \node at (-10,2) {\bfseries (c)};
  \pic[draw=blue,text=blue] (c) at (-7,0) {torus={b}};
  \draw[very thick,red,my arrow=0.85] ($(c-O)+(215:2.25cm and 1.125cm)$)
    arc (215:-132:2.25cm and 1.125cm) node[pos=0.85,below] {$a$};
  % Tranformations
  \draw[-latex] (-3,0.5) to[out=150,in=30]  node[midway,above] {$S$} (-4,0.5); 
  \draw[-latex]  (3,0.5) to[out=30,in=150]  node[midway,above] {$T$}  (4,0.5); 
\end{tikzpicture}
\end{document}

And the output: enter image description here

2
  • 3
    Very impressive, as always! +1
    – SebGlav
    Commented Nov 28, 2021 at 19:29
  • 3
    Thanks, @SebGlav, :D Commented Nov 28, 2021 at 20:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .