This is an interesting stereographic projection that you get when you rotate 90-degree Steiner circles about their axis of symmetry.
Animated GIF; you may need to click on it for running:
This is an example LaTeX file for a particular value of \animationparameter, that you can run yourself here in the browser:
\documentclass[
tikz
,border = 3.14mm
]{standalone}
\usepackage{tikz-3dplot}
\pgfmathdeclarefunction{sphereX}{2}{%
% #1 - longitude
% #2 - latitude
\pgfmathparse{cos(#2)*cos(#1)}%
}
\pgfmathdeclarefunction{sphereY}{2}{%
\pgfmathparse{cos(#2)*sin(#1)}%
}
\pgfmathdeclarefunction{sphereZ}{2}{%
\pgfmathparse{sin(#2)}%
}
\pgfmathdeclarefunction{toruscenter}{1}{%
% #1 - \animationparameter
\pgfmathparse{1/cos(#1)}%
}
\pgfmathdeclarefunction{torusradius}{1}{%
% #1 - \animationparameter
\pgfmathparse{-sin(#1)/cos(#1)}%
}
\pgfmathdeclarefunction{projectionx}{3}{%
% #1 - \animationparameter
% #2 - \longitude
% #2 - \latitude
\pgfmathparse{
torusradius(#1) *
sphereX(#2,#3) +
toruscenter(#1) *
cos(#2)
}%
}
\pgfmathdeclarefunction{projectiony}{3}{%
% #1 - \animationparameter
% #2 - \longitude
% #2 - \latitude
\pgfmathparse{
torusradius(#1) *
sphereY(#2,#3) +
toruscenter(#1) *
sin(#2)
}%
}
\pgfmathdeclarefunction{projectionz}{3}{%
% #1 - \animationparameter
% #2 - \longitude
% #2 - \latitude
\pgfmathparse{
torusradius(#1) *
sphereZ(#2,#3)
}%
}
\pgfmathsetmacro{\animationparameter}{60}
\begin{document}
\tdplotsetmaincoords{60}{120}
\begin{tikzpicture}[tdplot_main_coords]
% This clips and adds struts to a rectangle
% which mimicks the size of a Beamer frame.
\path[tdplot_screen_coords]
(-12.8/2,-9.6/2)
rectangle
(12.8/2,9.6/2);
\clip[tdplot_screen_coords]
(-12.8/2,-9.6/2)
rectangle
(12.8/2,9.6/2);
\pgfmathsetmacro{\startlatitude}{0}
\pgfmathsetmacro{\endlatitude}{360}
\pgfmathsetmacro{\sampleslatitude}{20}
\pgfmathsetmacro{\steplatitude}{
(\endlatitude - \startlatitude) /
\sampleslatitude
}
\foreach
\latitude[
parse = true
,count = \count
]
in {%
\startlatitude%
,\startlatitude+\steplatitude%
,...%
,\endlatitude%
} {
\pgfmathparse{\count != \sampleslatitude + 1}
\ifnum\pgfmathresult=1
\pgfmathsetmacro{\startlongitude}{0}
\pgfmathsetmacro{\endlongitude}{360}
\pgfmathsetmacro{\sampleslongitude}{20}
\draw[
smooth
,domain = \startlongitude:\endlongitude
,samples = \sampleslongitude
,variable = \longitude
] plot (
{
projectionx(
\animationparameter
,\longitude
,\latitude
)
}
,{
projectiony(
\animationparameter
,\longitude
,\latitude
)
}
,{
projectionz(
\animationparameter
,\longitude
,\latitude
)
}
) plot (
{
toruscenter(\animationparameter) *
sphereX(\longitude,\latitude)
}
,{
toruscenter(\animationparameter) *
sphereY(\longitude,\latitude)
}
,{
toruscenter(\animationparameter) *
sphereZ(\longitude,\latitude) +
torusradius(\animationparameter)
}
);
\fi
}
\pgfmathsetmacro{\startlongitude}{0}
\pgfmathsetmacro{\endlongitude}{360}
\pgfmathsetmacro{\sampleslongitude}{20}
\pgfmathsetmacro{\steplongitude}{
(\endlongitude - \startlongitude) /
\sampleslongitude
}
\foreach
\longitude[
parse = true
,count = \count
]
in {%
\startlongitude%
,\startlongitude+\steplongitude%
,...%
,\endlongitude%
} {
\pgfmathparse{\count != \sampleslongitude + 1}
\ifnum\pgfmathresult=1
\pgfmathsetmacro{\startlatitude}{0}
\pgfmathsetmacro{\endlatitude}{360}
\pgfmathsetmacro{\sampleslatitude}{20}
\draw[
smooth
,domain = \startlatitude:\endlatitude
,samples = \sampleslatitude
,variable = \latitude
] plot (
{
projectionx(
\animationparameter
,\longitude
,\latitude
)
}
,{
projectiony(
\animationparameter
,\longitude
,\latitude
)
}
,{
projectionz(
\animationparameter
,\longitude
,\latitude
)
}
) plot (
{
toruscenter(\animationparameter) *
sphereX(\longitude,\latitude)
}
,{
toruscenter(\animationparameter) *
sphereY(\longitude,\latitude)
}
,{
toruscenter(\animationparameter) *
sphereZ(\longitude,\latitude) +
torusradius(\animationparameter)
}
);
\fi
}
\end{tikzpicture}
\end{document}

