我从事天体动力学领域的工作,必须使用球面几何进行许多计算。为了直观地展示一些概念,我希望准备一些图形,例如球面三角形、环绕地球的平面或投影到球面上的圆圈。以下是一些示例 (1):
在 TeX 中如何做到这一点?我查看了是否可以用 TikZ 做到这一点,但找不到任何可比较的例子。我相信理论上应该可以准备一个 TikZ 扩展来相当简单地完成这样的事情,但目前我正在寻找一个已经存在的解决方案来完成这样的任务。当我对制作这样的图表更有经验时,我可能会考虑编写一个基本的包。
因此,问题实际上有三方面:
- 是是否可以使用当前软件包在 LaTeX 中绘制此类图表?
- 如果是,用 TikZ 吗?你能给我举个如何开始的例子吗?
- 如果没有,您会推荐什么软件来准备和包含这种 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}
这是一篇关于在给定北极的情况下绘制赤道的帖子。一个简单的宏来加速编码已知北极,画赤道。
假 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 包之前,我认为这只是一种解决方法。