# How to draw on a curved 3D surface?

I'm trying to reproduce in LaTeX this image, hand-drawn with Mathcha.

The thing is, I can't find anything online about how to draw on curved (smooth) 3d surfaces like this sphere.

Technically, the image is only two dimensional, hence it should be possible to do the drawing in 2d coordinates, however, it is difficult for me to know how to deform the sine-like curve without at least some trial and error (and in general it wouldn't be a method applicable to other scenarios).

Anything using tikz is very appreciated since I'm already familiar with it, but I will make do with any other package as well.

Thank you for your time and effort, it is very appreciated.

Edit:

I thank @Roland for his answer, however, what I was looking for is a method to wrap a drawing around a 3d surface, or otherwise a spherical coordinate system that would allow -- with a bit of math -- to draw at least some three-dimensional curved surfaces easily.

• "however, it is difficult for me to know how to deform the sine function without at least some trial and error" Of course you have to do some math to compute the coordinate (TikZ is especially bad at computation), or just approximate it by drawing on a wrapping cylinder or just approximate it with a 2D spline. Maybe external tools (Asymptote? gnuplot? Sympy? Mathematica?) would be useful. Jan 7, 2022 at 0:14
• Can you describe the curve? It is not the usual sine curve. Jan 7, 2022 at 17:03
• @BlackMild it's not really important the exact curve, anything similar will do. However, it should be the sine curve wrapped around the surface of the sphere. Jan 7, 2022 at 18:41

Another attempt, looking for a function as simple as possible that fits with the original drawing.

For example:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{3d,perspective}

\begin{document}
\begin{tikzpicture}[isometric view,blue]
\foreach\i in {-0.5,0.5}
\draw[canvas is xy plane at z=\i] (0,0) circle ({sqrt(4-\i*\i)});
\draw[red] plot[domain=135:315,samples=181]
({2*cos(\x)*sqrt(1-0.0625*sin(8*\x)*sin(8*\x))},
{2*sin(\x)*sqrt(1-0.0625*sin(8*\x)*sin(8*\x))},
{0.5*sin(8*\x)});
\draw[red] plot[domain=-45:135,samples=181]
({2*cos(\x)*sqrt(1-0.0625*sin(8*\x)*sin(8*\x))},
{2*sin(\x)*sqrt(1-0.0625*sin(8*\x)*sin(8*\x))},
{0.5*sin(8*\x)});
\def\h{0.7}                       % arrows height
\foreach\i in {10,55,100} \foreach\j in {-\h,\h}
\draw[-latex,canvas is xy plane at z=\j] (\i-10:\r) arc (\i-10:\i+10:\r);
\end{tikzpicture}
\end{document}


Edit 1: If you can't use the perspective library you can create your own isometric view adding this code to the preamble:

\pgfmathsetmacro\xx{1/sqrt(2)}
\pgfmathsetmacro\xy{1/sqrt(6)}
\pgfmathsetmacro\zz{sqrt(2/3)}
\tikzset{isometric view/.style={x={(-\xx cm,-\xy cm)},y={(\xx cm,-\xy cm)},z={(0cm,\zz cm)}}}


With this you can remove the rotate around z=180 option (these axes are defined with the rotation made).

Edit 2: There was an error in the sinusoidal function in the original post, now corrected.

This is a more customizable version. It has two parameters: the height of the circles and the sinusoidal function \h, and the number of periods \n (it must be a multiple of 4). The radius if always 1cm, but if you change the scale you can have any radius needed. This version improves the visibility too. It's not perfect yet, but it's a little bit better.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{3d,perspective}

\begin{document}
\begin{tikzpicture}[isometric view,rotate around z=180,scale=2] % <-- radius =2
\def\h{0.1}                      % height
\def\n{20}                       % numer of sines (must be a multiple of 4)
\pgfmathsetmacro\c{sqrt(1.5)*\h} % clip height
\pgfmathsetmacro\s{\n*20+1}      % samples
% circles, background
\foreach\i in {-1,1}
{
\begin{scope}
\clip (-1cm,\i*\c cm) rectangle (1cm,1cm);
\draw[blue,densely dashed,canvas is xy plane at z=\i*\h] (0,0) circle ({sqrt(1-\h*\h)});
\end{scope}
}
% function, background
\draw[red,densely dashed] plot[domain=135:315,samples=\s]
({cos(\x)*sqrt(1-\h*\h*sin(\n*\x)*sin(\n*\x))},
{sin(\x)*sqrt(1-\h*\h*sin(\n*\x)*sin(\n*\x))},
{\h*sin(\n*\x)});
% sphere
\draw[green,shading=ball,ball color=green,fill opacity=0.5] (0,0,0) circle (1cm);
% circles, foreground
\foreach\i in {-1,1}
{
\begin{scope}
\clip (-1cm,-1cm) rectangle (1cm,\i*\c cm);
\draw[blue,canvas is xy plane at z=\i*\h] (0,0) circle ({sqrt(1-\h*\h)});
\end{scope}
}
% function, foreground
\draw[red] plot[domain=-45:135,samples=\s]
({cos(\x)*sqrt(1-\h*\h*sin(\n*\x)*sin(\n*\x))},
{sin(\x)*sqrt(1-\h*\h*sin(\n*\x)*sin(\n*\x))},
{\h*sin(\n*\x)});
\end{tikzpicture}
\end{document}


• Thank you very much! Apparently, Overleaf does not have support for the perspective library, but I've tried it in MiKTeX and it works beautifully. Jan 7, 2022 at 20:00
• @EdoardoSerra, it's easy to define the isometric view without the perspective library. See my edit. Jan 7, 2022 at 20:49
• Hi, I'm sorry for bothering you again. Is there a way to generalize it to any radius of the ball and vertical separation between the two blue circles? I can't really wrap my head around the geometry here, and what I've tried hasn't worked so far. Thank you in advance! Jan 9, 2022 at 12:02
• @EdoardoSerra. See my new edit, now the code is more customizable and improved a bit. Jan 9, 2022 at 16:00

A tikz only suggestion by simply drawing it:

\documentclass[border=0.5cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\draw (3,0) circle (2cm);
\draw (1.21,0.91) .. controls (2,0.33) and (4,0.30) .. (4.84,0.80);
\draw (1,0.07) .. controls (2,-0.5) and (4,-0.5) .. (5,-0.08);
\draw[decorate, decoration={snake, segment length=7.04mm, amplitude=4mm}] (1.07,0.5) .. controls (2,0) and (4,0) .. (4.94,0.5);

\node[right] at (4.84,0.80) {$\theta_{1}$};
\node[right] at (5,-0.08) {$\theta_{2}$};

% arrows
\draw[-stealth] (1.5,1) -- (2.2,0.91);
\draw[-stealth] (2.5,0.88) -- (3.2,0.8);
\draw[-stealth] (3.5,0.91) -- (4.2,1);

\draw[-stealth] (1.5,-0.4) -- (2.2,-0.5);
\draw[-stealth] (2.5,-0.55) -- (3.2,-0.6);
\draw[-stealth] (3.5,-0.58) -- (4.2,-0.5);
\end{tikzpicture}
\end{document}


• There's a bump in the right part however Jan 7, 2022 at 9:42