如何用 TeX 绘制球形几何图形?

如何用 TeX 绘制球形几何图形?

我从事天体动力学领域的工作,必须使用球面几何进行许多计算。为了直观地展示一些概念,我希望准备一些图形,例如球面三角形、环绕地球的平面或投影到球面上的圆圈。以下是一些示例 (1):

图例 图例

在 TeX 中如何做到这一点?我查看了是否可以用 TikZ 做到这一点,但找不到任何可比较的例子。我相信理论上应该可以准备一个 TikZ 扩展来相当简单地完成这样的事情,但目前我正在寻找一个已经存在的解决方案来完成这样的任务。当我对制作这样的图表更有经验时,我可能会考虑编写一个基本的包。

因此,问题实际上有三方面:

  1. 是否可以使用当前软件包在 LaTeX 中绘制此类图表?
  2. 如果是,用 TikZ 吗?你能给我举个如何开始的例子吗?
  3. 如果没有,您会推荐什么软件来准备和包含这种 3D 图形?

请注意,这不是您有时会在这里遇到的那种问“请帮我做这件事!”的问题。老实说,我曾尝试解决这个问题,但毫无进展。如果能得到答案,那就太好了,我所在领域的很多人都会从中受益。

(1)Wertz,James R.(2009 年)。轨道和星座设计与管理. 纽约:Springer。

答案1

这是一个很长的答案,因为到处都散布着用于球面几何的好工具,所以我创建了几个部分来介绍这些工具。

tikz-3dplot:特别是 tdplotdrawarc

我建议使用 \tdplotdrawarc 。这在 TikZ 和 PGF 手册中有解释。您需要为弧定义三个角度 $\alpha$、$\beta$ 和 $\gamma$,然后是半径、原点、初始角度和最终角度。我在这里提供了一个使用角度的示例。通过此示例,您可以构建解释其他角度组合的新示例。

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{pgfplots}
\usetikzlibrary{calc,3d,intersections, positioning,intersections,shapes}

\newcommand{\InterSec}[3]{%
  \path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
  \pgfextra{\xdef\InterNb{\t}}; }

  \begin{document}
      \begin{center}
          \begin{tikzpicture}[scale=2]
            \pgfmathsetmacro\R{sqrt(3)} 
            \fill[ball color=white!10, opacity=0.1] (0,0,0) circle (\R); % 3D lighting effect
            \tdplotsetmaincoords{80}{110}
            \begin{scope}[tdplot_main_coords, shift={(0,0)}]
              \coordinate (O) at (0,0,0);
               % circle around Cp

            % rotate circle to make it look better.

              \pgfmathsetmacro{\thetavec}{0}
              \pgfmathsetmacro{\phivec}{0}
              \tdplotsetrotatedcoords{\phivec}{\thetavec}{0}
              \tdplotdrawarc[tdplot_rotated_coords,color=blue]{(O)}{\R}{-70}{110}{}{}
              \tdplotdrawarc[tdplot_rotated_coords,color=blue, dashed]{(O)}{\R}{110}{290}{}{}
              \node[] at (-1,2,1) {\textcolor{blue}{\scriptsize 
              $\alpha=\thetavec \, ,  \, $\beta=\phivec}};

              \pgfmathsetmacro{\thetavec}{90};
              \tdplotsetrotatedcoords{\phivec}{\thetavec}{0};
              \tdplotdrawarc[tdplot_rotated_coords,color=brown]{(O)}{\R}{0}{180}{}{};
              \tdplotdrawarc[tdplot_rotated_coords,color=brown, dashed]{(O)}{\R}{180}{360}{}{};
              \node[yshift=4 mm] at (-1,2,1) {\textcolor{brown}{\scriptsize $\alpha=\thetavec \, ,  \, 
                  $\beta=\phivec}};

              \pgfmathsetmacro{\phivec}{90}
              \tdplotsetrotatedcoords{\phivec}{\thetavec}{0};
              \tdplotdrawarc[tdplot_rotated_coords,color=red]{(O)}{\R}{0}{180}{}{};
              \tdplotdrawarc[tdplot_rotated_coords,color=red, dashed]{(O)}{\R}{180}{360}{}{};
              \node[yshift=8 mm] at (-1,2,1) {\textcolor{red}{\scriptsize $\alpha=\thetavec \, ,  \, 
                  $\beta=\phivec}};



              %axis
              \coordinate (X) at (5,0,0) ;
              \coordinate (Y) at (0,3,0) ;
              \coordinate (Z) at (0,0,3) ;

              \draw[-latex] (O) -- (X) node[anchor=west] {$X$};
              \draw[-latex] (O) -- (Y) node[anchor=west] {$Y$};
              \draw[-latex] (O) -- (Z) node[anchor=west] {$Z$};

            \end{scope}
          \end{tikzpicture}
        \end{center}
 \end{document}

对应图为: \tdplotdrawarc 的示例

这是一篇关于在给定北极的情况下绘制赤道的帖子。一个简单的宏来加速编码已知北极,画赤道

假 2D,交叉路口包,以及 [向右弯]、[向左弯] 的指令

有时最好不要去想,而是尝试做 3D。因此,我在这里与使用 tikz-3dplot 的建议相矛盾。想想如何绘制 3D 思维 2D(即椭圆和圆弧)。

下一个示例是对此处显示的示例的改进 球面三角形和大圆。代码基于@Tarass 的深刻见解。此处的示例更多是为了展示 Tikz 的功能及其在其他用途​​上的用途。正如我所说,一般来说,最好使用 \tdplotdrawarc 。

以下是一段代码(从@Tarass 代码复制并修改而来)

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{enumerate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\usepackage{hyperref}
\usepackage{pgfplots}
\usetikzlibrary{calc,3d,intersections, positioning,intersections,shapes}
\pgfplotsset{compat=1.11} 


\newcommand{\InterSec}[3]{%
  \path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
  \pgfextra{\xdef\InterNb{\t}}; }

   \begin{document}
    \begin{center}
       \begin{tikzpicture}

       \pgfmathsetmacro\R{2} 
       \fill[ball color=white!10, opacity=0.2] (0,0,0) circle (\R); % 3D lighting effect



        \foreach \angle[count=\n from 1] in {-5,225,290} {

          \begin{scope}[rotate=\angle]
            \path[draw,dashed,name path global=d\n] (2,0) arc [start angle=0,
              end angle=180,
              x radius=2cm,
            y radius=1cm] ;
            \path[draw,name path global=s\n] (-2,0) arc [start angle=180,
              end angle=360,
              x radius=2cm,
            y radius=1cm] ;
          \end{scope}
        }
        \InterSec{s1}{s2}{I3} ;
        \InterSec{s1}{s3}{I2} ;
        \InterSec{s3}{s2}{I1} ;
        %
        \fill[fill=red,opacity=0.5] (I1) to [bend right=8.5]  (I2) to [bend left=7] 
        (I3) to [bend left=6] (I1);

        \InterSec{d1}{d2}{J3} ;
        \InterSec{d1}{d3}{J2} ;
        \InterSec{d3}{d2}{J1} ;
        %\fill[blue] (J1)--(J2)--(J3)--cycle ;

        \fill[fill=blue,opacity=0.5] (J1) to [bend right=8.5]  (J2) to [bend left=7] 
        (J3) to [bend left=6] (J1);

      \end{tikzpicture}
    \end{center}
    \end{document}

这是照片。 在此处输入图片描述

绘制月牙有时可能很难。我首先参考了一个 StackExchange 链接,其中有一个绘制月牙的问题,以及 metapost 和 TiKz 中的解决方案。链接是: 如何在 TiKz 中绘制月牙形并为其着色

我在这里提供另一个图来展示线段和其半月形之间的对偶性。在这个特定的例子中,我结合了 3D 和 2D,因此回到建议使用 tikz-3dplot:代码如下:

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc,3d,decorations.markings, backgrounds, positioning,intersections,shapes}
\usepackage{pgfplots}

\newcommand{\InterSec}[3]{%
  \path[name intersections={of=#1 and #2, by=#3, sort by=#1,total=\t}]
  \pgfextra{\xdef\InterNb{\t}}; 
}


 \newcommand\getEquator[2]
  {
    \def\yt{#1}
    \def\zt{#2}

    \pgfmathsetmacro{\betav}{acos(\zt)};

    \def\gammav{0}
    \ifthenelse{\equal{\betav}{0.0}}
    {
      \def\alphav{0}
    }
    {
      \pgfmathsetmacro{\alphav}{asin(\yt/(sin(\betav))}
    };
  }


   % to color a line
        \tikzset{test/.style={
          postaction={
            decorate,
            decoration={
              markings,
              mark=at position \pgfdecoratedpathlength-0.5pt with 
              {\arrow[blue,line width=#1] {>}; },
              mark=between positions 0 and \pgfdecoratedpathlength step 0.5pt with {
                \pgfmathsetmacro\myval{multiply(divide(
                  \pgfkeysvalueof{/pgf/decoration/mark info/distance from start}, 
                \pgfdecoratedpathlength),100)};
                \pgfsetfillcolor{blue!\myval!green};
                \pgfpathcircle{\pgfpointorigin}{#1};
                \pgfusepath{fill};}
              }
            }
          }
        }




    \begin{document}

    \begin{tikzpicture}[scale=1.3]
      \coordinate (O) at (0,0,0);

      \tdplotsetmaincoords{60}{110}
      \pgfmathsetmacro\R{sqrt(3)} 
      \fill[ball color=white!10, opacity=0.2, name path global=C] (O) circle (\R); % 3D lighting effect
      \begin{scope}[tdplot_main_coords, shift={(0,0)}]
        \pgfmathsetmacro\R{sqrt(3)} 
        \pgfmathsetmacro{\thetavec}{0};
        \pgfmathsetmacro{\phivec}{0};
        \pgfmathsetmacro{\gammav}{0};
        \tdplotsetrotatedcoords{\phivec}{\thetavec}{\gammav};


        \def\angA{90}
        \def\angB{60}
        \pgfmathsetmacro{\ax}{cos(\angA)}
        \pgfmathsetmacro{\ay}{sin(\angA)}
        \pgfmathsetmacro{\z}{0}
        \pgfmathsetmacro{\bx}{cos(\angB)}
        \pgfmathsetmacro{\by}{sin(\angB)}
        \pgfmathsetmacro{\aax}{\R*cos(\angA)}
        \pgfmathsetmacro{\aay}{\R*sin(\angA)}
        \pgfmathsetmacro{\bbx}{\R*cos(\angB)}
        \pgfmathsetmacro{\bby}{\R*sin(\angB)}

        \coordinate (A) at (\aax,\aay,\z);
        \coordinate (B) at (\bbx,\bby,\z);




        \getEquator{\ay}{\z};
        \tdplotsetrotatedcoords{\alphav}{\betav}{\gammav};
        \tdplotdrawarc[tdplot_rotated_coords,color=green, name path global=GF, opacity=0]
           {(0,0)}{\R}{180}{360}{}{};
        \tdplotdrawarc[tdplot_rotated_coords,color=green, name path global=GB, opacity=0]
           {(0,0)}{\R}{0}{180}{}{};

        \tdplotdrawarc[tdplot_rotated_coords,color=yellow, name path=YB, opacity=0]
           {(0,0)}{\R}{90}{180}{}{};

        \getEquator{\by}{\z};
        \tdplotsetrotatedcoords{\alphav}{\betav}{\gammav};
        \tdplotdrawarc[tdplot_rotated_coords,color=blue, name path=BF, opacity=0]
            {(0,0)}{\R}{180}{360}{}{};
        \tdplotdrawarc[tdplot_rotated_coords,color=blue, name path=BB, opacity=0]
           {(0,0)}{\R}{0}{180}{}{};

        \tdplotdrawarc[tdplot_rotated_coords,color=red, name path=RB, opacity=0]
           {(0,0)}{\R}{90}{180}{}{};

        %\draw[color=red] (A) arc (\angA:\angB:\R); 
        \draw[test=0.2mm] (A) arc (\angA:\angB:\R); 



        \InterSec{GF}{BF}{F};
        \InterSec{GB}{BB}{B};
        \InterSec{C}{GF}{CG};
        \InterSec{C}{BF}{CB};
        \InterSec{C}{RB}{RC};
        \InterSec{GB}{RB}{RBF};
        \InterSec{YB}{C}{T};

        %\draw[] (F) circle (1pt) node[] {\; \; \tiny F};
        %\draw[] (CG) circle (1pt) node[] {\tiny CG};
        %\draw[] (CB) circle (1pt) node[] {\tiny CB};
        %\draw[] (B) circle (1pt) node[] {\tiny B};
        %\draw[] (RBF) circle (1pt) node[] {\; \; \tiny RBF};
        %\draw[] (T) circle (1pt) node[] {\tiny T};
        %\draw[] (RC) circle (1pt) node[] {\tiny RC};




              %axis
        \coordinate (X) at (4,0,0) ;
        \coordinate (Y) at (0,3,0) ;
        \coordinate (Z) at (0,0,3) ;

        \draw[-latex] (O) -- (X) node[anchor=east] {\; \; $X$};
        \draw[-latex] (O) -- (Y) node[anchor=north] {$Y$};
        \draw[-latex] (O) -- (Z) node[anchor=south west] {$Z$};

        \shade[left color=blue, right color=green, opacity=0.8] (F) to [bend right=50] (CB) to 
        [bend right=10] (CG) to [bend left]  (F);
        \shade[left color=blue, right color=green, opacity=0.3] (CB) to [bend right=10] (CG) to 
        [bend right]  (B) to [bend left] (CB);

        \shade[left color=green, right color=blue, opacity=0.3] (B) to [bend right=60] (RC) to 
        [bend right=10]  (RBF) to [bend left ] (B);
        \shade[left color=green, right color=blue, opacity=0.8] (F) to [bend left=10] (RC) to 
        [bend right=10]  (T) to [bend right] (F);

      \end{scope}
    \end{tikzpicture}



     \end{document}

图如下: 段和它的对偶:月牙

坐标转换和绘制圆弧的替代方法

在球面几何中,了解坐标(一个点)在哪里以及如何绘制圆弧是一个基本问题。

可能会造成混淆,因为数学家和物理学家的球面坐标使用不同的符号,以下链接提供了球面(方位角、极角)和笛卡尔坐标之间转换的宏,并解决了地理(纬度、高度)坐标之间的转换:三维球面坐标

最后,由于 TiKz 似乎没有工具来根据中心和半径绘制圆弧,我编写了一个宏并发布了 这里

答案2

R 包 GeoMap 将创建包含大陆地图的地球球形项目。除了验证它是否加载和构建地图外,我没有用过它。如果与 tikzDevice 包结合使用,您将获得可以修改的 tikz 代码。请注意,由于大量使用点进行绘图,它将是一个很大的文件。

一旦完成,您应该能够使用 Sweave 实现,以便所有代码都包含在 LaTeX 文件中。

在使用纯 tikz 构建 tikz 包之前,我认为这只是一种解决方法。

相关内容