news 2026/9/12 18:03:30

OI Wiki 三维计算几何指南:空间向量、平面方程、夹角距离与立体几何定理实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OI Wiki 三维计算几何指南:空间向量、平面方程、夹角距离与立体几何定理实战

OI Wiki 三维计算几何指南:空间向量、平面方程、夹角距离与立体几何定理实战

【免费下载链接】OI-wiki:star2: Wiki of OI / ICPC for everyone. (某大型游戏线上攻略,内含炫酷算术魔法)项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wiki

三维计算几何是信息学竞赛(OI / ICPC)中从平面走向立体的关键一步:空间中的点、向量、直线与平面,全部可以沿用二维问题的“坐标 + 向量运算”方法论来解决。本文以 OI Wiki 的docs/geometry/3d.md为主体,完整梳理三维空间的基本概念(平面点法式与一般式)、直线与平面之间的夹角判定、点到平面的距离、直线与平面的交点,以及三正弦定理、三余弦定理两大立体几何工具,并结合仓库内的 三维凸包模板代码 与 三维凸包算法讲解 给出源码级印证。读完本文,你将掌握用空间向量求解三维几何问题的完整公式体系,并能在代码中正确实现法向量、叉积与可见性判定等核心操作。

前置基础:从二维几何到三维空间

三维几何的很多概念与二维几何是相通的,我们可以用与解决二维几何问题相同的方法来解决三维几何问题:仍然把图形放入坐标系,用坐标表示点与向量,用向量运算刻画位置关系。

二维与三维的区别在于:

  • 二维平面使用直角坐标系下的有序数对 $(x,y)$ 表示点,三维空间则使用空间直角坐标系下的三元组 $(x,y,z)$;
  • 二维向量的线性运算(加减、数乘)在三维中逐分量成立,模长公式扩展为 $|\boldsymbol v|=\sqrt{x^2+y^2+z^2}$;
  • 二维中的“叉积”给出一个标量(有向面积),三维中的叉积则给出一个同时垂直于两个输入向量的新向量,这正是法向量的来源。

仓库的《向量》一文在“在三维空间中的拓展(立体几何/空间向量)”一节中明确指出:平面部分所述的所有内容在空间中均成立,并且补充了三条三维特有的结论:

  • 空间向量基本定理:如果三个向量 $\boldsymbol{e_1},\boldsymbol{e_2},\boldsymbol{e_3}$ 不共面,那么空间中任意向量 $\boldsymbol p$ 都可以唯一表示为 $\mathbf p=x\boldsymbol{e_1}+y\boldsymbol{e_2}+z\boldsymbol{e_3}$,据此可以用三个相互垂直的基底建立空间直角坐标系;
  • 共面向量基本定理:存在两个不共线的向量 $\boldsymbol{x},\boldsymbol{y}$ 时,向量 $\boldsymbol p$ 与它们共面的充要条件是存在唯一实数对 $(a,b)$ 使得 $\boldsymbol{p}=a\boldsymbol{x}+b\boldsymbol{y}$;
  • 方向向量与法向量:空间直线的位置由它经过的一点及其一个方向向量完全确定;已知垂直于某直线的平面一般方程 $ax+by+cz+d=0$ 时,$(a,b,c)$ 既是该平面的一个法向量,也是这条直线的一个方向向量。

这些结论是后续所有公式推导的基石,建议先阅读向量基础再进入本文。

基本概念:点、向量、直线与平面

点、向量、直线这些概念和二维几何是相似的,这里不再展开。三维空间中真正的新对象是平面

平面:点法式表示

我们可以用平面上的一点 $P_0(x_0,y_0,z_0)$ 和该平面的法向量(即垂直于该平面的向量)$\boldsymbol{n}$ 来表示一个平面。

因为 $\boldsymbol{n}$ 垂直于平面,所以 $\boldsymbol{n}$ 垂直于该平面内的所有直线。换句话说,设 $\boldsymbol{n}=(A,B,C)$,则该平面上的点 $P(x,y,z)$ 都满足:

$$ \boldsymbol{n} \cdot \overrightarrow{PP_0} = 0 $$

根据向量点积的定义,上式等价于:

$$ A(x-x_0)+B(y-y_0)+C(z-z_0)=0 $$

整理后得到:

$$ Ax+By+Cz-(Ax_0+By_0+Cz_0)=0 $$

令 $D=-(Ax_0+By_0+Cz_0)$,则上式变成:

$$ Ax+By+Cz+D=0 $$

我们称这个式子为平面的一般式。

记忆要点:平面一般式 $Ax+By+Cz+D=0$ 的系数 $(A,B,C)$ 恰好就是该平面的一个法向量。这一性质在竞赛中极为常用——给定三个不共线点,先求两条边向量的叉积得到法向量,再代入一个点解出 $D$,即可一步写出平面方程。

从源码结构看,三维凸包代码正是把“法向量由叉积给出”落实到了struct Node中:operator*重载了三维叉积,operator&重载了点积,struct Face::Normal()通过两条边向量做叉积返回面的法向量:

Node operator*(Node A) const { return {y * A.z - z * A.y, z * A.x - x * A.z, x * A.y - y * A.x}; } double operator&(Node A) const { return x * A.x + y * A.y + z * A.z; } Node Normal() { return (A[v[1]] - A[v[0]]) * (A[v[2]] - A[v[0]]); }

基本操作:直线、平面之间的夹角

运用空间向量的知识,空间中直线、平面之间的夹角可以很快求出。下面按“先定义、再公式”的顺序逐一展开。

三个基本角度定义

异面直线所成的角:对于两条异面直线 $a$、$b$,过空间中一点 $P$ 作 $a' \parallel a$,$b' \parallel b$,则 $a'$ 与 $b'$ 所成的锐角或直角被称为 $a$ 和 $b$ 两条异面直线所成的角。

直线与平面所成的角:对于直线 $a$ 和平面 $\alpha$,若 $a$ 与 $\alpha$ 相交于 $A$,过 $a$ 上一点 $P$ 引平面 $\alpha$ 的垂线交 $\alpha$ 于 $O$,则 $a$ 与 $PO$ 所成角的余角被称为直线与平面所成的角。特别地,若 $a \parallel \alpha$ 或 $a \subset \alpha$,则它们之间的夹角为 $0^\circ$。

二面角:对于两个平面 $\alpha$、$\beta$,它们的夹角被定义为与两条平面的交线 $l$ 垂直的两条直线 $a,b$(其中 $a \subset \alpha$,$b \subset \beta$)所成的角。

这三个定义把立体几何中的角度问题统一归结为向量夹角问题,从而可以用坐标计算。

两直线夹角定义与关系充要条件

关键命题:两直线的方向向量的夹角,叫做两直线的夹角。

有了这个命题,就可以得出以下结论:已知两条直线 $l_1, l_2$,它们的方向向量分别是 $s_1 (m_1, n_1, p_1)$,$s_2 (m_2, n_2, p_2)$,设 $\varphi$ 为两直线夹角,则:

$$ \cos \varphi = \dfrac{\left | m_1m_2+n_1n_2+p_1p_2 \right |}{\sqrt{m_1^2+n_1^2+p_1^2}\sqrt{m_2^2+n_2^2+p_2^2}} $$

分子取绝对值是因为异面直线所成的角取锐角或直角($\varphi \in [0, \frac{\pi}{2}]$),而两个方向向量本身的夹角可能在 $(\frac{\pi}{2}, \pi]$ 区间,取绝对值后才能映射回锐角。

由上式可以直接得到两条充要条件:

  • $l_1 \perp l_2 \iff m_1m_2 + n_1n_2 + p_1p_2 = 0$(点积为零)
  • $l_1 \parallel l_2 \iff \dfrac{m_1}{m_2} = \dfrac{n_1}{n_2} = \dfrac{p_1}{p_2}$(对应坐标成比例)

三维向量与平面的夹角

当直线与平面不垂直时,直线和它在平面上的投影直线的夹角 $\varphi$($\varphi \in [0, \frac{\pi}{2}]$)称为直线与平面的夹角。

设直线向量 $s(m, n, p)$,平面法线向量 $f(a, b, c)$,那么以下命题成立:

  • 角度的正弦值

$$ \sin\varphi = \dfrac{\left | am + bn + cp \right |}{\sqrt{a^2+b^2+c^2}\sqrt{m^2+n^2+p^2}} $$

注意这里是正弦而非余弦——因为直线与平面所成的角定义为“直线与其投影的夹角”,它与“直线方向向量与法向量夹角”互为余角,所以对直线方向向量与法向量夹角的余弦取余角即得正弦。

  • 直线与平面平行 $\iff am+bn+cp = 0$(方向向量与法向量垂直,即点积为零)
  • 直线与平面垂直 $\iff \dfrac{a}{m} = \dfrac{b}{n} = \dfrac{c}{p}$(方向向量与法向量平行,即对应坐标成比例)

点到平面的距离

设平面 $\Pi: Ax+By+Cz+D=0$(法向量 $\boldsymbol n=(A,B,C)$),平面外一点 $P_1(x_1,y_1,z_1)$。在平面上任取一点 $P_0(x_0,y_0,z_0)$,则点到平面的距离等于向量 $\overrightarrow{P_0P_1}$ 在法向量方向上的投影长度:

$$ d = \left| \overrightarrow{P_0P_1} \cdot \frac{\boldsymbol n}{|\boldsymbol n|} \right| = \frac{|A(x_1-x_0)+B(y_1-y_0)+C(z_1-z_0)|}{\sqrt{A^2+B^2+C^2}} $$

由于 $P_0$ 在平面上,满足 $Ax_0+By_0+Cz_0=-D$,代入得:

$$ d = \frac{|Ax_1+By_1+Cz_1+D|}{\sqrt{A^2+B^2+C^2}} $$

即:把点的坐标代入平面方程左边再取绝对值,除以法向量模长。该公式与二维中“点到直线距离 $d=\frac{|Ax_0+By_0+Cz_0|}{\sqrt{A^2+B^2+C^2}}$”的形式完全一致,是平面一般式最直接的应用。

直线与平面的交点

直接联立直线方程和平面方程即可。设直线过点 $P_0(x_0,y_0,z_0)$,方向向量为 $\boldsymbol s=(m,n,p)$,则直线上的点可以写成参数形式:

$$ \begin{cases} x = x_0 + tm\ y = y_0 + tn\ z = z_0 + tp \end{cases} $$

代入平面一般式 $Ax+By+Cz+D=0$:

$$ A(x_0+tm)+B(y_0+tn)+C(z_0+tp)+D=0 $$

解得:

$$ t = -\frac{Ax_0+By_0+Cz_0+D}{Am+Bn+Cp} $$

  • 当 $Am+Bn+Cp \neq 0$ 时,存在唯一交点,把 $t$ 代回参数方程即可得到交点坐标;
  • 当 $Am+Bn+Cp = 0$ 时,直线方向向量与平面法向量垂直,即直线与平面平行,此时无交点(或直线在平面内,需进一步验证)。

立体几何定理:三正弦定理与三余弦定理

除向量计算外,立体几何中还有两个在竞赛中高频出现的经典定理,它们把“二面角、线面角、线线角”之间的关系用简洁的正弦、余弦乘积式表达出来,可用于绕过繁琐的坐标运算快速解题。

三正弦定理

设二面角 $M-AB-N$ 的度数为 $\alpha$,在平面 $M$ 上有一条射线 $AC$,它和棱 $AB$ 所成角为 $\beta$,和平面 $N$ 所成的角为 $\gamma$,则:

$$ \sin\gamma = \sin\alpha\cdot\sin\beta $$

应用场景:当题目给出“二面角 + 平面内射线与棱的夹角”时,可一步求出该射线与另一平面所成的角,常用于空间几何计算与最值问题中。记忆方式:小角的正弦 = 二面角正弦 × 平面内夹角正弦。

三余弦定理

设 $O$ 为平面上一点,过平面外一点 $B$ 的直线 $BO$ 在面上的射影为 $AO$,$OC$ 为面上的一条直线,那么 $\angle COB$、$\angle AOC$、$\angle AOB$ 三角的余弦关系为:

$$ \cos\angle BOC=\cos\angle AOB\cdot\cos\angle AOC $$

($\angle AOC$、$\angle AOB$ 只能是锐角)

应用场景:三余弦定理又被称为“最小角定理”的定量版本,它揭示了一条斜线与平面内任意直线夹角的余弦,等于该斜线与其射影夹角的余弦乘以射影与该直线夹角的余弦。常用于求解“斜线—射影—平面内直线”构成的直角三角形链问题,在求二面角、判断两条异面直线夹角时都能显著减少运算量。记忆方式:大角的余弦 = 两个小角余弦之积。

源码实战:三维凸包中的空间向量运算

三维几何的知识在竞赛中最典型的应用之一是三维凸包。仓库在《凸包》文档末尾的“三维凸包”一节给出了完整算法与模板代码,其核心思路与本文的向量公式一一对应。

算法过程

三维凸包采用增量式(Incremental)构造,过程如下:

  1. 微小扰动:首先对输入点作微小扰动,避免出现四点共面的情况(四点共面会导致法向量为零向量,后续可见性判断失效);
  2. 新增一点:对于一个已知凸包,新增一个点 $P$,将 $P$ 视作一个点光源,向凸包做射线。光线的可见面不可见面一定是由若干条棱隔开的;
  3. 更新面集:将光的可见面删去,并新增由其分割棱与 $P$ 构成的平面,重复此过程直到处理完所有点。

由Pick 定理、欧拉公式(在凸多面体中,顶点数 $V$、边数 $E$ 及面数 $F$ 满足 $V-E+F=2$)和圆的反演可知,该算法的时间复杂度为 $O(n^2)$。

代码中的向量原语

docs/geometry/code/3d/3d_1.cpp中处处体现了本文的空间向量知识:

  • struct Node存储三维点/向量 $(x,y,z)$,len()计算模长 $\sqrt{x^2+y^2+z^2}$,operator*是三维叉积(结果向量垂直于两输入向量),operator&是点积;
  • struct Face用三个顶点下标表示一个三角面片,Normal()返回法向量,area()通过 $|\text{叉积}|/2$ 计算三角形面积:
double area() { return Normal().len() / 2.0; }

这正是利用了“向量叉积的模等于两向量张成平行四边形面积”这一几何意义,与本文“法向量垂直于平面”的表示完全一致;

  • see(Face a, Node b)判断点 $b$ 是否在面 $a$ 的可见侧:把向量 $(b - A[a.v[0]])$ 与面法向量做点积,点积大于 $0$ 说明 $b$ 位于法向量一侧(可见),这正是本文“直线与平面夹角”一节中 $\sin\varphi$ 分子 $|am+bn+cp|$ 的符号判定应用:
int see(Face a, Node b) { return ((b - A[a.v[0]]) & a.Normal()) > 0; }
  • shake()对每个点添加 $[-\frac{\epsilon}{2}, \frac{\epsilon}{2}]$ 量级的随机扰动($\epsilon = 10^{-9}$),对应算法第一步的“微小扰动”,避免四点共面;

  • 主流程:读入 $n$ 个点并扰动后调用Convex_3D(),维护当前凸包的所有面(用vis[x][y]标记棱的可视性),最后累加所有面的面积,保留 3 位小数输出。

由于三维凸包的可见性判定、法向量计算完全建立在本文的空间向量公式之上,吃透本文的平面表示与夹角理论,是理解该模板代码(以及用它求解洛谷 P4724【模板】三维凸包等题目)的直接前提。

总结

三维计算几何的核心方法论,是把立体几何问题“坐标化、向量化”:

几何对象表示方法关键公式
平面一点 + 法向量 / 一般式$Ax+By+Cz+D=0$,$(A,B,C)$ 为法向量
两直线夹角方向向量$\cos\varphi=\dfrac{m_1m_2+n_1n_2+p_1p_2}{\sqrt{m_1^2+n_1^2+p_1^2}\sqrt{m_2^2+n_2^2+p_2^2}}$
直线与平面夹角方向向量 + 法向量$\sin\varphi=\dfrac{am+bn+cp}{\sqrt{a^2+b^2+c^2}\sqrt{m^2+n^2+p^2}}$
点到平面距离一般式代入$d=\dfrac{Ax_0+By_0+Cz_0+D}{\sqrt{A^2+B^2+C^2}}$
直线与平面交点参数方程联立$t=-\dfrac{Ax_0+By_0+Cz_0+D}{Am+Bn+Cp}$
三正弦定理 / 三余弦定理角间关系$\sin\gamma=\sin\alpha\sin\beta$;$\cos\angle BOC=\cos\angle AOB\cos\angle AOC$

在实现层面,可以沿用二维计算几何一文“代码编写注意事项”中的经验:三维几何同样涉及大量double浮点运算,需要注意精度问题(如使用 $\epsilon=10^{-9}$ 级别的容差)与常数因子对时间的影响。同时注意叉积、点积在三维下的新语义——叉积返回法向量,点积用于判断方向关系——这是从二维迈向三维时最需要建立的习惯。

延伸阅读

  • 二维几何基础:三维几何的前置章节,快速排斥实验、跨立实验、多边形面积等思想可推广到空间;
  • 向量(含三维拓展):空间向量基本定理、方向向量、法向量的严格定义与坐标求法;
  • 凸包(含三维凸包):三维凸包的增量构造算法与 $O(n^2)$ 复杂度分析;
  • 三维凸包模板代码:可直接复用的法向量、叉积、可见性判定与面面积累加实现;
  • 极坐标与坐标变换:三维空间中的球坐标系可用于空间旋转类问题。

【免费下载链接】OI-wiki:star2: Wiki of OI / ICPC for everyone. (某大型游戏线上攻略,内含炫酷算术魔法)项目地址: https://gitcode.com/GitHub_Trending/oi/OI-wiki

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 18:03:13

CLI-Anything:基于LLM的智能终端语义路由系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 18:02:54

8大AI论文写作神器:从文献管理到语法检查全攻略

1. 项目概述:AI论文写作工具的必要性本科毕业论文是每个大学生必须跨越的一道门槛。从选题开题到文献综述,从实验设计到数据分析,再到最后的论文撰写与格式调整,整个过程往往需要耗费数月时间。对于缺乏科研经验的大四学生而言&am…

作者头像 李华
网站建设 2026/9/12 18:02:35

一句话让浏览器自己动手——Midscene 浏览器自动化零代码上手

一句话让浏览器自己动手——Midscene 浏览器自动化零代码上手 【免费下载链接】midscene GUI Agent for E2E Testing 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene 浏览器自动化过去是写脚本的工程师的活,普通人只能重复点点点。现在你只要打…

作者头像 李华
网站建设 2026/9/12 18:01:25

企业营销部门如何做好GEO,让AI带来客户?

昨天晚上,有一个企业老板给我留言:“勾老师,我最近老听说 GEO。我是外行,您能不能给我讲一讲,怎么做GEO呢?”这篇文章我就来谈谈,自己理解的GEO。如果你是GEO高手,也欢迎指正。一、概…

作者头像 李华
网站建设 2026/9/12 17:59:56

大模型分类误区:MoE、多模态与推理优化不是同类概念

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华