# 星球尺度、视锥与轨道

本笔记处理相机如何观察星球，以及真实尺度、轨道与渲染参数如何对应。大气散射与气候细节见《星球大气、海洋与气候》；地形和内部结构见《岩质星球地表与内部》。

## 相机视锥与完整星球可见性

### 推导目标与适用范围

### 视锥与 FOV

#### 视觉范围、透视视锥与 FOV 换算

人眼并不是严格意义上的单一对称透视视锥，但在实时渲染、相机模型和星球 Shader 中，可以近似为一个具有水平和垂直视场角的视锥。

典型人眼视野范围可近似为：

| 项目         |        典型范围 |
| ---------- | ----------: |
| 单眼水平视野     | 约 150°–160° |
| 双眼综合水平视野   | 约 200°–220° |
| 双眼重叠区域     |      约 120° |
| 垂直视野       | 约 130°–140° |
| 中央视觉高分辨率区域 |     约 2°–5° |

可以粗略表示为：

```tikz
\usetikzlibrary{arrows.meta}
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \draw[draw=cyan!85, thick] (1.73,0.58) -- (-1.27,2.68);
  \draw[draw=cyan!85, thick] (1.73,0.58) -- (-1.27,-1.52);
  \draw[draw=cyan!85, thick, densely dashed] (1.73,0.58) -- (-1.27,0.58);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (1.88,0.58) {观察者};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-1.13,1.05) {双眼重叠区约 $120^\circ$};
  \draw[draw=cyan!85, thick, -{Latex}] (-2.58,3.15) -- (-0.47,3.13);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,165;blue,0}] at (-1.12,3.48) {总水平视野约 $200^\circ$};
  \draw[draw={rgb,255:red,255;green,216;blue,77}, thick] (1.73,0.58) ++(145.01:0.96) arc[start angle=145.01, end angle=214.99, radius=0.96];
  \pgfresetboundingbox
  \path[use as bounding box] (-12,-7.6) rectangle (12,7.6);
\end{tikzpicture}
```
其中：

* `≈ 200°` 表示包含周边视觉在内的总水平感知范围；
* `≈ 120°` 表示双眼同时覆盖的主要立体视觉区域；
* 普通显示器上的透视相机通常只使用 `60°–90°` 左右的 FOV。

---


标准透视相机可以定义为：

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \draw[draw=cyan!85, thick] (-3.5,-0.17) -- (3.5,2.63);
  \draw[draw=cyan!85, thick] (-3.5,-0.17) -- (3.5,-2.97);
  \draw[draw=cyan!85, thick] (-0.5,-1.37) -- (-0.5,1.03);
  \draw[draw=cyan!85, thick] (3.5,-2.97) -- (3.5,2.63);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-3.5,-0.52) {相机};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-0.5,1.78) {近裁剪面};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (3.5,2.98) {远裁剪面};
\end{tikzpicture}
```
其中：

* `Near`：近平面；
* `Far`：远平面；
* `FOV_y`：垂直视场角；
* `FOV_x`：水平视场角；
* `W/H`：屏幕宽高比。

---


给定垂直视场角：

$$
FOV_y
$$

和宽高比：

$$
a=\frac{W}{H}
$$

则水平视场角为：

$$
\boxed{
FOV_x
=
2\arctan
\left(
a\tan\frac{FOV_y}{2}
\right)
}
$$

例如：

$$
FOV_y=60^\circ
$$

宽高比：

$$
a=\frac{16}{9}
$$

则：

$$
FOV_x
=
2\arctan
\left(
\frac{16}{9}\tan30^\circ
\right)
$$

得到：

$$
\boxed{
FOV_x\approx91.5^\circ
}
$$

因此一个常见相机可以设置为：

```cpp
float fovY = 60.0f;
float nearZ = 0.1f;
float farZ  = 100000.0f;
```

在 `16:9` 屏幕下对应：


---

### 星球视盘几何

#### 观察几何与星球视盘角半径

将地球近似为一个半径为：

$$
R
$$

的球体。

地球平均半径近似：

$$
\boxed{
R=6371\text{ km}
}
$$

观察者位于距离地表高度：

$$
h
$$

的位置。

因此观察者距离地心：

$$
\boxed{
d=R+h
}
$$

建立二维截面：

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \draw[draw=cyan!85, thick, densely dashed] (-2.53,-0.71) -- (-2.4,0.94);
  \draw[draw=cyan!85, thick, densely dashed] (-2.53,-0.71) -- (1.77,0.37);
  \draw[draw=cyan!85, thick] (-2.4,0.94) -- (1.77,0.37);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-2.53,-1.01) {地心 $C$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-2.68,1.41) {切点 $T$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (2.86,0.41) {观察者 $O$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-3.4,-0.17) {$CT=R$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (0.54,-0.64) {$CO=R+h$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,165;blue,0}] at (-0.69,1.15) {$CT\perp OT$};
  \draw[draw=cyan, thick] (-2.53,-0.71) circle (1.65);
  \draw[draw={rgb,255:red,255;green,216;blue,77}, thick] (1.77,0.37) ++(-165.9:1.77) arc[start angle=-165.9, end angle=-187.78, radius=1.77];
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=white] at (-0.44,0.26) {$\theta$};
\end{tikzpicture}
```
其中：

$$
CT\perp OT
$$

因此三角形 `COT` 是直角三角形。

---


定义：

$$
\theta
$$

为地球视盘的角半径。

也就是从观察者看：


完整地球的角直径为：

$$
\boxed{
\Phi=2\theta
}
$$

在直角三角形 `COT` 中：

$$
CT=R
$$

$$
CO=R+h
$$

根据正弦关系：

$$
\sin\theta
=
\frac{CT}{CO}
$$

因此：

$$
\sin\theta
=
\frac{R}{R+h}
$$

得到：

$$
\boxed{
\theta
=
\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

所以完整地球的角直径：

$$
\boxed{
\Phi(h)
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

这就是相机高度与地球在视野中所占角度之间的关系。

---

#### 由 FOV 反求完整星球可见距离

如果希望完整地球轮廓刚好进入一个角度为：

$$
\Phi
$$

的视锥，则：

$$
\Phi
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
$$

两边除以 2：

$$
\frac{\Phi}{2}
=
\arcsin
\left(
\frac{R}{R+h}
\right)
$$

两边取正弦：

$$
\sin\frac{\Phi}{2}
=
\frac{R}{R+h}
$$

于是：

$$
R+h
=
\frac{R}{\sin(\Phi/2)}
$$

最终得到：

$$
\boxed{
h
=
\frac{R}{\sin(\Phi/2)}
-
R
}
$$

这是完整地球进入指定视锥的最低观察高度。

---

### 数值结果与近似结论

#### 不同 FOV 下的地球数值结果

取：

$$
R=6371\text{ km}
$$

---


$$
h
=
\frac{6371}{\sin30^\circ}
-
6371
$$

由于：

$$
\sin30^\circ=0.5
$$

因此：

$$
h
=
12742-6371
$$

得到：

$$
\boxed{
h\approx6371\text{ km}
}
$$

---


$$
h
=
\frac{6371}{\sin45^\circ}
-
6371
$$

$$
\sin45^\circ
\approx0.7071
$$

因此：

$$
h
\approx
\frac{6371}{0.7071}
-
6371
$$

得到：

$$
\boxed{
h\approx2639\text{ km}
}
$$

---


$$
h
=
\frac{6371}{\sin60^\circ}
-
6371
$$

由于：

$$
\sin60^\circ
=
\frac{\sqrt3}{2}
\approx0.8660
$$

所以：

$$
h
\approx
7357-6371
$$

得到：

$$
\boxed{
h\approx986\text{ km}
}
$$

这大致对应双眼主要重叠视野范围。

---


$$
h
=
\frac{6371}{\sin70^\circ}
-
6371
$$

$$
\sin70^\circ
\approx0.9397
$$

因此：

$$
h
\approx
6779-6371
$$

得到：

$$
\boxed{
h\approx408\text{ km}
}
$$

这已经接近国际空间站典型轨道高度。

---

#### 高度、角直径与近地极限

|   高度 \(h\) | 地球角直径 \(\Phi\) |
| ---------: | -------------: |
|       0 km |           180° |
|     100 km |         ≈ 160° |
|     400 km |         ≈ 140° |
|    1000 km |         ≈ 120° |
|    2000 km |         ≈ 100° |
|    2639 km |          ≈ 90° |
|    6371 km |          ≈ 60° |
|  35,786 km |        ≈ 17.4° |
| 384,400 km |         ≈ 1.9° |

其中地球同步轨道高度约：

$$
h=35786\text{ km}
$$

此时：

$$
\Phi
=
2\arcsin
\left(
\frac{6371}{42157}
\right)
$$

约为：

$$
\boxed{
\Phi\approx17.4^\circ
}
$$

而在月球距离附近：

$$
h\approx384400\text{ km}
$$

地球角直径约：

$$
\boxed{
\Phi\approx1.9^\circ
}
$$

---


当：

$$
h=0
$$

时：

$$
\Phi
=
2\arcsin
\left(
\frac{R}{R}
\right)
$$

所以：

$$
\Phi
=
2\arcsin(1)
$$

$$
\boxed{
\Phi=180^\circ
}
$$

数学意义上，这是因为观察点位于球面上，此时球体占据观察者前方整个半空间。

但这并不意味着站在地面可以看见完整地球。

因为观察者本身就在地球表面，球体绝大部分被地平线遮挡。

因此：

> “球体占据视野角度”与“能够看到完整球体外轮廓”需要区分。

严格意义上的完整圆盘需要：

$$
h>0
$$

并且高度越低，圆盘越接近占满整个视野。

---


如果采用不同的人眼有效视野：

| 有效视锥 |      最低高度 |
| ---: | --------: |
|  60° | ≈ 6371 km |
|  90° | ≈ 2639 km |
| 120° |  ≈ 986 km |
| 130° |  ≈ 658 km |
| 140° |  ≈ 408 km |

因此，如果采用双眼主要重叠视觉范围：

$$
\Phi\approx120^\circ
$$

则：

$$
\boxed{
h\approx1000\text{ km}
}
$$

可以认为：

> 在距离地表约 1000 km 时，人眼主要双眼视区可以同时容纳完整地球轮廓。

如果把更外围的垂直周边视觉也算入：

$$
\Phi\approx140^\circ
$$

则只需要：

$$
\boxed{
h\approx400\text{ km}
}
$$

但此时地球会几乎占满整个视觉范围。

---

### 相机与 Shader 实现

#### 相机约束、核心公式与实现

对于半径为：

$$
R
$$

的任意星球，相机高度：

$$
h
$$

可以直接得到星球角尺寸：

$$
\boxed{
planetAngularDiameter
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

如果相机使用垂直 FOV：

$$
FOV_y
$$

则星球大致占屏幕垂直比例：

$$
\boxed{
P
\approx
\frac{\Phi}{FOV_y}
}
$$

其中：

$$
\Phi
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
$$

例如：


则地球直径大约正好占满屏幕高度。

---


```cpp
float planetAngularDiameter(float radius, float height)
{
    float distance = radius + height;

    return 2.0f * asinf(radius / distance);
}
```

结果单位为弧度。

转换为角度：

```cpp
float radiansToDegrees(float x)
{
    return x * 180.0f / 3.14159265359f;
}
```

反过来，根据期望 FOV 计算最低高度：

```cpp
float heightForFullPlanet(float radius, float fovRadians)
{
    return radius / sinf(fovRadians * 0.5f) - radius;
}
```

---


观察高度：

$$
\boxed{
d=R+h
}
$$

星球角半径：

$$
\boxed{
\theta
=
\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

星球角直径：

$$
\boxed{
\Phi
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

根据视锥反求高度：

$$
\boxed{
h
=
\frac{R}{\sin(FOV/2)}
-
R
}
$$

对于地球：

$$
\boxed{
R\approx6371\text{ km}
}
$$

若使用约 `120°` 的有效视锥：

$$
\boxed{
h\approx986\text{ km}
}
$$

---

## 地球尺度、大气层与同步轨道

### 地球尺度与视锥复核

#### 地球参数与单位复核

地球平均半径：

$$
R_E \approx 6371\text{ km}
$$

地球赤道半径：

$$
R_{eq} \approx 6378.1\text{ km}
$$

地球极半径：

$$
R_p \approx 6356.8\text{ km}
$$

一般星球渲染中，可以近似：

$$
\boxed{R_E = 6371\text{ km}}
$$

地球直径：

$$
D_E = 2R_E
$$

因此：

$$
\boxed{D_E \approx 12742\text{ km}}
$$

---


人眼并不是严格的单一透视视锥，但实时渲染中可以使用透视视锥近似。

典型视野范围：

| 类型        |          典型范围 |
| --------- | ------------: |
| 单眼水平视野    | 约 150° ~ 160° |
| 双眼综合水平视野  | 约 200° ~ 220° |
| 双眼重叠区域    |        约 120° |
| 垂直视野      | 约 130° ~ 140° |
| 中央高精度视觉区域 |     约 2° ~ 5° |

普通显示器上的 3D 相机通常使用：

$$
FOV_y \approx 45^\circ \sim 90^\circ
$$

典型值：

$$
\boxed{FOV_y=60^\circ}
$$

---



定义：

* \(FOV_y\)：垂直视场角
* \(FOV_x\)：水平视场角
* \(W\)：屏幕宽度
* \(H\)：屏幕高度
* \(a=W/H\)：宽高比
* \(z_n\)：近平面
* \(z_f\)：远平面

---


屏幕宽高比：

$$
a=\frac{W}{H}
$$

水平 FOV 与垂直 FOV 的关系：

$$
\boxed{
FOV_x
=
2\arctan
\left(
a\tan\frac{FOV_y}{2}
\right)
}
$$

例如：

$$
FOV_y=60^\circ
$$

屏幕宽高比：

$$
a=\frac{16}{9}
$$

则：

$$
FOV_x
=
2\arctan
\left(
\frac{16}{9}\tan30^\circ
\right)
$$

得到：

$$
\boxed{
FOV_x\approx91.5^\circ
}
$$

---


设：

* 地球半径：\(R\)
* 观察者距地表高度：\(h\)
* 观察者距地心距离：\(d\)

则：

$$
\boxed{
d=R+h
}
$$

二维截面：


三角形 \(COT\) 为直角三角形。

---


定义：

$$
\theta
$$

为地球视盘的角半径。

因为：

$$
CT=R
$$

且：

$$
CO=R+h
$$

所以：

$$
\sin\theta
=
\frac{CT}{CO}
$$

即：

$$
\sin\theta
=
\frac{R}{R+h}
$$

因此：

$$
\boxed{
\theta
=
\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

完整地球的角直径：

$$
\Phi=2\theta
$$

所以：

$$
\boxed{
\Phi(h)
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

---


如果要求完整地球刚好进入视锥：

$$
FOV=\Phi
$$

则：

$$
FOV
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
$$

两边除以 2：

$$
\frac{FOV}{2}
=
\arcsin
\left(
\frac{R}{R+h}
\right)
$$

取正弦：

$$
\sin\frac{FOV}{2}
=
\frac{R}{R+h}
$$

于是：

$$
R+h
=
\frac{R}
{\sin(FOV/2)}
$$

最终得到：

$$
\boxed{
h
=
\frac{R}
{\sin(FOV/2)}
-R
}
$$

这是给定有效视锥时，完整球体轮廓刚好进入视锥所对应的高度。

---


取：

$$
R=6371\text{ km}
$$

得到：

|  FOV |      最低高度 |
| ---: | --------: |
|  60° | ≈ 6371 km |
|  90° | ≈ 2639 km |
| 100° | ≈ 1946 km |
| 120° |  ≈ 986 km |
| 130° |  ≈ 658 km |
| 140° |  ≈ 408 km |
| 150° |  ≈ 225 km |
| 160° |   ≈ 98 km |
| 180° |    → 0 km |

如果采用双眼主要重叠视觉范围：

$$
FOV\approx120^\circ
$$

则：

$$
\boxed{
h\approx986\text{ km}
}
$$

约为：

$$
\boxed{
h\approx1000\text{ km}
}
$$

---


使用：

$$
\Phi(h)
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
$$

可以得到：

|       高度 |   地球角直径 |
| -------: | ------: |
|   100 km |  ≈ 160° |
|   400 km |  ≈ 140° |
|  1000 km |  ≈ 120° |
|  2000 km |  ≈ 100° |
|  2639 km |   ≈ 90° |
|  6371 km |   ≈ 60° |
| 20200 km | ≈ 27.7° |
| 35786 km | ≈ 17.4° |
|   月球距离附近 |  ≈ 1.9° |

---

### 大气层尺度

#### 大气边界、尺度高度与散射层

地球大气没有严格的物理外边界。

大气密度随高度连续降低。

通常按照温度结构划分：

| 大气层              |             大致高度 |
| ---------------- | ---------------: |
| 对流层 Troposphere  |        0 ~ 12 km |
| 平流层 Stratosphere |       12 ~ 50 km |
| 中间层 Mesosphere   |       50 ~ 85 km |
| 热层 Thermosphere  |      85 ~ 600 km |
| 外逸层 Exosphere    | 约 600 ~ 10000 km |

示意：

```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \draw[draw=cyan!85, thick] (0,-2.62) -- (0,2.98);
  \draw[draw=cyan!85, thick] (-1.2,-2.62) -- (1.2,-2.62);
  \draw[draw=cyan!85, thick, densely dashed] (-0.9,-2.08) -- (0.9,-2.08);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.95,-2.08) {对流层 0--12 km};
  \draw[draw=cyan!85, thick, densely dashed] (-0.9,-0.97) -- (0.9,-0.97);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.95,-0.97) {平流层 12--50 km};
  \draw[draw=cyan!85, thick, densely dashed] (-0.9,0.13) -- (0.9,0.13);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.95,0.13) {中间层 50--85 km};
  \draw[draw=cyan!85, thick, densely dashed] (-0.9,1.33) -- (0.9,1.33);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.95,1.33) {热层 85--600 km};
  \draw[draw=cyan!85, thick, densely dashed] (-0.9,2.53) -- (0.9,2.53);
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.95,2.53) {外逸层 600--10000 km};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (0,-2.97) {地表};
\end{tikzpicture}
```
---


通常将：

$$
\boxed{
h_K=100\text{ km}
}
$$

作为航空与太空之间的一个工程参考边界。

距离地心：

$$
r_K=R_E+h_K
$$

所以：

$$
r_K=6371+100
$$

得到：

$$
\boxed{
r_K=6471\text{ km}
}
$$

相对于地球半径：

$$
\frac{100}{6371}
\approx0.0157
$$

即：

$$
\boxed{
h_K\approx1.57\%R_E
}
$$

因此在真实星球尺度下，大气层是非常薄的一层。

---


虽然外逸层可以延伸到数千甚至上万公里，但对于大气散射 Shader，没有必要把整个外逸层作为主要光学积分范围。

通常可以设置有效光学大气高度：

$$
\boxed{
H_{atm}\approx80\sim120\text{ km}
}
$$

例如取：

$$
H_{atm}=100\text{ km}
$$

则大气外半径：

$$
R_{atm}
=
R_E+H_{atm}
$$

即：

$$
R_{atm}
=
6371+100
$$

得到：

$$
\boxed{
R_{atm}=6471\text{ km}
}
$$

---


基本指数大气模型：

$$
\boxed{
\rho(h)
=
\rho_0e^{-h/H}
}
$$

其中：

* \(\rho_0\)：基准密度
* \(h\)：距地表高度
* \(H\)：尺度高度 Scale Height

---


空气分子的有效尺度高度可以近似：

$$
H_R\approx8\text{ km}
$$

因此：

$$
\boxed{
\rho_R(h)
=
e^{-h/H_R}
}
$$

---


气溶胶通常集中在更低高度。

可以近似：

$$
H_M\approx1.2\text{ km}
$$

因此：

$$
\boxed{
\rho_M(h)
=
e^{-h/H_M}
}
$$

随着高度增加：

$$
h\rightarrow\infty
$$

有：

$$
\rho(h)\rightarrow0
$$

因此实际 Shader 可以在有限高度停止大气积分。

---

### 轨道与同步轨道

#### 典型轨道与同步轨道推导

| 对象     |           距地表高度 |            距地心距离 |
| ------ | --------------: | ---------------: |
| 地球表面   |            0 km |          6371 km |
| 卡门线    |          100 km |          6471 km |
| ISS    |        ≈ 400 km |        ≈ 6771 km |
| LEO    | 约 160 ~ 2000 km | 约 6531 ~ 8371 km |
| GPS    |      ≈ 20200 km |       ≈ 26571 km |
| GEO    |      ≈ 35786 km |       ≈ 42164 km |
| 月球平均距离 |               — |      ≈ 384400 km |

---


地球同步轨道 Geosynchronous Orbit 的基本条件：

$$
\boxed{
T_{orbit}=T_E
}
$$

其中地球恒星自转周期约：

$$
\boxed{
T_E\approx86164\text{ s}
}
$$

也就是：

$$
23\text{ h }56\text{ min }4\text{ s}
$$

需要注意：

$$
T_E\neq24\text{ h}
$$

24 小时是平均太阳日，而同步轨道对应的是恒星自转周期。

---


设：

* 地球质量：\(M\)
* 卫星质量：\(m\)
* 轨道半径：\(r\)
* 轨道速度：\(v\)
* 轨道周期：\(T\)

万有引力：

$$
F_g
=
\frac{GMm}{r^2}
$$

圆周运动需要的向心力：

$$
F_c
=
m\frac{v^2}{r}
$$

圆轨道满足：

$$
F_g=F_c
$$

所以：

$$
\frac{GMm}{r^2}
=
m\frac{v^2}{r}
$$

消去 \(m\)：

$$
\frac{GM}{r^2}
=
\frac{v^2}{r}
$$

圆轨道速度：

$$
v
=
\frac{2\pi r}{T}
$$

代入：

$$
\frac{GM}{r^2}
=
\frac{1}{r}
\left(
\frac{2\pi r}{T}
\right)^2
$$

展开：

$$
\frac{GM}{r^2}
=
\frac{4\pi^2r}{T^2}
$$

整理：

$$
GMT^2
=
4\pi^2r^3
$$

因此：

$$
r^3
=
\frac{GMT^2}{4\pi^2}
$$

最终得到：

$$
\boxed{
r_{sync}
=
\sqrt[3]
{
\frac{GMT^2}{4\pi^2}
}
}
$$

定义标准引力参数：

$$
\mu=GM
$$

则：

$$
\boxed{
r_{sync}
=
\sqrt[3]
{
\frac{\mu T^2}{4\pi^2}
}
}
$$

---


地球标准引力参数：

$$
\mu_E
\approx
398600.4
\text{ km}^3/\text{s}^2
$$

恒星日：

$$
T=86164\text{ s}
$$

代入：

$$
r_{sync}
=
\sqrt[3]
{
\frac{
398600.4\times86164^2
}{
4\pi^2
}
}
$$

得到：

$$
\boxed{
r_{sync}\approx42164\text{ km}
}
$$

这个值是：

> 距离地心的轨道半径。

采用地球赤道半径：

$$
R_{eq}\approx6378\text{ km}
$$

轨道高度：

$$
h_{GEO}
=
r_{sync}-R_{eq}
$$

因此：

$$
h_{GEO}
=
42164-6378
$$

得到：

$$
\boxed{
h_{GEO}\approx35786\text{ km}
}
$$

---

#### 同步轨道与地球静止轨道的区别


地球同步轨道只要求：

$$
T_{orbit}=T_E
$$

轨道可以具有偏心率：

$$
e\neq0
$$

也可以具有轨道倾角：

$$
i\neq0
$$

因此从地面观察，卫星不一定固定在天空中的一个位置。

---


地球静止轨道 GEO 是同步轨道的特殊情况。

需要近似满足：

$$
\boxed{
e=0
}
$$

即圆轨道。

同时：

$$
\boxed{
i=0^\circ
}
$$

即轨道位于地球赤道平面。

还要求卫星运行方向和地球自转方向一致。

因此：

$$
\boxed{
\text{卫星相对于地面近似静止}
}
$$

---

### 屏幕尺寸与观察尺度

#### GEO 视盘与屏幕占比

GEO 距离地心：

$$
d\approx42164\text{ km}
$$

地球角直径：

$$
\Phi
=
2\arcsin
\left(
\frac{R_E}{d}
\right)
$$

代入：

$$
\Phi
=
2\arcsin
\left(
\frac{6371}{42164}
\right)
$$

得到：

$$
\boxed{
\Phi\approx17.4^\circ
}
$$

因此在 GEO 高度：

> 地球完整圆盘的角直径约为 17.4°。

这比正常人眼视野小很多。

---


假设：

$$
FOV_y=60^\circ
$$

地球角直径：

$$
\Phi=17.4^\circ
$$

不能简单认为屏幕占比严格等于：

$$
\frac{\Phi}{FOV_y}
$$

因为透视投影是正切关系。

精确关系近似为：

$$
\boxed{
P_y
=
\frac{
\tan(\Phi/2)
}{
\tan(FOV_y/2)
}
}
$$

其中 \(P_y\) 表示星球直径占整个屏幕高度的比例。

代入：

$$
P_y
=
\frac{
\tan8.7^\circ
}{
\tan30^\circ
}
$$

得到：

$$
\boxed{
P_y\approx0.265
}
$$

即：

$$
\boxed{
26.5\%
}
$$

所以：

> GEO 高度、60° 垂直 FOV 时，地球直径约占画面高度的四分之一。

---


相机距离星球中心：

$$
d
$$

星球半径：

$$
R
$$

首先计算星球角直径：

$$
\boxed{
\Phi
=
2\arcsin
\left(
\frac{R}{d}
\right)
}
$$

由于：

$$
d=R+h
$$

也可以写成：

$$
\boxed{
\Phi
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

然后根据相机垂直 FOV：

$$
FOV_y
$$

计算星球直径占屏幕高度：

$$
\boxed{
P_y
=
\frac{
\tan(\Phi/2)
}{
\tan(FOV_y/2)
}
}
$$

将：

$$
\sin\frac{\Phi}{2}
=
\frac{R}{d}
$$

代入后还可以进一步化简。

因为：

$$
\tan(\arcsin x)
=
\frac{x}{\sqrt{1-x^2}}
$$

所以：

$$
\tan\frac{\Phi}{2}
=
\frac{R}
{\sqrt{d^2-R^2}}
$$

因此：

$$
\boxed{
P_y
=
\frac{
R
}{
\sqrt{d^2-R^2}
\tan(FOV_y/2)
}
}
$$

又因为：

$$
d=R+h
$$

所以：

$$
\boxed{
P_y
=
\frac{
R
}{
\sqrt{(R+h)^2-R^2}
\tan(FOV_y/2)
}
}
$$

展开：

$$
(R+h)^2-R^2
=
2Rh+h^2
$$

因此：

$$
\boxed{
P_y
=
\frac{
R
}{
\sqrt{h(2R+h)}
\tan(FOV_y/2)
}
}
$$

这对于星球相机非常实用。

---

### 地平线与可见地表

#### 地平线距离、中心角与可见面积

观察者距地表高度：

$$
h
$$

从观察者到地平线切点：

$$
L=OT
$$

根据直角三角形：

$$
(R+h)^2
=
R^2+L^2
$$

因此：

$$
L^2
=
(R+h)^2-R^2
$$

展开：

$$
L^2
=
R^2+2Rh+h^2-R^2
$$

所以：

$$
\boxed{
L
=
\sqrt{2Rh+h^2}
}
$$

也可以写成：

$$
\boxed{
L
=
\sqrt{h(2R+h)}
}
$$

当：

$$
h\ll R
$$

可以忽略：

$$
h^2
$$

得到常见近似：

$$
\boxed{
L\approx\sqrt{2Rh}
}
$$

---


设从地心看观察者与地平线切点之间的角为：

$$
\alpha
$$

则：

$$
\cos\alpha
=
\frac{R}{R+h}
$$

因此：

$$
\boxed{
\alpha
=
\arccos
\left(
\frac{R}{R+h}
\right)
}
$$

这个角可以用于计算观察者能够看到多少地球表面。

---


观察者能够看到的是一个球冠。

球冠面积：

$$
A
=
2\pi R^2(1-\cos\alpha)
$$

由于：

$$
\cos\alpha
=
\frac{R}{R+h}
$$

所以：

$$
A
=
2\pi R^2
\left(
1-\frac{R}{R+h}
\right)
$$

整个球面积：

$$
A_E=4\pi R^2
$$

因此可见表面积比例：

$$
f
=
\frac{A}{4\pi R^2}
$$

得到：

$$
\boxed{
f
=
\frac12
\left(
1-\frac{R}{R+h}
\right)
}
$$

整理：

$$
\boxed{
f
=
\frac{h}{2(R+h)}
}
$$

当：

$$
h\rightarrow\infty
$$

则：

$$
f\rightarrow\frac12
$$

也就是说：

> 无论距离多远，同一时刻最多只能看到球体表面的一个半球。

---

### 统一归一化尺度

#### 统一尺度、归一化规则与尺度表

为了 Shader 和物理模拟方便，可以令：

$$
\boxed{
R_E=1
}
$$

所有距离除以：

$$
6371\text{ km}
$$

---


对于：

$$
H_{atm}=100\text{ km}
$$

有：

$$
H_{atm,n}
=
\frac{100}{6371}
$$

得到：

$$
\boxed{
H_{atm,n}\approx0.01570
}
$$

因此：

$$
R_{atm,n}
=
1+0.01570
$$

所以：

$$
\boxed{
R_{atm,n}\approx1.01570
}
$$

---


ISS 高度近似：

$$
h_{ISS}=400\text{ km}
$$

归一化高度：

$$
h_{ISS,n}
=
\frac{400}{6371}
$$

得到：

$$
\boxed{
h_{ISS,n}\approx0.0628
}
$$

距地心半径：

$$
R_{ISS,n}
=
1+0.0628
$$

所以：

$$
\boxed{
R_{ISS,n}\approx1.0628
}
$$

---


$$
h=1000\text{ km}
$$

则：

$$
h_n
=
\frac{1000}{6371}
$$

得到：

$$
\boxed{
h_n\approx0.1570
}
$$

距地心：

$$
\boxed{
d_n\approx1.1570
}
$$

此时地球角直径约：

$$
\boxed{
\Phi\approx120^\circ
}
$$

---


GPS 轨道高度约：

$$
h_{GPS}=20200\text{ km}
$$

归一化高度：

$$
h_{GPS,n}
=
\frac{20200}{6371}
$$

得到：

$$
\boxed{
h_{GPS,n}\approx3.17
}
$$

轨道半径：

$$
R_{GPS,n}
=
1+3.17
$$

得到：

$$
\boxed{
R_{GPS,n}\approx4.17
}
$$

---


GEO 高度：

$$
h_{GEO}=35786\text{ km}
$$

归一化：

$$
h_{GEO,n}
=
\frac{35786}{6371}
$$

得到：

$$
\boxed{
h_{GEO,n}\approx5.62
}
$$

距地心轨道半径：

$$
R_{GEO,n}
=
1+5.62
$$

因此：

$$
\boxed{
R_{GEO,n}\approx6.62
}
$$

需要区分：

$$
\boxed{
h_{GEO}\approx5.62R_E
}
$$

和：

$$
\boxed{
r_{GEO}\approx6.62R_E
}
$$

前者是距地表高度，后者是距地心距离。

---


月球平均地心距离约：

$$
d_M\approx384400\text{ km}
$$

归一化：

$$
d_{M,n}
=
\frac{384400}{6371}
$$

得到：

$$
\boxed{
d_{M,n}\approx60.3
}
$$

因此：

> 月球平均距离约为 60 个地球半径。

---


令：

$$
R_E=1
$$

则：

| 对象           |  距地表高度 |  距地心半径 |
| ------------ | -----: | -----: |
| 地球表面         |      0 |  1.000 |
| 100 km 光学大气层 | 0.0157 | 1.0157 |
| ISS          | 0.0628 | 1.0628 |
| 1000 km      | 0.1570 | 1.1570 |
| 2000 km      | 0.3139 | 1.3139 |
| GPS          |   3.17 |   4.17 |
| GEO          |   5.62 |   6.62 |
| 月球距离         | ≈ 59.3 | ≈ 60.3 |

---

### 尺度示意


```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \begin{scope}
    \clip (-12,-7.6) rectangle (12,7.6);
  \end{scope}
  \fill[fill=cyan!45] (-2.22,-1.07) circle (0.65);
  \draw[draw=cyan, thick] (-2.22,-1.07) circle (0.65);
  \draw[draw=cyan, thick, densely dashed] (-2.22,-1.07) circle (1.05);
  \draw[draw=cyan, thick, densely dashed] (-2.22,-1.07) circle (1.35);
  \draw[draw=cyan, thick, densely dashed] (-2.22,-1.07) circle (2.4);
  \draw[draw=cyan, thick, densely dashed] (-2.22,-1.07) circle (3.35);
  \draw[draw=cyan, thick, densely dashed] (-2.22,-1.07) circle (4.45);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-2.22,-1.07) {Earth};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (-1.71,-1.65) {大气 $1.016R$};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (-1.12,-0.93) {ISS $1.063R$};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (-0.57,-0.07) {GPS $4.17R$};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.05,1.18) {GEO $6.62R$};
  \node[anchor=west, inner sep=0pt, outer sep=0pt, text=cyan] at (0.56,2.34) {Moon $60.3R$};
  \pgfresetboundingbox
  \path[use as bounding box] (-12,-7.6) rectangle (12,7.6);
\end{tikzpicture}
```
可以明显看到：

$$
H_{atm}\ll R_E
$$

而：

$$
R_{GEO}\gg R_{atm}
$$

---

### 计算与 Shader 接口

#### 真实尺度、归一化尺度与单位契约

如果使用 km：

```cpp
float planetRadius = 6371.0f;

float atmosphereHeight = 100.0f;
float atmosphereRadius = 6471.0f;

float issHeight = 400.0f;
float issRadius = 6771.0f;

float gpsHeight = 20200.0f;
float gpsRadius = 26571.0f;

float geoHeight = 35786.0f;
float geoRadius = 42164.0f;
```

---


如果：

```cpp
float planetRadius = 1.0f;
```

则：

```cpp
float atmosphereHeight = 0.01570f;
float atmosphereRadius = 1.01570f;

float issHeight = 0.0628f;
float issRadius = 1.0628f;

float gpsHeight = 3.17f;
float gpsRadius = 4.17f;

float geoHeight = 5.62f;
float geoRadius = 6.62f;

float moonDistance = 60.3f;
```

---

#### 视盘、FOV、地平线与屏幕占比函数

C++：

```cpp
float planetAngularDiameter(float radius, float height)
{
    float distance = radius + height;

    return 2.0f * asinf(radius / distance);
}
```

输出单位：

$$
\text{rad}
$$

转换到角度：

```cpp
float radiansToDegrees(float value)
{
    return value * 180.0f / 3.14159265359f;
}
```

---


```cpp
float heightForFullPlanet(float radius, float fov)
{
    return radius / sinf(fov * 0.5f) - radius;
}
```

其中：

> radius : 星球半径  
> fov    : 弧度  
> return : 距地表高度  
对应：

$$
\boxed{
h
=
\frac{R}{\sin(FOV/2)}
-R
}
$$

---


```cpp
float horizonDistance(float radius, float height)
{
    return sqrtf(height * (2.0f * radius + height));
}
```

对应：

$$
\boxed{
L
=
\sqrt{h(2R+h)}
}
$$

---


```cpp
float planetScreenHeightRatio(
    float radius,
    float height,
    float fovY)
{
    float distance = radius + height;

    float angularRadius =
        asinf(radius / distance);

    return tanf(angularRadius)
        / tanf(fovY * 0.5f);
}
```

返回：

> 1.0  = 刚好占满整个屏幕高度  
> 0.5  = 星球直径占屏幕高度 50%  
> 0.25 = 星球直径占屏幕高度 25%  
---

#### 星球与大气层射线求交

星球 Shader 中还需要判断相机射线是否与星球或大气球相交。

射线：

$$
P(t)=O+tD
$$

其中：

* \(O\)：射线起点
* \(D\)：单位方向
* \(t\)：沿射线距离

球：

$$
|P-C|^2=R^2
$$

令：

$$
L=O-C
$$

代入：

$$
|L+tD|^2=R^2
$$

展开：

$$
(L+tD)\cdot(L+tD)=R^2
$$

得到：

$$
L\cdot L
+
2t(L\cdot D)
+
t^2(D\cdot D)
=
R^2
$$

如果：

$$
|D|=1
$$

则：

$$
D\cdot D=1
$$

于是：

$$
t^2
+
2(L\cdot D)t
+
(L\cdot L-R^2)
=
0
$$

定义：

$$
b=L\cdot D
$$

$$
c=L\cdot L-R^2
$$

得到：

$$
t^2+2bt+c=0
$$

判别式：

$$
\boxed{
\Delta=b^2-c
}
$$

如果：

$$
\Delta<0
$$

射线没有击中球。

如果：

$$
\Delta\ge0
$$

两个交点：

$$
\boxed{
t_0=-b-\sqrt{\Delta}
}
$$

$$
\boxed{
t_1=-b+\sqrt{\Delta}
}
$$

---


```hlsl
float2 raySphere(
    float3 rayOrigin,
    float3 rayDir,
    float3 sphereCenter,
    float sphereRadius)
{
    float3 L = rayOrigin - sphereCenter;

    float b = dot(L, rayDir);
    float c = dot(L, L)
            - sphereRadius * sphereRadius;

    float delta = b * b - c;

    if (delta < 0.0)
    {
        return float2(-1.0, -1.0);
    }

    float s = sqrt(delta);

    return float2(
        -b - s,
        -b + s
    );
}
```

---


对于大气球：

$$
R_{atm}=R_p+H_{atm}
$$

分别计算：

```hlsl
float2 atmosphereHit =
    raySphere(
        cameraPosition,
        rayDirection,
        planetCenter,
        atmosphereRadius
    );
```

再计算地表：

```hlsl
float2 planetHit =
    raySphere(
        cameraPosition,
        rayDirection,
        planetCenter,
        planetRadius
    );
```

这样可以得到：

```tikz
\usetikzlibrary{arrows.meta}
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \fill[fill={rgb,255:red,47;green,121;blue,76}] (0.5,-0.1) circle (1.35);
  \draw[draw=cyan, thick] (0.5,-0.1) circle (1.35);
  \draw[draw=cyan!85, thick] (-4.5,0.95) -- (-0.85,0.45);
  \draw[draw=cyan!85, thick] (-0.85,0.45) -- (1.85,-0.65);
  \draw[draw=cyan!85, thick] (1.85,-0.65) -- (4.5,-1.15);
  \draw[draw=cyan!85, thick, -{Latex}] (-4.5,0.95) -- (-3.3,0.78);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-3.3,1.15) {相机射线};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-0.85,0.75) {进入};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (1.85,-1) {离开};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (0.5,-0.1) {星球};
  \pgfresetboundingbox
  \path[use as bounding box] (-12,-7.6) rectangle (12,7.6);
\end{tikzpicture}
```
从而确定实际大气积分长度。

---

#### 核心尺度关系与最终检查

地球半径：

$$
\boxed{
R_E\approx6371\text{ km}
}
$$

大气外半径：

$$
\boxed{
R_{atm}
=
R_E+H_{atm}
}
$$

典型光学大气：

$$
\boxed{
H_{atm}\approx100\text{ km}
}
$$

因此：

$$
\boxed{
R_{atm}\approx6471\text{ km}
}
$$

---

观察距离：

$$
\boxed{
d=R+h
}
$$

---

星球角半径：

$$
\boxed{
\theta
=
\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

---

星球角直径：

$$
\boxed{
\Phi
=
2\arcsin
\left(
\frac{R}{R+h}
\right)
}
$$

---

根据 FOV 反求高度：

$$
\boxed{
h
=
\frac{R}
{\sin(FOV/2)}
-R
}
$$

---

地平线距离：

$$
\boxed{
L
=
\sqrt{h(2R+h)}
}
$$

---

地平线中心角：

$$
\boxed{
\alpha
=
\arccos
\left(
\frac{R}{R+h}
\right)
}
$$

---

可见球面比例：

$$
\boxed{
f
=
\frac{h}{2(R+h)}
}
$$

---

同步轨道半径：

$$
\boxed{
r_{sync}
=
\sqrt[3]
{
\frac{\mu T^2}{4\pi^2}
}
}
$$

---

地球 GEO：

$$
\boxed{
r_{GEO}\approx42164\text{ km}
}
$$

$$
\boxed{
h_{GEO}\approx35786\text{ km}
}
$$

---

归一化：

$$
R_E=1
$$

得到：

$$
\boxed{
R_{atm}\approx1.0157
}
$$

$$
\boxed{
R_{ISS}\approx1.0628
}
$$

$$
\boxed{
R_{GPS}\approx4.17
}
$$

$$
\boxed{
R_{GEO}\approx6.62
}
$$

$$
\boxed{
R_{Moon}\approx60.3
}
$$

---


```tikz
\begin{tikzpicture}[scale=1.18, line cap=round, line join=round]
  \color{white}
  \begin{scope}
    \clip (-12,-7.6) rectangle (12,7.6);
  \end{scope}
  \draw[draw=cyan!85, thick] (-5.35,-0.05) -- (5.35,-0.05);
  \draw[draw=cyan!85, thick] (-5.35,-0.21) -- (-5.35,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-5.16,-0.82) {地表 $R=1$};
  \draw[draw=cyan!85, thick] (-4.15,-0.21) -- (-4.15,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-3.37,0.68) {大气 $1.016R$};
  \draw[draw=cyan!85, thick] (-2.85,-0.21) -- (-2.85,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (-1.86,1.35) {ISS $1.063R$};
  \draw[draw=cyan!85, thick] (-1.25,-0.21) -- (-1.25,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (0.32,2.1) {完整入视锥 $1.157R$};
  \draw[draw=cyan!85, thick] (0.95,-0.21) -- (0.95,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (2.12,2.68) {GPS $4.17R$};
  \draw[draw=cyan!85, thick] (2.95,-0.21) -- (2.95,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (3.6,3.6) {GEO $6.62R$};
  \draw[draw=cyan!85, thick] (5.35,-0.21) -- (5.35,0.11);
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text=cyan] at (5.35,0.3) {月球 $60.3R$};
  \node[anchor=center, inner sep=0pt, outer sep=0pt, text={rgb,255:red,255;green,165;blue,0}] at (-0.1,-1.03) {轨道和视锥尺度（半径单位）};
  \pgfresetboundingbox
  \path[use as bounding box] (-12,-7.6) rectangle (12,7.6);
\end{tikzpicture}
```
因此，对于真实尺度星球 Shader：

$$
\boxed{
H_{atm}\ll R_E\ll R_{GEO}\ll R_{Moon}
}
$$

大气层相对于星球半径极薄，而同步轨道和月球距离已经进入完全不同的空间尺度。

---
