Improve or simplify this TikZ code for southern hemisphere?
I am not sure if that is a real improvement of Max' great answer, but I took the liberty of changing some things.
- Spherical coordinates may be advantageous here. This makes the placement of the labels is a bit more straightforward.
- Determine the visible vs. invisible parts of the semicircle using intersections rather than manually. This has the advantage that you can adjust the view (within a certain range) and it still works.
- Load the
tikz-3dplot
package. This is by no means better than Max' way of adjusting the view, but better documented. - Remove all the
scale=...
andx=...
statements and just adjust one length: the radius. At the end the picture reports its actual width on the terminal. This may help finding the "optimal" radius. - Use the reverse clip trick to block out parts of the visible arc in the back.
Here is the MWE: EDIT: Dialed the radius such that the pic is 1.6261in wide and 1.03177in tall.
\documentclass[tikz,border=0pt,10pt]{standalone}
\usepackage{tikz-3dplot} % not better than Max' nice code but better documented
\usetikzlibrary{3d,arrows.meta,shadings,calc,intersections,positioning}
\usepackage{pgfplots} % only needed to access different intersection segments
\pgfplotsset{compat=newest}
\usepgfplotslibrary{fillbetween}
\makeatletter %from https://tex.stackexchange.com/a/375604/121799
% spherical coordinates
\define@key{z sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{z sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{z sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{z spherical}{% %%%rotation around x
\setkeys{z sphericalkeys}{#1}%
\pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*sin(\mytheta)*sin(\myphi)}{\myradius*cos(\mytheta)}}
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother
% from https://tex.stackexchange.com/a/12033/121799
\tikzset{reverseclip/.style={insert path={(current page.north east) --
(current page.south east) --
(current page.south west) --
(current page.north west) --
(current page.north east)}
}}
\RequirePackage{bm}
\newcommand{\Stwo}{\ensuremath{\bm{\mathsf{S}}_{2}}}
\newcommand{\StwoMinus}{\Stwo^{-}}
\tikzset{
dot/.style={circle, fill, minimum size=#1, inner sep=0pt, outer sep=0pt},
dot/.default = 4.5pt,
hemispherebehind/.style={ball color=gray!20!white, fill=none, opacity=0.3},
hemispherefront/.style={ball color=gray!65!white, fill=none, opacity=0.3},
circlearc/.style={thick,color=gray!90},
circlearchidden/.style={thick,dashed,color=gray!90},
equator/.style = {thick, black},
diameter/.style = {thick, black},
axis/.style={thick, -stealth,black!60, every node/.style={text=black, at={([turn]1mm,0mm)}},
},
}
\pgfmathsetmacro{\radius}{1.85}
\pgfmathsetmacro\el{10}
\begin{document}
\tdplotsetmaincoords{90+\el}{-105} % - because of difference between active and passive transformations...
\begin{tikzpicture}
\begin{scope}[tdplot_main_coords]
\coordinate (O) at (0,0,0);
\coordinate (xpos) at (z spherical cs:radius=\radius,theta=90,phi=-45);
\coordinate (xneg) at (z spherical cs:radius=\radius,theta=90,phi=135);
\coordinate (nearxpos) at (z spherical cs:radius=0.85*\radius,theta=90,phi=-45);
\coordinate (nearxneg) at (z spherical cs:radius=0.85*\radius,theta=90,phi=135);
% shaded southern hemisphere: (on bottom)
\shade[name path=bottom,
hemispherebehind,
delta angle=180,
x radius=\radius cm
] (\radius cm,0)
\ifnum\el=0
-- ++(-2*\radius,0,0)
\else
arc [y radius={\radius*sin(\el)*1cm},start angle=0]
\fi
arc [y radius=\radius cm,start angle=-180];
% another hemisphere (on top)
\shade[
hemispherefront,
delta angle=180,
x radius=\radius cm,
] (\radius cm,0)
arc [y radius={\radius*sin(\el)*1cm},start angle=0,delta angle=-180]
arc [y radius=\radius cm,start angle=-180];
% equator
\draw[name path=equator,equator, canvas is xy plane at z=.02] (O) circle (\radius);
% maximal visible angle
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(\tdplotmainphi))}
\draw[circlearc, canvas is xz plane at y=0]
(0,0) ++(0:\radius) arc (0:-\MyThetaMax:\radius);
% great semicircle
\path[name path=semicircle, canvas is xz plane at y=0] (0,0) ++(180:\radius)
arc (-180:-\MyThetaMax:\radius);
\draw[circlearchidden,
intersection segments={of=semicircle and equator,sequence={L0}}];
\path[name path=back arc,
intersection segments={of=semicircle and equator,sequence={L2}}];
% Point to diametrically opposite points
\draw[name path=diameter,diameter,Stealth-Stealth] (nearxpos) -- (nearxneg); %
\draw node[dot] at (xpos){} node[anchor=south west] at (xpos){$x$};
\node[dot] at (xneg){} node[anchor=south east] at (xneg){$-x$};
% equator label
\path (z spherical cs:radius=\radius,theta=90,phi=180)
coordinate[label=above right:$E$] (L1)
(z spherical cs:radius=\radius,theta=90,phi=0)
coordinate[label=below left:$\Stwo^{-}$] (L1);
\path[name intersections={of=back arc and diameter,by=aux}];
\begin{scope}
\clip[overlay] (aux) circle (2pt) [reverseclip];
\draw[circlearc,
intersection segments={of=semicircle and equator,sequence={L2}}];
\end{scope}
\path let \p1=($(current bounding box.north east)-
(current bounding box.south west)$) in \pgfextra{
\pgfmathsetmacro{\mywidth}{\x1/1in}
\pgfmathsetmacro{\myheight}{\y1/1in}
\typeout{currently\space the\space picture\space is\space \mywidth in
\space wide\space and\space \myheight in \space tall}};
\end{scope}
\end{tikzpicture}
\end{document}
EDIT: Improved the procedure by computing the visible angle on front analytically, see here for details. Then one only need to compute one intersections, the thing becomes much more stable, and it is easy to create the mandatory animation.
\documentclass[tikz,border=0pt,10pt]{standalone}
\usepackage{tikz-3dplot} % not better than Max' nice code but better documented
\usetikzlibrary{3d,arrows.meta,shadings,calc,intersections,positioning}
\usepackage{pgfplots} % only needed to access different intersection segments
\pgfplotsset{compat=newest}
\usepgfplotslibrary{fillbetween}
\makeatletter %from https://tex.stackexchange.com/a/375604/121799
% spherical coordinates
\define@key{z sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{z sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{z sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{z spherical}{% %%%rotation around x
\setkeys{z sphericalkeys}{#1}%
\pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*sin(\mytheta)*sin(\myphi)}{\myradius*cos(\mytheta)}}
% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane}
\makeatother
\RequirePackage{bm}
\newcommand{\Stwo}{\ensuremath{\bm{\mathsf{S}}_{2}}}
\newcommand{\StwoMinus}{\Stwo^{-}}
\tikzset{
dot/.style={circle, fill, minimum size=#1, inner sep=0pt, outer sep=0pt},
dot/.default = 4.5pt,
hemispherebehind/.style={ball color=gray!20!white, fill=none, opacity=0.3},
hemispherefront/.style={ball color=gray!65!white, fill=none, opacity=0.3},
circlearc/.style={thick,color=gray!90},
circlearchidden/.style={thick,dashed,color=gray!90},
equator/.style = {thick, black},
diameter/.style = {thick, black},
axis/.style={thick, -stealth,black!60, every node/.style={text=black, at={([turn]1mm,0mm)}},
},
}
\pgfmathsetmacro{\radius}{2}
\pgfmathsetmacro\el{10}
\begin{document}
\foreach \X in {0,10,...,350}
{\pgfmathtruncatemacro{\el}{30+20*sin(\X)}
\tdplotsetmaincoords{90+\el}{-105+30*sin(\X)} % - because of difference between active and passive transformations...
\begin{tikzpicture}
\draw (-2.5,-2.5) rectangle (2.5,1.5);
\begin{scope}[tdplot_main_coords]
\coordinate (O) at (0,0,0);
\coordinate (xpos) at (z spherical cs:radius=\radius,theta=90,phi=-45);
\coordinate (xneg) at (z spherical cs:radius=\radius,theta=90,phi=135);
\coordinate (nearxpos) at (z spherical cs:radius=0.85*\radius,theta=90,phi=-45);
\coordinate (nearxneg) at (z spherical cs:radius=0.85*\radius,theta=90,phi=135);
% shaded southern hemisphere: (on bottom)
\shade[name path=bottom,
hemispherebehind,
delta angle=180,
x radius=\radius cm
] (\radius cm,0)
\ifnum\el=0
-- ++(-2*\radius,0,0)
\else
arc [y radius={\radius*sin(\el)*1cm},start angle=0]
\fi
arc [y radius=\radius cm,start angle=-180];
% another hemisphere (on top)
\shade[
hemispherefront,
delta angle=180,
x radius=\radius cm,
] (\radius cm,0)
arc [y radius={\radius*sin(\el)*1cm},start angle=0,delta angle=-180]
arc [y radius=\radius cm,start angle=-180];
% equator
\draw[name path=equator,equator, canvas is xy plane at z=.02] (O) circle (\radius);
% maximal visible angle
\pgfmathsetmacro{\MyThetaMax}{atan(tan(\tdplotmaintheta)*sin(\tdplotmainphi))}
\draw[circlearc, canvas is xz plane at y=0]
(0,0) ++(0:\radius) arc (0:-\MyThetaMax:\radius);
% great semicircle
\path[name path=semicircle, canvas is xz plane at y=0] (0,0) ++(180:\radius)
arc (-180:-\MyThetaMax:\radius);
\draw[circlearchidden,
intersection segments={of=semicircle and equator,sequence={L0}}];
\draw[circlearc,
intersection segments={of=semicircle and equator,sequence={L2}}];
% Point to diametrically opposite points
\draw[diameter,Stealth-Stealth] (nearxpos) -- (nearxneg); %
\draw node[dot] at (xpos){} node[anchor=south west] at (xpos){$x$};
\node[dot] at (xneg){} node[anchor=south east] at (xneg){$-x$};
% equator label
\path (z spherical cs:radius=\radius,theta=90,phi=180)
coordinate[label=below left:$E$] (L1)
(z spherical cs:radius=\radius,theta=90,phi=0)
coordinate[label=below right:$\Stwo^{-}$] (L1);
\path let \p1=($(current bounding box.north east)-
(current bounding box.south west)$) in \pgfextra{
\pgfmathsetmacro{\mywidth}{\x1/1in}
\pgfmathsetmacro{\myheight}{\y1/1in}
\typeout{currently\space the\space picture\space is\space \mywidth in
\space wide\space and\space \myheight in \space tall}};
\end{scope}
\end{tikzpicture}}
\end{document}
A simpler but maybe also less sophisticated approach:
\documentclass[margin=10pt]{standalone}
\usepackage{tikz,bm,pgfplots}
\pgfplotsset{compat=1.14}
\usetikzlibrary{fillbetween}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{80}{140}
\begin{tikzpicture}[scale=2,tdplot_main_coords]
\tikzset{
dot/.style={circle, fill, minimum size=#1, inner sep=0pt, outer sep=0pt},
dot/.default=4.5pt,
hemispherebehind/.style={ball color=gray!20!white, fill=none, opacity=0.3},
hemispherefront/.style={ball color=gray!65!white, fill=none, opacity=0.3},
circlearc/.style={thick,color=gray!90},
circlearchidden/.style={thick,dashed,color=gray!90},
equator/.style={thick, black},
diameter/.style={thick, black, stealth-stealth, shorten <=5pt, shorten >=5pt}
}
\newcommand{\hemispherefront}{(1cm,0) arc (0:-180:1cm and 1.8mm) arc (180:0:1cm and -1cm)}
\newcommand{\hemispherebehind}{(1cm,0) arc (0:-180:1cm and -1.8mm) arc (-180:0:1cm and 1cm)}
\newcommand{\equator}{(-1,0,0) arc (0:360:-1)}
\tdplotsetthetaplanecoords{35}
\path[tdplot_rotated_coords,name path=semicircle] (0,-1,0) arc (90:-90:-1);
\path[name path=equator] \equator;
\shade[hemispherebehind,text opacity=1] \hemispherebehind;
\shade[hemispherefront,name path=hemisphere] \hemispherefront;
\draw[circlearc,intersection segments={of=semicircle and equator,sequence={L2}}];
\draw[circlearchidden,intersection segments={of=semicircle and hemisphere,sequence={L2}}];
\draw[circlearc,intersection segments={of=semicircle and hemisphere,sequence={L3}}];
\draw[equator] \equator node[pos=1,label={90:$E$}]{};
\draw[diameter] (0,-1,0) node[dot,label={120:$-x$}]{} -- (0,1,0) node[dot,label={30:$x$}]{};
\node at (.75,0,-.5) {$\bm{\mathsf{S}}_2^-$};
\end{tikzpicture}
\end{document}
Edit: Improved thanks to marmot’s good idea to use intersections.