如何使用特定坐标在图表上任意旋转绘制大圆?

如何使用特定坐标在图表上任意旋转绘制大圆?

我正在尝试重现类似四边形球体的 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}

在此处输入图片描述

相关内容