3

I wanted to design a drawing in tikz as follows: (this is my desired output)

enter image description here

Currently I have the following code (which is clearly not effecient...)

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usepackage{graphicx}


\begin{document}
\begin{figure}[h]
\centering
\resizebox{\columnwidth}{!}{
\tikzset{every picture/.style={line width=0.75pt}}
\begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1]
\draw [line width=1.5]    (43,287.33) -- (144.5,287.33) ;
%\draw    (169.5,287.33) -- (231,287.33) ;
%\draw [shift={(233,287.33)}, rotate = 180] [color={rgb, 255:red, 0; green, 0; blue, 0 }  ][line width=0.75]    (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29)   ;
\draw    (115,275.33) .. controls (137.28,157.52) and (283.53,120.08) .. (333.03,118.37) ;
\draw [shift={(334.5,118.33)}, rotate = 538.81] [color={rgb, 255:red, 0; green, 0; blue, 0 }  ][line width=0.75]    (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29)   ;
%\draw  [line width=1.5]  (274,257.33) .. controls (284,252.33) and (373.17,228.33) .. (403.17,247.33) .. controls (433.17,266.33) and (412,321.33) .. (393.17,322.33) .. controls (374.33,323.33) and (340.33,322.33) .. (306.17,322.33) .. controls (272,322.33) and (243.4,304.08) .. (245.17,290.33) .. controls (246.94,276.58) and (250.76,276.46) .. (256.5,270.55) .. controls (262.23,264.65) and (269,259.83) .. (274,257.33) -- cycle ;
%\draw    (285,277.33) .. controls (323.17,264.33) and (315.17,280.33) .. (332.17,274.33) .. controls (349.17,268.33) and (346.17,283.33) .. (372.17,274.33) ;
\draw    (165,288.33) -- (333.03,288.33) ;
\draw [shift={(334.5,288.33)}, rotate = 180] [color={rgb, 255:red, 0; green, 0; blue, 0 }  ][line width=0.75]    (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29)   ;
\draw  [line width=1.5]  (412,254.33) .. controls (421.5,256.2) and (507.5,225.2) .. (537.5,244.2) .. controls (567.5,263.2) and (560.5,317.2) .. (536.17,319.33) .. controls (511.83,321.47) and (483.33,319.33) .. (449.17,319.33) .. controls (415,319.33) and (380.83,323.07) .. (380.5,289.2) .. controls (380.17,255.33) and (386.76,263.11) .. (392.5,257.2) .. controls (398.24,251.29) and (408.5,252.47) .. (417,254.33) -- cycle ;
\draw    (417.5,284.2) .. controls (457.5,254.2) and (486.5,254.2) .. (525,273.2) ;
\draw  [line width=1.5]  (412.5,51.2) .. controls (421,53.07) and (486.5,32.2) .. (562.5,58.2) .. controls (638.5,84.2) and (581.5,145.2) .. (567.5,157.2) .. controls (553.5,169.2) and (433.5,151.2) .. (399.5,161.2) .. controls (365.5,171.2) and (344.33,149.2) .. (344,115.33) .. controls (343.67,81.47) and (346.76,90.11) .. (352.5,84.2) .. controls (358.24,78.29) and (404,49.33) .. (412.5,51.2) -- cycle ;
\draw    (382.5,132.2) .. controls (397.5,112.2) and (418.31,94.7) .. (445.5,93.2) .. controls (472.69,91.7) and (516.25,100.7) .. (535.5,110.2) ;
\draw    (480.5,171.2) -- (480.5,235.33) ;
\draw [shift={(480.5,237.33)}, rotate = 269.57] [color={rgb, 255:red, 0; green, 0; blue, 0 }  ][line width=0.75]    (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29)   ;
% Text Node
\draw (45,290.73) node [anchor=north west][inner sep=0.75pt]    {$0$};
% Text Node
\draw (135.5,290.73) node [anchor=north west][inner sep=0.75pt]    {$1$};
% Text Node
\draw (91,266.73) node [anchor=north west][inner sep=0.75pt]    {$I$};
% Text Node
\draw (250,266.73) node [anchor=north west][inner sep=0.75pt]    {$f$};
% Text Node
\draw (410.17,288.73) node [anchor=north west][inner sep=0.75pt]    {$r$};
% Text Node
\draw (580.17,271.73) node [anchor=north west][inner sep=0.75pt]    {$SO(3)$};
% Text Node
\draw (365.17,130) node [anchor=north west][inner sep=0.75pt]    {$\tilde f(0) = q$};
% Text Node
\draw (500.17,110.73) node [anchor=north west][inner sep=0.75pt]    {$\tilde f(1) = -q$};
% Text Node
\draw (490,192.73) node [anchor=north west][inner sep=0.75pt]    {$p$};
% Text Node
\draw (620,110.73) node [anchor=north west][inner sep=0.75pt]    {$SU(2)$};
% Text Node
\draw (159,141.6) node [anchor=north west][inner sep=0.75pt]    {$\tilde f$};
\end{tikzpicture}}
\end{figure}
\end{document}

This gives me the following output:

enter image description here

But I was looking for more aesthetic: for example, in this answer, the circles and the paths look way "cooler" but I was unable to mimic it to my code. For those who don't want to click the link, the circle I am talking about is:

enter image description here

EDIT

One really cool output I found online (which is more or less what I want - just with some slight differences) is this one:

enter image description here

I have no idea how to create this though.

4
  • I'm a bit confused. What is the problem? The snakey line and that loop inside the ellipses? The ellipses themselves? The arrows f and ~f? Dec 22, 2022 at 19:52
  • @Qrrbrbirlbel Sorry for some confusion my question may cause. My desired output is visible in Thurston answer. I want exactly what he produced in Metapost, but using Tikz. The main reference here is the last picture and my original pen and paper drawing.
    – Rodrigo
    Dec 22, 2022 at 19:53
  • That's certainly doable. Dec 22, 2022 at 20:23
  • @Qrrbrbirlbel I am trying to reproduce it :) I will edit my question with my progress soon.
    – Rodrigo
    Dec 22, 2022 at 20:49

2 Answers 2

2

Libraries

I've chosen a matrix because it automatically gives you a node around some sub-picture. Though, this doesn't guarantee that the ellipses have the same size (which could have been solved, too).

It might be better to just draw that ellipse on the background layer or before the red paths and its labels (though this will need you to figure out the size yourself).
This is also the reason why I have chosen to use \vphantomed labels so that the red line inside the matrix is vertically centered. An alternative solution would be to overlay the labels and use a custom inner ysep padding for the matrix node.

The last edges (the ones labeled with f) use the I node as a reference, a bit cheaty if you ask me but it works.

The superellipse shape is a bit much (it's a curved close plot and its border uses the intersections library which is a bit heavy for TeX), it might be better to use a normal ellipse shape or construct it out of four Bézier curves if really is needed.

The easiest would just be a rectangle with rounded corners.


I've noticed a bug in my superellipse shape which doesn't return the correct border when any transformation has been applied between node creation and reference. It is avoidable here.

Code

\documentclass[tikz,border=2pt,convert]{standalone}
\usepackage{mathtools}
\usetikzlibrary{
  arrows.meta,
  bbox,
  decorations.pathmorphing,
  ext.shapes.superellipse,
  positioning,
  quotes,
}
\tikzset{
  shorten/.style={shorten <={#1},shorten >={#1}},
  math node/.style={execute at begin node=$, execute at end node=$}}
\begin{document}
\begin{tikzpicture}[
  @label/.style n args={4}{"#4{#1}" {#2, inner sep=+.1em},
                           "\vphantom{#1}" {#3, inner sep=+.1em}},
  l/.style={@label={#1}{above}{below}{\mathclap}},
  l'/.style={@label={#1}{below left}{above left}{}},
  >={Triangle[scale=1.33, angle=45:1pt 3]},
  dot/.style={shape=circle, fill=black, draw=none, minimum size=+3pt,
              inner sep=+0pt, outer sep=+0pt, node contents=},
  mat/.style={
    every outer matrix/.append style={shape=superellipse, inner ysep=+0pt},
    draw=black, fill=green!10},
  mat line/.style={draw=red},
  snakes/.style={
    decorate, decoration={snake, segment length=#1, amplitude=+1pt}},
  every label/.append style=math node,every edge quotes/.append style=math node,
  dot line/.style={dash pattern=on \pgflinewidth off 1.5\pgflinewidth},
]
\matrix[mat, "SU(2)" right] (upper set) {
  \node (us-q) at (-5mm,0) [dot, l=q];
  \node (us--q) at (5mm,0) [dot, l=-q];
  \draw[mat line, snakes=3.333mm] (us-q) -- (us--q);
\\};
\matrix[mat, "SO(3)" right, below=1.5cm of upper set] (lower set) {
  \node (ls-R) [dot, l'=R];
  \draw[mat line] (ls-R)
    to[bezier bounding box, out=30, in=-30, min distance=10mm] (ls-R);
\\};

\path[dot line, out=90, in=-90] (ls-R) edge (us-q) edge[out=45] (us--q);
\path[|->, shorten=1mm] (upper set) edge["P" name=P] (lower set);

\path[shift=(P), xshift=-5cm, |-|] (0,0) edge["I"' name=I] ++(right:1.5cm);
\path[->, shorten=1mm] (I)
  edge[out=60, in=185, "\tilde f"] (upper set)
  edge[out=45, in=160, "f"]        (lower set);
\end{tikzpicture}
\end{document}

Output

enter image description here

2
  • Good answer - I have one problem: When I create a TeX file with your code, it works in perfection. Altought, when I insert this code in my current TeX file i get the following error: "Package pgfkeys: I do not know the key '\tikz\"SU(2)" right". Do you have any idea why this might be happening?
    – Rodrigo
    Dec 22, 2022 at 21:06
  • That needs the quotes library. Do you load it? Or you replace them with explicitlabels and nodes on edges. That's all it does. Dec 22, 2022 at 21:07
4

While you are waiting for Tikz-assistance, here is an effort in Metapost.

enter image description here

You can read more about MP if you follow the link above.

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
% define the required paths
path base, se, upper_set, lower_set, f, f', p;
base = (left--right) scaled 40 shifted 160 left;
se = superellipse(40 right, 20 up, 40 left, 20 down, .78);
upper_set = se shifted 60 up;
lower_set = se shifted 60 down;

interim bboxmargin := 10;
f = point 3/4 of base shifted 6 up {dir 45} .. {dir -30} center lower_set cutafter bbox lower_set;
f' = point 5/8 of base shifted 6 up {dir 45} .. {dir 0} center upper_set cutafter bbox upper_set;
p = center upper_set .. center lower_set cutbefore bbox upper_set cutafter bbox lower_set;

% fill and draw the main shapes
fill upper_set withcolor 1/16(15, 16, 13);
fill lower_set withcolor 1/16(15, 16, 13);
draw upper_set;
draw lower_set;
draw base; 
draw (up--down) scaled 4 shifted point 0 of base;
draw (up--down) scaled 4 shifted point 1 of base;
drawarrow f;
drawarrow f';
drawarrow p;  
draw (left--right) scaled 4 shifted point 0 of p;

% now decorate the sets
z1 = center lower_set shifted 10 left;
z2 = center lower_set shifted 24 right;
z3 = center upper_set shifted 24 left;
z4 = center upper_set shifted 24 right;

draw z1 {dir -30} .. z2 .. {dir 210} z1 withcolor 3/4 red;
draw z3 {dir 30} .. 1/3[z3,z4] {dir 30} .. 2/3[z3, z4] {dir 30} .. z4 {dir 30} 
    withcolor 3/4 red;

draw z3 {down} .. {down} z1 dashed withdots scaled 1/4;
draw z4 {down} .. 5/8[z4, z2] - (8,6) .. {down} z1 dashed withdots scaled 1/4;

dotlabel.llft("$R$", z1);
dotlabel.top("$q$", z3); 
dotlabel.top("$-q$", z4);

% finally add the remaining labels
label.ulft("$\tilde{f}$", point 1/2 of f');
label.urt("$f$", point 1/2 of f);
label.bot("$I$", point 1/2 of base);
label.rt ("$P$", point 1/2 of p);
label.rt ("$SU(2)$", point 0 of upper_set);
label.rt ("$SO(3)$", point 0 of lower_set);

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

You need to compile this with the lualatex engine.

1
  • 1
    @Rodrigo I would say it IS perfect ;) Now, if you cannot use LuaLatex or you want to learn something in TikZ is a different matter altogether...
    – Pier Paolo
    Dec 22, 2022 at 22:24

You must log in to answer this question.

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