# Drawing a topological “handle” with Tikz

I'm trying to do the following drawing in Tikz:

I almost finished the leftmost picture:

\begin{tikzpicture}
\fill[blue!20] (7.5,0) ellipse (1 and .75);
\draw (7.5,0) ellipse (1 and .75);
\begin{scope}
\clip (7.5,-.9) ellipse (1 and 1.25);
\draw(7.5,1.1) ellipse (1 and 1.25);
\clip (7.5,1.1) ellipse (1 and 1.25);
\draw (7.5,-1.1) ellipse (1 and 1.25);
\fill[white] (7.5,-1.1) ellipse (1 and 1.25);
\end{scope}
\draw (7.5,0) ellipse (0.8 and .47);
\draw (7.5,.47) node[scale=0.8] {$<$} node[above] {$a$};
\node (a) at (7.61,-.142894){};
\node (b) at (8,-.649519){};
\node (c) at ($(a)!0.5!(b)$) {};
\begin{scope}[shift={(c)},x={(a)}, scale=0.7]
\draw (1,0) arc (0:180:1 and 0.3);
\draw[dashed] (-1,0) arc (180:360:1 and 0.3);
\end{scope}
\draw (7.942,-0.555) node[scale=0.8,rotate=-85] {$<$};
\draw (7.67,-0.60) node {$b$};
\end{tikzpicture}


However I failed to do the "bubble" in the first drawing and to the second one. I appreciate any help.

The closest question I found here was this one: Tikz: Once punctured torus?

However, the answers there don't solve most of my problems.

If you really intend to play with these tori, you may eventually want to switch to 3d coordinates, where it is possible to find out whether a coordinate is on the visible or hidden patch.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{60}{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.5}
\draw[thick,fill=gray,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 {300}
{\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)});
\draw[thick,-latex]
plot[smooth,variable=\x,domain={vcrit1(\X,\tdplotmaintheta)}:90,samples=71]
({torusx(\X,\x,\R,\r)},{torusy(\X,\x,\R,\r)},{torusz(\X,\x,\R,\r)});
}
\draw[thick,-latex] plot[smooth,variable=\x,domain=00:360,samples=71]
({torusx(\x,90,\R,\r)},
{torusy(\x,90,\R,\r)},
{torusz(\x,90,\R,\r)});
\begin{scope}[declare function={myu(\x)=sin(2*\x)*sin(\x);
myv(\x)=sin(2*\x)*cos(\x);}]
\draw[thick,fill=white] plot[smooth,variable=\x,domain=00:90,samples=71]
({torusx(-60+45*myu(\x),90-45*myv(\x),\R,\r)},
{torusy(-60+45*myu(\x),90-45*myv(\x),\R,\r)},
{torusz(-60+45*myu(\x),90-45*myv(\x),\R,\r)});
\end{scope}
\end{tikzpicture}
\end{document}


If you want a cartoon, consider e.g.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{arrows.meta,bending,decorations.markings,intersections}
% https://tex.stackexchange.com/a/430239/121799
\tikzset{% inspired by https://tex.stackexchange.com/a/316050/121799
arc arrow/.style args={%
to pos #1 with length #2}{
decoration={
markings,
mark=at position 0 with {\pgfextra{%
\pgfmathsetmacro{\tmpArrowTime}{#2/(\pgfdecoratedpathlength)}
\xdef\tmpArrowTime{\tmpArrowTime}}},
mark=at position {#1-\tmpArrowTime} with {\coordinate(@1);},
mark=at position {#1-2*\tmpArrowTime/3} with {\coordinate(@2);},
mark=at position {#1-\tmpArrowTime/3} with {\coordinate(@3);},
mark=at position {#1} with {\coordinate(@4);
\draw[-{Stealth[length=#2,bend]}]
(@1) .. controls (@2) and (@3) .. (@4);},
},
postaction=decorate,
},bent arrow/.style={arc arrow=to pos #1 with length 2mm},
}

\begin{document}
\begin{tikzpicture}[scale=4]
\begin{scope}[local bounding box=left]
\draw[fill=blue!20,even odd rule] (0,0) ellipse (1 and .75)
(-0.5,0) arc(120:60:1 and 1.25)  arc(-60:-120:1 and 1.25) coordinate[pos=0.25] (xt);
\draw (-0.5,0) arc(-120:-130:1 and 1.25) (0.5,0) arc(-60:-50:1 and 1.25);
\draw[bent arrow=0.2,thick,name path=b] (-65:1 and .75) to[out=40,in=10]
node[pos=0.2,right]{$b$} (xt);
\draw[dashed] (xt) to[out=-170,in=-140] (-65:1 and .75);
\draw[bent arrow=0.98,thick,name path=a] (0.8,0.05) arc(0:360:0.8 and .5)
node[pos=0.2,below]{$\ell$} node[pos=0.98,right]{$a$};
\draw[name intersections={of=a and b,by=i},fill=white] (i)
to[out=45,in=-45] ++ (0.2,0.4) to[out=135,in=45](i);
\end{scope}
%
\begin{scope}[local bounding box=right,xshift=2.5cm]
\draw[fill=blue!20,even odd rule]
(-0.7,-1) to[out=90,in=-90] (-1,0) arc(180:0:1 and .75)
to[out=-90,in=90] coordinate[pos=0.7] (ys) (0.7,-1) arc(0:180:0.7 and 0.12) coordinate[pos=0.5] (p)
(-0.5,0) arc(120:60:1 and 1.25)  arc(-60:-120:1 and 1.25) coordinate[pos=0.5] (yt);
\draw (-0.5,0) arc(-120:-130:1 and 1.25) (0.5,0) arc(-60:-50:1 and 1.25);
\draw (0.7,-1) arc(0:-180:0.7 and 0.12);
\draw[bent arrow=0.5,thick] (p) to[out=70,in=-120] (-20:0.8 and .5)
arc(-20:200:0.8 and .5) node[pos=0.5,below]{$a$}  to[out=-60,in=110] cycle;
\draw[bent arrow=0.5,thick] (p) to[out=80,in=180] node[pos=0.5,right]{$b$}  (yt);
\draw[dashed] (yt) to[out=0,in=70] (ys);
\draw[thick] (ys) to[out=-110,in=20] (p);
\end{scope}
\path (left) -- (right) node[midway,scale=2]{$\simeq$};
\end{tikzpicture}
\end{document}


Unlike in the above picture, you cannot adjust the view angle.

• Is it also easier to do the second picture with this method? – Gabriel Mar 24 at 16:32
• @GabrielRibeiro It depends on what you want to do in the end. This proposal makes more sense if you have to draw several tori with cycles and so on. If you just need two quick cartoons, this might be an overkill. – marmot Mar 24 at 17:36
• @GabrielRibeiro I also added cartoons. – marmot Mar 24 at 18:50
• This is beautiful! Thank you a lot – Gabriel Mar 24 at 19:50

Using the tqft package:

\documentclass{article}
%\url{https://tex.stackexchange.com/q/481212/86}
\usepackage{tikz}
\usetikzlibrary{
tqft,
decorations.markings,
arrows.meta,
hobby,
calc
}

\begin{document}

\begin{tikzpicture}[use Hobby shortcut]
\pic[
scale=2,
tqft,
incoming boundary components = 0,
outgoing boundary components = 2,
cobordism edge/.style={draw},
fill=gray!50,
name=top
];
\pic[
scale=2,
tqft,
incoming boundary components = 2,
outgoing boundary components = 0,
cobordism edge/.style={draw},
fill=gray!50,
name=bottom,
at=(top-outgoing boundary 1)
];
\draw[
decoration={
markings,
mark=at position .25 with {\arrow{Latex}},
},
postaction={decorate}
]
(bottom-between first incoming and last incoming) to[out=45,in=-45]  node[pos=.25,right] {$$b$$} coordinate[pos=.5] (a) (bottom-between incoming 1 and 2);
\draw[dashed] (bottom-between first incoming and last incoming) to[out=135,in=-135] (bottom-between incoming 1 and 2);
\draw[
decoration={
markings,
mark=at position .25 with {\arrow{Latex}},
mark=at position .25 with {\node[right] {$$a$$};},
},
postaction={decorate}
] ([closed]$(bottom-between first incoming and last incoming)!.5!(bottom-between incoming 1 and 2)$) .. (bottom-incoming boundary 2.north) .. ($(top-between first and last outgoing)!.5!(top-between outgoing 1 and 2)$) .. (bottom-incoming boundary 1.north);
\draw[fill=white] ([out angle=30]a) .. ++(1,.5) .. ++(.5,.6) .. ++(-.25,0) .. ([in angle=30]a);

\pic[
scale=2,
tqft,
incoming boundary components = 0,
outgoing boundary components = 2,
cobordism edge/.style={draw},
fill=gray!50,
name=secondtop,
at={(7,0)}
];
\pic[
scale=2,
tqft,
incoming boundary components = 2,
outgoing boundary components = 1,
offset=.5,
cobordism edge/.style={draw},
every outgoing boundary component/.style={transform shape,draw},
fill=gray!50,
name=secondbottom,
at=(secondtop-outgoing boundary 1)
];
\draw[
decoration={
markings,
mark=at position .5 with {\arrow{Latex}},
mark=at position .5 with {\node[right] {$$b$$};},
},
postaction={decorate}
]
(secondbottom-outgoing boundary 1.north) to[out=90,in=-135] (secondbottom-between incoming 1 and 2);
\draw (secondbottom-outgoing boundary 1.north) to[out=90,in=-135] (secondbottom-between last incoming and last outgoing);
\draw[dashed] (secondbottom-between last incoming and last outgoing) to[out=45,in=0] (secondbottom-between incoming 1 and 2);
\draw[
decoration={
markings,
mark=at position .25 with {\arrow{Latex}},
mark=at position .25 with {\node[right] {$$a$$};},
},
postaction={decorate}
]
([out angle=90]secondbottom-outgoing boundary 1.north) .. (secondbottom-incoming boundary 2.north) .. ($(secondtop-between first and last outgoing)!.5!(secondtop-between outgoing 1 and 2)$) .. (secondbottom-incoming boundary 1.north) .. ([in angle=90]secondbottom-outgoing boundary 1.north);

\node at ($(top-outgoing boundary 2.east)!.5!(secondtop-outgoing boundary 1.west)$) {$$\simeq$$};
\end{tikzpicture}
\end{document}