我正在尝试重现类似四边形球体的 3D 图(取自这里)使用TikZ:
重要的是,我使用特定的天体坐标(纬度/经度可以毫无问题地替换),这样我就可以绘制单独的箱体并标记它们。更一般地说,问题是如何从提供的坐标绘制大圆弧(方案中的所有线都是大圆)。我的目标是在本地坐标中工作时执行此操作,例如“从 (0°,-45°) 到 (0°,45°) 到 (45°,45°) 再到 (45°,0°) 绘制一条弧”。
我从以下来源找到了解决此问题的所有部分:
第一个链接在 Metapost 中,但包含数学知识,后两个链接会用到这些知识。但是,后两种方法完全不同,我无法概括解决方案。一种用于\tdplotsetmaincoords
设置视角和旋转坐标系,另一种用于\begin{scope}
修改框架。我尝试从基础开始重建每个图,但无法充分抽象出几何图形,同时能够任意旋转球体并使用我的“原生”坐标(并保持绘制“隐藏”虚线的能力)。有很多活动部件!(上面示例的视觉质量优于上面的图表。)
非常感谢您的帮助。
答案1
我们先来讨论一下如何构造解决方案。当然,这是用 LaTeX 完成的,因为需要几个方程式。
\documentclass[fleqn]{beamer}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{overlay-beamer-styles}
\makeatletter
\newcommand*{\currentoverlaynumber}{\number\beamer@slideinframe}
\makeatother
\newcommand{\Explain}[1]{\only<.(1)>{\begin{enumerate}
\item[\currentoverlaynumber.] #1
\end{enumerate}}}
\begin{document}
\begin{frame}[t]
\frametitle{How to construct a great circle arc}
\begin{center}
\begin{tikzpicture}[declare function={R=3;},bullet/.style={circle,inner
sep=1.5pt,fill},>=stealth]
\shade[ball color = black!80,transform canvas={rotate=-35},
visible on=<1-2>] (0,0,0) coordinate (O) circle[radius=R];
\tdplotsetmaincoords{70}{0}
\tdplotsetrotatedcoords{0}{20}{0}
\begin{scope}[tdplot_rotated_coords]
\path[blue,visible on=<2>]
({R*cos(-130)},{R*sin(-130)},0) node[bullet,label=above:$\vec A$](A){}
({R*cos(-30)},{R*sin(-30)},0) node[bullet,label=above:$\vec B$](B){};
\begin{scope}[visible on=<3->,thick]
\begin{scope}
\clip plot[variable=\t,domain=-180:170,smooth cycle,samples=36]
({R*cos(\t)},{R*sin(\t)},0);
\shade[tdplot_screen_coords,ball color = gray!50,
transform canvas={rotate=-215}] (0,0,0) circle[radius=R];
\end{scope}
\begin{scope}
\clip plot[variable=\t,domain=-180:00,smooth,samples=19] ({R*cos(\t)},{R*sin(\t)},0)
-- plot[variable=\t,domain=00:-180,smooth,samples=19] ({R*cos(\t)},{0},{R*sin(\t)})
--cycle;
\shade[tdplot_screen_coords,ball color = black!80,
transform canvas={rotate=-35}] (0,0,0) circle[radius=R];
\end{scope}
\draw[blue,->] (O) -- (A);
\draw[blue,->] (O) -- (B);
\path[red] (O) node[bullet,label=above left:$\vec O$]{};
\draw[red,->,visible on=<4->] (O) -- (0,0,2) node[above left]{$\vec n$};
\end{scope}
\path[blue]
({R*cos(-130)},{R*sin(-130)},0) node[bullet,label=above:$\vec A$]{}
({R*cos(-30)},{R*sin(-30)},0) node[bullet,label=above:$\vec B$]{};
\draw[orange,visible on=<5->]
plot[variable=\t,domain=-130:-30,smooth,samples=19] ({cos(\t)},{sin(\t)},0)
({cos(-80)},{sin(-80)},0) node[below] {$\alpha$};
\draw[magenta,visible on=<5->,->] (O) -- ({R*cos(-130+90)},{R*sin(-130+90)},0) coordinate[label=below:$\vec y$]
(y);
\draw[magenta,visible on=<5->,->] (O) -- (A) coordinate[label=below:$\vec x$]
(y);
\end{scope}
\end{tikzpicture}
\end{center}
\Explain{Consider a sphere of radius $R$.}\pause
\Explain{Consider two points on the sphere, $\vec A$ and $\vec B$.}\pause
\Explain{We know of course the center of the sphere, $\vec O$.}\pause
\Explain{The normal of the plane in which the great circle lies is
$\vec n=\vec A\times\vec B$.}\pause
\Explain{The angle $\alpha$ between $\vec A$ and $\vec B$ is
$\displaystyle\sphericalangle(\vec A,\vec B)=\arccos\left(\frac{\vec A\cdot\vec
B}{R^2}\right)$.}\pause
\Explain{So all we need to do is to draw an arc of angle $\alpha$ in a plane
spanned by $\vec x:=\vec A$ and and a normalized version of $\vec y=\vec n\times
\vec A$.}\pause
\Explain{What remains to do is to check whether a given point is on the fore or
back side of the sphere.}
\end{frame}
\begin{frame}[t,allowframebreaks]
\frametitle{Visibility check and sceen depth}
\begin{enumerate}
\item Orthographic projections are obtained by truncating the column vectors of
a 3d rotatinon matrix,
\begin{equation} O=\begin{pmatrix}
O_{11} & O_{12} & O_{13} \\
O_{21} & O_{22} & O_{23} \\
O_{31} & O_{32} & O_{33} \\
\end{pmatrix}
\end{equation}
so that
\begin{subequations}
\begin{align}
\vec e_x&=\begin{pmatrix}O_{11}\\ O_{21}\end{pmatrix}
=\begin{pmatrix}\texttt{\textbackslash pgf@xx}\\
\texttt{\textbackslash pgf@xy}\end{pmatrix}\;,\\
\vec e_y&=\begin{pmatrix}O_{21}\\ O_{22}\end{pmatrix}
=\begin{pmatrix}\texttt{\textbackslash pgf@yx}\\
\texttt{\textbackslash pgf@yy}\end{pmatrix}\;,\\
\vec e_z&=\begin{pmatrix}O_{13}\\ O_{23}\end{pmatrix}
=\begin{pmatrix}\texttt{\textbackslash pgf@zx}\\
\texttt{\textbackslash pgf@zy}\end{pmatrix}\;,
\end{align}
\end{subequations}
where we indicate the internal pgf dimensions these components get stored in.
\pause
\item The third row of $O$ can be (almost trivially) reconstructed via
\begin{align}
\vec n=\begin{pmatrix}
O_{31} \\ O_{32} \\ O_{33}\\
\end{pmatrix}
&=
\begin{pmatrix}
O_{11} \\ O_{12} \\ O_{13}\\
\end{pmatrix}\times
\begin{pmatrix}
O_{21} \\ O_{22} \\ O_{23}\\
\end{pmatrix}\notag\\
&=
\begin{pmatrix}
\texttt{\textbackslash pgf@xx} \\
\texttt{\textbackslash pgf@yx} \\
\texttt{\textbackslash pgf@zx}\\
\end{pmatrix}\times
\begin{pmatrix}
\texttt{\textbackslash pgf@xy} \\
\texttt{\textbackslash pgf@yy} \\
\texttt{\textbackslash pgf@zx}\\
\end{pmatrix}\;.\label{eq:d_screen}
\end{align}
\pause
\item The screen depth, i.e.\ the amount by which a point $\vec P=(x,y,z)$ is above or below the
screen zero plane, is thus given by
\begin{equation}
d_\mathsf{screen}=\vec P\cdot \vec n\;.
\end{equation}
The zero of $d_\mathsf{screen}$ depends on conventions. However, the larger
$d_\mathsf{screen}$ is, the further ``above'' is $\vec P$ of the screen. This
means that points with larger $d_\mathsf{screen}$ are closer to the
``observer''. Proper 3d ordering ``only'' means drawing objects with larger
$d_\mathsf{screen}$ later. As is evident from \eqref{eq:d_screen}, one can
compute $d_\mathsf{screen}$ in a package--independent way, i.e.\ without
knowing whether the 3d view got installed with \texttt{tikz-3dplot},
the official \texttt{perspective} library or the inofficial
\texttt{3dtools} library.
\pause
\item With regards to the visbility on a sphere, since by convention the center
of the sphere is at the origin, only points with nonnegative
$d_\mathsf{screen}$ are on the foreside of the sphere, i.e.\ visible. As
explained before, establishing the visibility can thus be done in a package- or
convention--independent way. Of course, if the user does not use an
orthographic projection, none of this applies in full generality.
\end{enumerate}
\end{frame}
\end{document}
现在来回答这个问题。这是一个沿着大圆弧连接球体上两点的东西。它们可以有任意极坐标。即使我tikz-3dplot
在这里工作,你也可以使用任何安装正交视图的工具。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{fpu}
\makeatletter
\pgfmathdeclarefunction{isfore}{3}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{%
sign(((\the\pgf@yx)*(\the\pgf@zy)-(\the\pgf@yy)*(\the\pgf@zx))*(#1)+
((\the\pgf@zx)*(\the\pgf@xy)-(\the\pgf@xx)*(\the\pgf@zy))*(#2)+
((\the\pgf@xx)*(\the\pgf@yy)-(\the\pgf@yx)*(\the\pgf@xy))*(#3))}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\tikzset{great circle arc/.cd,
theta1/.initial=0,phi1/.initial=0,theta2/.initial=0,phi2/.initial=30,
r/.initial=R,fore/.style={draw=white,semithick},back/.style={draw=gray,very thin}}
\newcommand\GreatCircleArc[2][]{%
\tikzset{great circle arc/.cd,#2}%
\def\pv##1{\pgfkeysvalueof{/tikz/great circle arc/##1}}%
% Cartesian coordinates of the first point (A)
\pgfmathsetmacro\tikz@td@Ax{\pv{r}*cos(\pv{theta1})*cos(\pv{phi1})}%
\pgfmathsetmacro\tikz@td@Ay{\pv{r}*cos(\pv{theta1})*sin(\pv{phi1})}%
\pgfmathsetmacro\tikz@td@Az{\pv{r}*sin(\pv{theta1})}%
% Cartesian coordinates of the second point (B)
\pgfmathsetmacro\tikz@td@Bx{\pv{r}*cos(\pv{theta2})*cos(\pv{phi2})}%
\pgfmathsetmacro\tikz@td@By{\pv{r}*cos(\pv{theta2})*sin(\pv{phi2})}%
\pgfmathsetmacro\tikz@td@Bz{\pv{r}*sin(\pv{theta2})}%
% cross product C=AxB
\pgfmathsetmacro\tikz@td@Cx{(\tikz@td@Ay)*(\tikz@td@Bz)-(\tikz@td@By)*(\tikz@td@Az)}%
\pgfmathsetmacro\tikz@td@Cy{(\tikz@td@Az)*(\tikz@td@Bx)-(\tikz@td@Bz)*(\tikz@td@Ax)}%
\pgfmathsetmacro\tikz@td@Cz{(\tikz@td@Ax)*(\tikz@td@By)-(\tikz@td@Bx)*(\tikz@td@Ay)}%
% normalize C to have length r
\pgfmathsetmacro\pgfutil@tempa{sqrt((\tikz@td@Cx)*(\tikz@td@Cx)+(\tikz@td@Cy)*(\tikz@td@Cy)+(\tikz@td@Cz)*(\tikz@td@Cz))/\pv{r}}%
\pgfmathsetmacro\tikz@td@Cx{\tikz@td@Cx/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Cy{\tikz@td@Cy/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Cz{\tikz@td@Cz/\pgfutil@tempa}%
% angle between A and B
\pgfmathsetmacro\tikz@td@AdotB{((\tikz@td@Ax)*(\tikz@td@Bx)+
(\tikz@td@Ay)*(\tikz@td@By)+(\tikz@td@Az)*(\tikz@td@Bz))/(\pv{r}*\pv{r})}%
\pgfmathsetmacro\tikz@td@angle{acos(\tikz@td@AdotB)}%
% cross product D=AxC
\pgfmathsetmacro\tikz@td@Dx{(\tikz@td@Ay)*(\tikz@td@Cz)-(\tikz@td@Cy)*(\tikz@td@Az)}%
\pgfmathsetmacro\tikz@td@Dy{(\tikz@td@Az)*(\tikz@td@Cx)-(\tikz@td@Cz)*(\tikz@td@Ax)}%
\pgfmathsetmacro\tikz@td@Dz{(\tikz@td@Ax)*(\tikz@td@Cy)-(\tikz@td@Cx)*(\tikz@td@Ay)}%
\pgfmathsetmacro\pgfutil@tempa{sqrt((\tikz@td@Dx)*(\tikz@td@Dx)+(\tikz@td@Dy)*(\tikz@td@Dy)+(\tikz@td@Dz)*(\tikz@td@Dz))/\pv{r}}%
\pgfmathsetmacro\tikz@td@Dx{\tikz@td@Dx/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Dy{\tikz@td@Dy/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Dz{\tikz@td@Dz/\pgfutil@tempa}%
%\typeout{A=(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az),B=(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz),C=(\tikz@td@Cx,\tikz@td@Cy,\tikz@td@Cz)}
%\typeout{\tikz@td@AdotB,\tikz@td@angle}
\edef\pgfutil@tempa{0}%
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\edef\tikz@td@lstviscoords{}%
\else
\edef\tikz@td@lsthidcoords{}%
\edef\tikz@td@lstviscoords{(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\fi
\pgfmathtruncatemacro\pgfutil@tempb{acos(\tikz@td@AdotB)}%
\pgfmathtruncatemacro\pgfutil@tempc{sign(\pgfutil@tempb)}%
\loop
\pgfmathsetmacro{\tmpx}{cos(\pgfutil@tempa)*\tikz@td@Ax-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dx}%
\pgfmathsetmacro{\tmpy}{cos(\pgfutil@tempa)*\tikz@td@Ay-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dy}%
\pgfmathsetmacro{\tmpz}{cos(\pgfutil@tempa)*\tikz@td@Az-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dz}%
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tmpx,\tmpy,\tmpz)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{\tikz@td@lsthidcoords\space(\tmpx,\tmpy,\tmpz)}%
\else
\edef\tikz@td@lstviscoords{\tikz@td@lstviscoords\space(\tmpx,\tmpy,\tmpz)}%
\fi
\edef\pgfutil@tempa{\the\numexpr\pgfutil@tempa+1}%
\ifnum\pgfutil@tempa<\the\numexpr\pgfutil@tempc*\pgfutil@tempb\relax
\repeat
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{\tikz@td@lsthidcoords\space(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\else
\edef\tikz@td@lstviscoords{\tikz@td@lstviscoords\space(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\fi
\ifx\tikz@td@lsthidcoords\pgfutil@empty%
\else
\draw[great circle arc/back] plot coordinates {\tikz@td@lsthidcoords};%
\fi
\ifx\tikz@td@lstviscoords\pgfutil@empty%
\else
\draw[great circle arc/fore] plot coordinates {\tikz@td@lstviscoords};%
\fi
}
\makeatother
\begin{document}
\begin{tikzpicture}[declare function={R=3;},bullet/.style={circle,fill,inner
sep=2pt}]
\shade[ball color = black!80,transform canvas={rotate=-35}] (0,0,0) circle[radius=R];
\tdplotsetmaincoords{70}{110}
\begin{scope}[tdplot_main_coords]
\GreatCircleArc{theta1=-40,phi1=5,theta2=-40,phi2=100}
\GreatCircleArc{theta1=-40,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=0,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=40,phi2=100}
\GreatCircleArc{theta1=-40,phi1=5,theta2=40,phi2=5}
\GreatCircleArc{theta1=-40,phi1=100,theta2=40,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=40,phi2=-90}
\end{scope}
\end{tikzpicture}
\end{document}
视图可自由调整。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{fpu}
\makeatletter
\pgfmathdeclarefunction{isfore}{3}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{%
sign(((\the\pgf@yx)*(\the\pgf@zy)-(\the\pgf@yy)*(\the\pgf@zx))*(#1)+
((\the\pgf@zx)*(\the\pgf@xy)-(\the\pgf@xx)*(\the\pgf@zy))*(#2)+
((\the\pgf@xx)*(\the\pgf@yy)-(\the\pgf@yx)*(\the\pgf@xy))*(#3))}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\tikzset{great circle arc/.cd,
theta1/.initial=0,phi1/.initial=0,theta2/.initial=0,phi2/.initial=30,
r/.initial=R,fore/.style={draw=white,semithick},back/.style={draw=gray,very thin}}
\newcommand\GreatCircleArc[2][]{%
\tikzset{great circle arc/.cd,#2}%
\def\pv##1{\pgfkeysvalueof{/tikz/great circle arc/##1}}%
% Cartesian coordinates of the first point (A)
\pgfmathsetmacro\tikz@td@Ax{\pv{r}*cos(\pv{theta1})*cos(\pv{phi1})}%
\pgfmathsetmacro\tikz@td@Ay{\pv{r}*cos(\pv{theta1})*sin(\pv{phi1})}%
\pgfmathsetmacro\tikz@td@Az{\pv{r}*sin(\pv{theta1})}%
% Cartesian coordinates of the second point (B)
\pgfmathsetmacro\tikz@td@Bx{\pv{r}*cos(\pv{theta2})*cos(\pv{phi2})}%
\pgfmathsetmacro\tikz@td@By{\pv{r}*cos(\pv{theta2})*sin(\pv{phi2})}%
\pgfmathsetmacro\tikz@td@Bz{\pv{r}*sin(\pv{theta2})}%
% cross product C=AxB
\pgfmathsetmacro\tikz@td@Cx{(\tikz@td@Ay)*(\tikz@td@Bz)-(\tikz@td@By)*(\tikz@td@Az)}%
\pgfmathsetmacro\tikz@td@Cy{(\tikz@td@Az)*(\tikz@td@Bx)-(\tikz@td@Bz)*(\tikz@td@Ax)}%
\pgfmathsetmacro\tikz@td@Cz{(\tikz@td@Ax)*(\tikz@td@By)-(\tikz@td@Bx)*(\tikz@td@Ay)}%
% normalize C to have length r
\pgfmathsetmacro\pgfutil@tempa{sqrt((\tikz@td@Cx)*(\tikz@td@Cx)+(\tikz@td@Cy)*(\tikz@td@Cy)+(\tikz@td@Cz)*(\tikz@td@Cz))/\pv{r}}%
\pgfmathsetmacro\tikz@td@Cx{\tikz@td@Cx/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Cy{\tikz@td@Cy/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Cz{\tikz@td@Cz/\pgfutil@tempa}%
% angle between A and B
\pgfmathsetmacro\tikz@td@AdotB{((\tikz@td@Ax)*(\tikz@td@Bx)+
(\tikz@td@Ay)*(\tikz@td@By)+(\tikz@td@Az)*(\tikz@td@Bz))/(\pv{r}*\pv{r})}%
\pgfmathsetmacro\tikz@td@angle{acos(\tikz@td@AdotB)}%
% cross product D=AxC
\pgfmathsetmacro\tikz@td@Dx{(\tikz@td@Ay)*(\tikz@td@Cz)-(\tikz@td@Cy)*(\tikz@td@Az)}%
\pgfmathsetmacro\tikz@td@Dy{(\tikz@td@Az)*(\tikz@td@Cx)-(\tikz@td@Cz)*(\tikz@td@Ax)}%
\pgfmathsetmacro\tikz@td@Dz{(\tikz@td@Ax)*(\tikz@td@Cy)-(\tikz@td@Cx)*(\tikz@td@Ay)}%
\pgfmathsetmacro\pgfutil@tempa{sqrt((\tikz@td@Dx)*(\tikz@td@Dx)+(\tikz@td@Dy)*(\tikz@td@Dy)+(\tikz@td@Dz)*(\tikz@td@Dz))/\pv{r}}%
\pgfmathsetmacro\tikz@td@Dx{\tikz@td@Dx/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Dy{\tikz@td@Dy/\pgfutil@tempa}%
\pgfmathsetmacro\tikz@td@Dz{\tikz@td@Dz/\pgfutil@tempa}%
%\typeout{A=(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az),B=(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz),C=(\tikz@td@Cx,\tikz@td@Cy,\tikz@td@Cz)}
%\typeout{\tikz@td@AdotB,\tikz@td@angle}
\edef\pgfutil@tempa{0}%
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\edef\tikz@td@lstviscoords{}%
\else
\edef\tikz@td@lsthidcoords{}%
\edef\tikz@td@lstviscoords{(\tikz@td@Ax,\tikz@td@Ay,\tikz@td@Az)}%
\fi
\pgfmathtruncatemacro\pgfutil@tempb{acos(\tikz@td@AdotB)}%
\pgfmathtruncatemacro\pgfutil@tempc{sign(\pgfutil@tempb)}%
\loop
\pgfmathsetmacro{\tmpx}{cos(\pgfutil@tempa)*\tikz@td@Ax-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dx}%
\pgfmathsetmacro{\tmpy}{cos(\pgfutil@tempa)*\tikz@td@Ay-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dy}%
\pgfmathsetmacro{\tmpz}{cos(\pgfutil@tempa)*\tikz@td@Az-\pgfutil@tempc*sin(\pgfutil@tempa)*\tikz@td@Dz}%
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tmpx,\tmpy,\tmpz)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{\tikz@td@lsthidcoords\space(\tmpx,\tmpy,\tmpz)}%
\else
\edef\tikz@td@lstviscoords{\tikz@td@lstviscoords\space(\tmpx,\tmpy,\tmpz)}%
\fi
\edef\pgfutil@tempa{\the\numexpr\pgfutil@tempa+1}%
\ifnum\pgfutil@tempa<\the\numexpr\pgfutil@tempc*\pgfutil@tempb\relax
\repeat
\pgfmathtruncatemacro{\pgfutil@tempd}{isfore(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\ifnum\pgfutil@tempd=-1\relax
\edef\tikz@td@lsthidcoords{\tikz@td@lsthidcoords\space(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\else
\edef\tikz@td@lstviscoords{\tikz@td@lstviscoords\space(\tikz@td@Bx,\tikz@td@By,\tikz@td@Bz)}%
\fi
\ifx\tikz@td@lsthidcoords\pgfutil@empty%
\else
\draw[great circle arc/back] plot coordinates {\tikz@td@lsthidcoords};%
\fi
\ifx\tikz@td@lstviscoords\pgfutil@empty%
\else
\draw[great circle arc/fore] plot coordinates {\tikz@td@lstviscoords};%
\fi
}
\makeatother
\begin{document}
\foreach \Angle in {5,15,...,355}
{\tdplotsetmaincoords{90+20*cos(\Angle)}{\Angle}
\begin{tikzpicture}[declare function={R=3;},bullet/.style={circle,fill,inner
sep=2pt}]
\shade[ball color = black!80,transform canvas={rotate=-35}] (0,0,0) circle[radius=R];
\begin{scope}[tdplot_main_coords]
\GreatCircleArc{theta1=-40,phi1=5,theta2=-40,phi2=100}
\GreatCircleArc{theta1=-40,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=0,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=0,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=40,phi2=100}
\GreatCircleArc{theta1=-40,phi1=5,theta2=40,phi2=5}
\GreatCircleArc{theta1=-40,phi1=100,theta2=40,phi2=100}
\GreatCircleArc{theta1=40,phi1=5,theta2=40,phi2=-90}
\end{scope}
\end{tikzpicture}}
\end{document}