Draw lower (southern) hemisphere and great semicircle with “mathematician's” axes orientation

With tikz and tikz-3dplot I want to draw:

• the unit lower (i.e., southern) hemisphere; and on that
• two great semicircles through the south pole, i.e., point $(x, y, z) = (0, 0, -1)$, the first joining the points $(\sqrt{2}, \sqrt{2}, 0)$ and $(\sqrt{2}, \sqrt{2}, 0)$ and the second joining the points $(-\sqrt{2}, \sqrt{2}, 0)$ and $(\sqrt{2}, -\sqrt{2}, 0)$; and
• points at the ends of each of those great semicircles (in my code, shown below, I could use dot, perhaps?)

[Meta question: how does one enter LaTeX code here??]

Moreover, I want the drawing to show the x-, y-, z-axes with the orientation and position that mathematicians so often use for sketches on paper or on a blackboard, namely: z-axis pointing straight up; y-axis pointing directly to the right, that is on the 2D paper, towards due east); and x-axis "outward" but, as drawn on paper, pointing to the southwest — as shown in this image from https://en.wikipedia.org/wiki/Three-dimensional_space:

In particular, I do not want the southest-pointing" x-axis to be unduly foreshortened.

Edit: rough version of what I want

The following was drawn with Mathematica, but for consistency with my LaTeX document and other graphics there, I need a version done in TikZ.

The positive z-axis in this version exends much further north than I actually want!

Here's my incomplete start:

\documentclass[tikz,border=0pt]{standalone}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{calc}

\begin{document}

\tdplotsetmaincoords{60}{110} % theta, phi

\begin{tikzpicture}[scale=5,tdplot_main_coords,
dot/.style = {circle, fill, minimum size=#1, inner sep=0pt, outer sep=0pt},
dot/.default = 4pt,  % size of the circle diameter
]

\coordinate (O) at (0,0,0);
\draw[thick,->] (0,0,0) -- (1.25*\radius,0,0) node[anchor=north east]{$X$};
\draw[thick,->] (0,0,0) -- (0,1.25*\radius,0) node[anchor=north west]{$Y$};
\draw[thick,->] (0,0,0) -- (0,0,1.25*\radius) node[anchor=south]{$Z$};

\shade[ball color=gray!20!white,opacity=0.3] (1cm,0) arc (0:180:1cm and 5mm) arc (-180:0:1cm and 1cm);

\tdplotsetrotatedcoords{0}{270}{90}; % semicircle for lower hemishphere
\end{tikzpicture}

\end{document}


Question: How accomplish this?

Evidently it would suffice if I could find out how to draw one of those great semicircles and the points on the equator at its ends.

My difficulty is in 3d visualization, i.e., "seeing" how to rotate everything, first to get the axes orientation right, second to move things into position to draw each great semicircle.

• To your "meta question": MathJax is (intentionally) disabled on this site. – TeXnician Aug 23 '18 at 19:51
• @TeXnician: drat! – murray Aug 23 '18 at 19:55

Like this? Obviously not! See below for a newer version!

The Tikz library 3d is very helpful here. You can use styles as canvas is xy plane at z=0 to start drawing on a certain plane, and rotate around z=45 to rotate the entire coordinate system about z (or any other axis). See also this answer for the available options.

\documentclass[tikz,border=0pt]{standalone}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
%\usepackage{calc}

\usetikzlibrary{3d}

% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\makeatletter
\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

\begin{document}

\tdplotsetmaincoords{60}{110} % theta, phi

\begin{tikzpicture}[scale=5,tdplot_main_coords,
dot/.style = {circle, fill, minimum size=#1, inner sep=0pt, outer sep=0pt},
dot/.default = 4pt,  % size of the circle diameter
]

\coordinate (O) at (0,0,0);

% equator
\draw[canvas is xy plane at z=0,thick,gray!90] (0,0) circle (\radius);

\shade[ball color=gray!20!white,opacity=0.3] (1cm,0) arc (0:180:1cm and 5mm) arc (-180:0:1cm and 1cm);

% two semicircles
\foreach \ang in {-45,45}{
\draw[rotate around z=\ang,canvas is xz plane at y=0,thick,color=gray!90] (0,0) ++(0:\radius) arc (0:-180:\radius);
\path[rotate around z=\ang] (1,0,0) node[dot]{} (-1,0,0) node[dot]{};
}

% axes
\draw[thick,->] (0,0,0) -- (1.25*\radius,0,0) node[anchor=north east]{$X$};
\draw[thick,->] (0,0,0) -- (0,1.25*\radius,0) node[anchor=north west]{$Y$};
\draw[thick,->] (0,0,0) -- (0,0,1.25*\radius) node[anchor=south]{$Z$};
\end{tikzpicture}

\end{document}


Edit You will have to scroll further down for another edit.
It's still a bit unclear for me what your asking, but that is probably due to me not understanding properly, and not due to you not explaining properly :) I made a version that is a bit more like the Mathematica example you provided.

To achieve it I adjusted the shading to make the y radius dependent of the current elevation angle \el. I also added another shading area that strengthens the '3D feel' of the hemisphere by overlaying part of the former shading (see the image, I can't explain this very well).

I added a view={<azimuth>}{<elevation>} key that sets the view angle. The <azimuth> angle is measured w.r.t. the negative y axis in the xy plane, and the <elevation> angle is measured w.r.t. the horizontal xy plane, so if both angles are zero, z points up and x points right. I don't know how Mathematica sets its 3D viewing point, but the Matlab view command works as above. The following animation shows in what order the rotations are executed (I changed the shading to a fill for this animation due to the upload limit on image size):

MWE:

\documentclass[tikz,border=0pt]{standalone}

\usetikzlibrary{3d}

% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\makeatletter
\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}

% view={<azimuth>,<elevation>} key
\tikzset{
view/.code args={#1,#2}{%
% Set elevation and azimuth angles
\pgfmathsetmacro\view@az{#1}
\pgfmathsetmacro\view@el{#2}
% Calculate projections of rotation matrix
\pgfmathsetmacro\xvec@x{cos(\view@az)}
\pgfmathsetmacro\xvec@y{-sin(\view@az)*sin(\view@el)}
\pgfmathsetmacro\yvec@x{sin(\view@az)}
\pgfmathsetmacro\yvec@y{cos(\view@az)*sin(\view@el)}
\pgfmathsetmacro\zvec@x{0}
\pgfmathsetmacro\zvec@y{cos(\view@el)}
% Set base vectors
\pgfsetxvec{\pgfpoint{\xvec@x cm}{\xvec@y cm}}
\pgfsetyvec{\pgfpoint{\yvec@x cm}{\yvec@y cm}}
\pgfsetzvec{\pgfpoint{\zvec@x cm}{\zvec@y cm}}
},
}
\makeatother

\tikzset{
dot/.style={
circle,
fill,
minimum size=#1,
inner sep=0pt,
outer sep=0pt
},
dot/.default = 4pt,
hemisphere/.style={
ball color=gray!20!white,
fill=none,
opacity=0.3,
},
equator/.style={
thick,
gray!90,
},
axis/.style={
thick,
-stealth,
black!60,
every node/.style={
text=black,
at={([turn]1mm,0mm)}
},
},
}

\pgfmathsetmacro\el{10}

\begin{document}
\begin{tikzpicture}[
view={105,\el}, % {<azimuth>}{<elevation>}
]
\coordinate (O) at (0,0,0);

% shaded southern hemisphere: (on bottom)
\fill[
hemisphere,
delta angle=180,
\ifnum\el=0
\else
\fi

% another hemisphere (on top)
\fill[
hemisphere,
delta angle=180,

% equator
\draw[equator,canvas is xy plane at z=0] (O) circle (\radius);

% two semicircles
\foreach \ang in {-45,45}{
\begin{scope}[rotate around z=\ang]
\end{scope}
}

% axes
\draw[axis] (-1, 0, 0) -- (1,0,0  ) node {$X$};
\draw[axis] ( 0,-1, 0) -- (0,1,0  ) node {$Y$};
\draw[axis] ( 0, 0,-1) -- (0,0,0.5) node {$Z$};
\end{scope}

\end{tikzpicture}
\end{document}


MWE Animation:

\documentclass[tikz,border=0pt]{standalone}

\usetikzlibrary{3d}

% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\makeatletter
\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}

% view={<azimuth>,<elevation>} key
\tikzset{
view/.code args={#1,#2}{%
% Set elevation and azimuth angles
\pgfmathsetmacro\view@az{#1}
\pgfmathsetmacro\view@el{#2}
% Calculate projections of rotation matrix
\pgfmathsetmacro\xvec@x{cos(\view@az)}
\pgfmathsetmacro\xvec@y{-sin(\view@az)*sin(\view@el)}
\pgfmathsetmacro\yvec@x{sin(\view@az)}
\pgfmathsetmacro\yvec@y{cos(\view@az)*sin(\view@el)}
\pgfmathsetmacro\zvec@x{0}
\pgfmathsetmacro\zvec@y{cos(\view@el)}
% Set base vectors
\pgfsetxvec{\pgfpoint{\xvec@x cm}{\xvec@y cm}}
\pgfsetyvec{\pgfpoint{\yvec@x cm}{\yvec@y cm}}
\pgfsetzvec{\pgfpoint{\zvec@x cm}{\zvec@y cm}}
},
}
\makeatother

\tikzset{
dot/.style={
circle,
fill,
minimum size=#1,
inner sep=0pt,
outer sep=0pt
},
dot/.default = 4pt,
hemisphere/.style={
gray,
fill opacity=0.3,
},
equator/.style={
thick,
gray!90,
},
axis/.style={
thick,
-stealth,
black!60,
every node/.style={
text=black,
at={([turn]1mm,0mm)}
},
},
}

\newcommand{\drawSouthernHemisphere}{
\coordinate (O) at (0,0,0);

\path (5cm,4cm) node[align=left,left] {azimuth: \\ elevation:} node[align=right,right,text width=1cm] {\az$^\circ$\\ \el$^\circ$};
% shaded southern hemisphere: (on bottom)
\fill[
hemisphere,
delta angle=180,
\ifnum\el=0
\else
\fi
% another hemisphere (on top)
\fill[
hemisphere,
delta angle=180,
\ifnum\el=0
\else
\fi
% equator
\ifnum\el=0
\else
\draw[equator,canvas is xy plane at z=0] (O) circle (\radius);
\fi
% two semicircles
\foreach \ang in {-45,45}{
\begin{scope}[rotate around z=\ang]
\end{scope}
}
% axes
\draw[axis] (-1, 0, 0) -- (1,0,0  ) node {$X$};
\draw[axis] ( 0,-1, 0) -- (0,1,0  ) node {$Y$};
\draw[axis] ( 0, 0,-1) -- (0,0,0.5) node {$Z$};
\end{scope}
}

\begin{document}
\foreach \az in {0,5,...,100}{
\pgfmathsetmacro\el{0}
\begin{tikzpicture}[view={\az,\el}]% {<azimuth>}{<elevation>}
\drawSouthernHemisphere
\end{tikzpicture}
}
\foreach \el in {0,2,...,10,10,10,8,...,2}{
\pgfmathsetmacro\az{105}
\begin{tikzpicture}[view={\az,\el}]% {<azimuth>}{<elevation>}
\drawSouthernHemisphere
\end{tikzpicture}
}
\foreach \az in {105,100,...,0,0,0}{
\pgfmathsetmacro\el{0}
\begin{tikzpicture}[view={\az,\el}]% {<azimuth>}{<elevation>}
\drawSouthernHemisphere
\end{tikzpicture}
}
\end{document}


Edit 2
I think what you want is a cabinet projection (which I believe is not really an orthographic projection, but an oblique projection, but I also found some writings stating that oblique is a subset of orthographic). The solution presented above is also orthographic, and definitely not perspective (see my answer here for a perspective view).

3D projections can be set with Tikz fairly easy, by setting the base vectors of the coordinate system as projected on the paper. For example, for a view from the positive y axis, those base vectors are x=[-1;0], y=[0 0], and z=[0;1]. The view key mentioned above sets the base vectors according to its input angles. For the cabinet projection, we would want the following base vectors:

• z=[0;1] To point the z vector straight up on the paper;
• y=[1;0] To point the y vector to the right on the paper;
• x=[-0.3536;-0.3536] To point to the below-left on the paper. These values are 1/2*cos(225) and 1/2*sin(225) which happen to be the same for 225 degrees (big surprise :) ).

The problem with these base vectors for a cabinet projection are that the projection of a perfect sphere on the paper, which is expected to be a perfect circle from any view, now becomes an ellipse. To demonstrate this I drew a number of circles which represent a sphere (this way I can let Tikz do the mapping in the coordinate system).

The left image is with the orthographic coordinate system, set with view={105,25}, the middle is set with the key cabinet projection which sets the base vectors as listed above, and the right one is drawn in a cavalier projection (set with cavalier projection key), which is similar to the cabinet projection, only with a longer x base vector, so the sphere is even more ellipsoid. See also the house shapes in the same projections.

I actually also tried to come up with a poor man solution to the above, namely drawing the half-sphere in orthographic projection with a slight additional rotation about z, with the axes drawn in the cabinet projection. This comes out as:

For completeness I also added the 'real' projection axes in red, to highlight the difference:

The above images were drawn with the following code. I made a \drawSphereWithAxes and a \drawHouseWithAxes command just for repeating these easily, but they are obviously not needed for your solution so you can simply throw them out.

\documentclass[tikz,border=2mm]{standalone}

\usetikzlibrary{3d}

% small fix for canvas is xy plane at z % https://tex.stackexchange.com/a/48776/121799
\makeatletter
\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}

% view={<azimuth>,<elevation>} key
\tikzset{
view/.code args={#1,#2}{%
% Set elevation and azimuth angles
\pgfmathsetmacro\view@az{#1}
\pgfmathsetmacro\view@el{#2}
% Calculate projections of rotation matrix
\pgfmathsetmacro\xvec@x{cos(\view@az)}
\pgfmathsetmacro\xvec@y{-sin(\view@az)*sin(\view@el)}
\pgfmathsetmacro\yvec@x{sin(\view@az)}
\pgfmathsetmacro\yvec@y{cos(\view@az)*sin(\view@el)}
\pgfmathsetmacro\zvec@x{0}
\pgfmathsetmacro\zvec@y{cos(\view@el)}
% Set base vectors
\pgfsetxvec{\pgfpoint{\xvec@x cm}{\xvec@y cm}}
\pgfsetyvec{\pgfpoint{\yvec@x cm}{\yvec@y cm}}
\pgfsetzvec{\pgfpoint{\zvec@x cm}{\zvec@y cm}}
},
}
\makeatother

\tikzset{
dot/.style={
circle,
fill,
minimum size=#1,
inner sep=0pt,
outer sep=0pt
},
dot/.default = 4pt,
hemisphere/.style={
ball color=gray!20!white,
fill=none,
opacity=0.3,
},
equator/.style={
thick,
gray!90,
},
axis/.style={
thick,
-stealth,
black!60,
every node/.style={
text=black,
at={([turn]1mm,0mm)}
},
},
cabinet projection/.style={
x={({0.5*cos(225)*10mm},{0.5*sin(225)*10mm})},
y={(10mm,0mm)},
z={(0mm,10mm)},
},
cavalier projection/.style={
x={({cos(225)*10mm},{sin(225)*10mm})},
y={(10mm,0mm)},
z={(0mm,10mm)},
},
}

\newcommand\drawSphereWithAxes{
\foreach \ang [evaluate=\ang as \height using {\radius*cos(\ang)}] in {0,5,...,179}{
\begin{scope}[rotate around z=\ang]
\draw[canvas is yz plane at x=0,opacity=0.1] (0,0) circle (\radius);
\end{scope}
\begin{scope}[canvas is xy plane at z=\height]
\end{scope}
}
\begin{scope}[scale=1.3]
\draw[axis] (-1, 0, 0) -- (1,0,0) node {$X$};
\draw[axis] ( 0,-1, 0) -- (0,1,0) node {$Y$};
\draw[axis] ( 0, 0,-1) -- (0,0,1) node {$Z$};
\end{scope}
\path foreach \crossing in {{(-1,0,0)},{(1,0,0)},{(0,-1,0)},{(0,1,0)},{(0,0,-1)},{(0,0,1)}}{ \crossing node[dot]{}};
\end{scope}
}
\newcommand\drawHouseWithAxes{
\begin{scope}[scale=2]
\draw[axis] (-1, 0, 0  ) -- (1,0,0  ) node {$X$};
\draw[axis] ( 0,-1, 0  ) -- (0,1,0  ) node {$Y$};
\draw[axis] ( 0, 0,-0.5) -- (0,0,1.5) node {$Z$};
\end{scope}
\begin{scope}[fill opacity=0.1,line join=round,shift={(-1,-1,0)}]
\filldraw (0,0,0) -- (0,2,0) -- (2,2,0) -- (2,0,0) -- cycle;
\filldraw (0,2,0) -- (0,2,1) -- (0,1,2) -- (0,0,1) -- (0,0,0) -- cycle;
\filldraw (0,2,1) -- (0,1,2) -- (2,1,2) -- (2,2,1) -- cycle;
\filldraw (0,0,1) -- (0,1,2) -- (2,1,2) -- (2,0,1) -- cycle;
\filldraw (0,0,0) -- (0,0,1) -- (2,0,1) -- (2,0,0) -- cycle;
\filldraw (0,2,0) -- (0,2,1) -- (2,2,1) -- (2,2,0) -- cycle;
\filldraw (2,2,0) -- (2,2,1) -- (2,1,2) -- (2,0,1) -- (2,0,0) -- cycle;
\end{scope}
}

\pgfmathsetmacro\el{10}

\begin{document}
\begin{tikzpicture}[cabinet projection]

\coordinate (O) at (0,0,0);

\begin{scope}[view={90,\el},rotate around z=-10]

% shaded southern hemisphere: (on bottom)
\fill[
hemisphere,
delta angle=180,

% another hemisphere (on top)
\fill[
hemisphere,
delta angle=180,

% equator
\draw[equator,canvas is xy plane at z=0] (O) circle (\radius);

% two semicircles
\foreach \ang in {-45,45}{
\begin{scope}[rotate around z=\ang]
\end{scope}
}

% Real sphere projection axes
\draw[axis,red,very thick] (-1, 0, 0) -- (1,0,0  ) node {$X'$};
\draw[axis,red,very thick] ( 0,-1, 0) -- (0,1,0  ) node {$Y'$};
\draw[axis,red,very thick] ( 0, 0,-1) -- (0,0,0.5) node {$Z'$};
\end{scope}
\end{scope}

% axes
\draw[axis] (-1, 0, 0) -- (1,0,0  ) node {$X$};
\draw[axis] ( 0,-1, 0) -- (0,1,0  ) node {$Y$};
\draw[axis] ( 0, 0,-1) -- (0,0,0.5) node {$Z$};
\end{scope}

\end{tikzpicture}

\begin{tikzpicture}

\begin{scope}[view={105,25}]
\node at (0cm,4cm) {\huge Orthographic};
\drawSphereWithAxes
\begin{scope}[shift={(0,-6cm)}]
\drawHouseWithAxes
\end{scope}
\end{scope}

\begin{scope}[cabinet projection,shift={(7cm,0cm)}]
\node at (0cm,4cm) {\huge Cabinet};
\drawSphereWithAxes
\begin{scope}[shift={(0,-6cm)}]
\drawHouseWithAxes
\end{scope}
\end{scope}

\begin{scope}[cavalier projection,shift={(14cm,0cm)}]
\node at (0cm,4cm) {\huge Cavalier};
\drawSphereWithAxes
\begin{scope}[shift={(0,-6cm)}]
\drawHouseWithAxes
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}

• Very nice! +1 . In case the OP does not like the 3d library, you could just do \draw plot[variable=\x,domain=0:180,smooth,samples=60] ({cos(45)*cos(\x)},{sin(45)*cos(\x)}{-sin(\x)}); and the same with -45 instead of 45. If you do that in rotated coordinates, you can rotate the hemisphere, of course. – user121799 Aug 23 '18 at 22:51
• I dunno, according to his profile he is a mathematician, and I can not see any reason why he has not accepted your nice answer so I am speculating why. ;-) The only other reason may be that he is waiting for the dots at the end. – user121799 Aug 23 '18 at 23:06
• @Max: which command(s) draw the dots? – murray Aug 24 '18 at 0:50
• @murray Inside the \foreach the line \path[rotate around z=\ang] (1,0,0) node[dot]{} (-1,0,0) node[dot]{}; draws a dot on x=1 and x=-1 but these coordinates are rotated 45 or -45 degrees w.r.t. the other frame. – Max Aug 24 '18 at 0:53
• For the record: Jake's patch is now incorporated in v3.1 of TikZ. – Stefan Pinnow Jan 15 at 19:15