UPDATE I encountered some minor problems with the above, otherwise fantastic macros as well as those under Henri Menkes link. The main issue is that I find that the yshift
is only correct for a sphere radius of 1. In what follows, I present 3 codes, the last of which might be the most convenient. Needless to say that they are at best minor amendments to the fantastic routines by Alain Matthes.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}
\usepackage{verbatim}
\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % azimuth
\tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % latitude
\pgfmathsetmacro\yshift{\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\NewLatitudePlane[4][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#3} % elevation
\pgfmathsinandcos\sint\cost{#4} % latitude
\pgfmathsetmacro\yshift{#2*\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
% angle of "visibility"
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
\draw[current plane,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][1]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}
%% document-wide tikz options and styles
\tikzset{%
>=latex, % option for nice arrows
inner sep=0pt,%
outer sep=2pt,%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,
fill=black,circle}%
}
\begin{document}
\begin{tikzpicture} % "THE GLOBE" showcase
\def\R{4 } % sphere radius
\def\angEl{20} % elevation angle
\def\angAz{-20} % azimuth angle
\filldraw[ball color=white] (0,0) circle (\R);
\filldraw[fill=white] (0,0) circle (\R);
\foreach \t in {0,30} { \DrawLatitudeCircle[\R]{\t} }
\foreach \t in {-120} { \DrawLongitudeCircle[\R]{\t} }
\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole
\coordinate (O) at (0,0);
\node[circle,draw,black,scale=0.3] at (0,0) {};
\draw[right] node at (0,0){O};
\coordinate[mark coordinate] (N) at (0,\H);
\draw[left] node at (0,\H){N};
\coordinate[mark coordinate] (S) at (0,-\H);
\draw[left] node at (0,-\H){S};
\draw[thick, dashed, black](N)--(S);
\NewLatitudePlane[planeP]{\R}{\angEl}{30};
\path[planeP] (-120:\R) coordinate (P);
\draw[left] node at (P){$P$};
\NewLatitudePlane[equator]{\R}{\angEl}{00};
\path[equator] (-120:\R) coordinate (Pprime);
\draw[left] node at (Pprime){$P'$};
\draw[-,dashed] (O)--(P);
\draw[-,dashed] (O)--(Pprime);
\LongitudePlane[angle]{\angEl}{-120};
\draw[angle,-] (0:1) arc (0:30:1);
\end{tikzpicture}
\end{document}
The only thing I did is to introduce a command \NewLatitudePlane
, which differs from \LatitudePlane
in that it also takes a radius. This is necessary in order to compute the correct yshift
. Then you can define longitude planes and latitude planes and draw all the features within them. The above code yields
I introduced two latitude planes, one at 30 degrees called planeP
, in which I put the point P at -120 degrees longitude, and an equator plane, in which P' is placed at -120 degrees. Then I defined a longitudinal plane for drawing the angle. I did not spend any energy in placing P and P' more nicely.
For the other picture, you may start from
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}
\usepackage{verbatim}
\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % azimuth
\tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % latitude
\pgfmathsetmacro\yshift{\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\NewLatitudePlane[4][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#3} % elevation
\pgfmathsinandcos\sint\cost{#4} % latitude
\pgfmathsetmacro\yshift{#2*\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
% angle of "visibility"
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
\draw[current plane,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][1]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}
%% document-wide tikz options and styles
\tikzset{%
>=latex, % option for nice arrows
inner sep=0pt,%
outer sep=2pt,%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,
fill=black,circle}%
}
\begin{document}
\begin{tikzpicture} % "THE GLOBE" showcase
\def\R{4 } % sphere radius
\def\angEl{20} % elevation angle
\def\angAz{-20} % azimuth angle
\filldraw[ball color=white] (0,0) circle (\R);
\filldraw[fill=white] (0,0) circle (\R);
\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole
\coordinate (O) at (0,0);
\node[circle,draw,black,scale=0.3] at (0,0) {};
\draw[right] node at (0,0){O};
\coordinate[mark coordinate] (N) at (0,\H);
\draw[left] node at (0,\H){N};
\coordinate[mark coordinate] (S) at (0,-\H);
\draw[left] node at (0,-\H){S};
\draw[thick, dashed, black](N)--(S);
\tikzset{
every path/.style={
color=green
}
}
\DrawLatitudeCircle[\R]{0}
\tikzset{
every path/.style={
color=black
}
}
\LongitudePlane[angle]{\angEl}{-80};
\draw[angle,-,red] (-70:\R) arc (-70:90:\R); % note : -70 could also be computed!
\draw[angle,-,red,dashed] (-90:\R) arc (-90:-70:\R); % note : -70 could also be computed!
\path[angle] (00:\R) coordinate (Pprime);
\draw[right] node at (Pprime){$P'$};
\LongitudePlane[angel]{\angEl}{-120};
\draw[angel,-,blue] (-70:\R) arc (-70:90:\R); % note : -70 could also be computed!
\draw[angel,-,blue,dashed] (-90:\R) arc (-90:-70:\R); % note : -70 could also be computed!
\path[angel] (00:\R) coordinate (Oprime);
\draw[left] node at (Oprime){$O'$};
\def\arcrad{2}
\NewLatitudePlane[equator]{\R}{\angEl}{00};
\draw[equator,-,red,dashed] (-120:\arcrad) arc (-120:-80:\arcrad);
\path[equator] (-120:\arcrad) coordinate (m);
\draw[left] node at (m){$m$};
\path[equator] (-80:\arcrad) coordinate (mprime);
\draw[right] node at (mprime){$m'$};
\draw[-,dashed] (Oprime) -- (O) -- (Pprime);
\end{tikzpicture}
\end{document}

Here is a version that supports latitude and longitude arcs.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fadings,decorations.pathreplacing,shadings}
\usepackage{verbatim}
\newcommand\pgfmathsinandcos[3]{%
\pgfmathsetmacro#1{sin(#3)}%
\pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % azimuth
\tikzset{#1/.style={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#2} % elevation
\pgfmathsinandcos\sint\cost{#3} % latitude
\pgfmathsetmacro\yshift{\RadiusSphere*\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\NewLatitudePlane[4][current plane]{%
\pgfmathsinandcos\sinEl\cosEl{#3} % elevation
\pgfmathsinandcos\sint\cost{#4} % latitude
\pgfmathsetmacro\yshift{#2*\cosEl*\sint}
\tikzset{#1/.style={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
% angle of "visibility"
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
\draw[current plane,opacity=0.4] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLongitudeArc[4][black]{
\LongitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=1}}
\pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
\pgfmathsetmacro\angA{mod(max(\angVis,#3),360)} %
\pgfmathsetmacro\angB{mod(min(\angVis+180,#4),360} %
\draw[current plane,#1,opacity=0.4] (#3:\RadiusSphere) arc (#3:#4:\RadiusSphere);
\draw[current plane,#1] (\angA:\RadiusSphere) arc (\angA:\angB:\RadiusSphere);
}%
\newcommand\DrawLatitudeCircle[2][1]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=#1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
\draw[current plane,opacity=0.4] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}
\newcommand\DrawLatitudeArc[4][black]{
\LatitudePlane{\angEl}{#2}
\tikzset{current plane/.prefix style={scale=1}}
\pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
% angle of "visibility"
\pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
\pgfmathsetmacro\angA{max(min(\angVis,#3),-\angVis-180)} %
\pgfmathsetmacro\angB{min(\angVis,#4)} %
\draw[current plane,#1,opacity=0.4] (#3:\RadiusSphere) arc (#3:#4:\RadiusSphere);
\draw[current plane,#1] (\angA:\RadiusSphere) arc (\angA:\angB:\RadiusSphere);
}
%% document-wide tikz options and styles
\tikzset{%
>=latex, % option for nice arrows
inner sep=0pt,%
outer sep=2pt,%
mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,
fill=black,circle}%
}
\begin{document}
\begin{tikzpicture} % "THE GLOBE" showcase
\def\RadiusSphere{4} % sphere radius
\def\angEl{20} % elevation angle
\def\angAz{-20} % azimuth angle
\shade[ball color = gray!40, opacity = 0.5] (0,0) circle (\RadiusSphere);
\pgfmathsetmacro\H{\RadiusSphere*cos(\angEl)} % distance to north pole
\coordinate (O) at (0,0);
\node[circle,draw,black,scale=0.3] at (0,0) {};
\draw[right] node at (0,0){O};
\coordinate[mark coordinate] (N) at (0,\H);
\draw[left] node at (0,\H){N};
\coordinate[mark coordinate] (S) at (0,-\H);
\draw[left] node at (0,-\H){S};
\draw[thick, dashed, black](N)--(S);
\tikzset{
every path/.style={
color=green!50!black
}
}
\DrawLatitudeCircle[\RadiusSphere]{0}
\tikzset{
every path/.style={
color=black
}
}
\DrawLatitudeArc[blue]{30}{-90}{90}
\DrawLatitudeArc[blue]{20}{-200}{20}
\LongitudePlane[angle]{\angEl}{-80};
\DrawLongitudeArc[red]{-80}{-90}{90}
\path[angle] (00:\RadiusSphere) coordinate (Pprime);
\draw[right] node at (Pprime){$P'$};
\LongitudePlane[angel]{\angEl}{-120};
\DrawLongitudeArc[blue]{-120}{-90}{90}
\path[angel] (00:\RadiusSphere) coordinate (Oprime);
\draw[left] node at (Oprime){$O'$};
\def\arcrad{2}
\NewLatitudePlane[equator]{\RadiusSphere}{\angEl}{00};
\draw[equator,-,red,dashed] (-120:\arcrad) arc (-120:-80:\arcrad);
\path[equator] (-120:\arcrad) coordinate (m);
\draw[left] node at (m){$m$};
\path[equator] (-80:\arcrad) coordinate (mprime);
\draw[right] node at (mprime){$m'$};
\draw[-,dashed] (Oprime) -- (O) -- (Pprime);
\end{tikzpicture}
\end{document}
