校赛G题题解
需要提前知道的知识
点积
其中 $\theta$ 是两个向量之间的夹角。
叉积
其中 $\theta$ 是两个向量之间的夹角,$\vec{n}$ 是 $\vec{a}$ 和 $\vec{b}$ 所在平面的法向量。
那么可以用行列式表达为:
这个行列式可以展开为:
直线的方程
其中 $\vec{r_0}$ 是直线上的一个点,$\vec{v}$ 是直线的方向向量,$t$ 是参数。
如果 $\vec{v}$ 的坐标知道,那么我们可以写成参数方程的形式:
而其写成 $t$ 的表达式为:
平面方程
其中 $\vec{n}$ 是平面的法向量,$\vec{r_0}$ 是平面上的一个点。
写成方程的形式为:
其中 $D = -\vec{n} \cdot \vec{r_0}$ ,即把 $\vec{r_0}$ 代入平面方程中即可,或者把平面中的一点坐标带入。
点到平面的距离
其中 $n_x,n_y,n_z$ 是平面的法向量,$x_0,y_0,z_0$ 是平面上的一个点,$D$ 是平面方程中的常数项。
题目
描述
已知三角形平面 $ABC$ 的三个顶点坐标和另外一点 $P$ 的坐标,求 $P$ 到三角形平面$ABC$ 的距离。
这里三角形平面 $ABC$ 是一个薄片
题目分析
要求 $P$ 到三角形平面 $ABC$ 的距离,我们可以先想想什么是点 $P$ 到平面 $ABC$ 的距离?
- 如果 $P$ 到三角形平面的投影点 $D$ 在 $ABC$ 内,那么 $PD$ 就是 $P$ 到三角形平面的距离(如图一)。
- 如果 $P$ 到三角形平面的投影点 $D$ 在 $ABC$ 外,那么点 $P$ 到 $AB$ 或 $BC$ 或 $CA$ 的距离的最小值就是 $P$ 到三角形平面的距离。但注意到 $AB$ 这些为线段,过 $P$ 的垂线与线段相交的点不一定在 $AB$ 上,所以又有以下两种情况:
- $P$ 到 $AB$ 的垂线与 $AB$ 相交于点 $E$,那么 $PE$ 就是 $P$ 到三角形平面的距离(如图二)。
- $P$ 到 $AB$ 的垂线与 $AB$ 相交于点 $E$,但 $E$ 不在 $AB$ 上,那么 $P$ 到这条线段的距离就是 $P$ 到 $A$ 或 $B$ 的距离的最小值。
- $P$ 到 $AB$ 的垂线与 $AB$ 相交于点 $E$,那么 $PE$ 就是 $P$ 到三角形平面的距离(如图二)。
求解过程
好了,现在我们知道大概的过程,接下来就是数学推导了。
1. 求 $P$ 到三角形平面 $ABC$ 的垂足
设 $P$ 到三角形平面 $ABC$ 的垂足为 $D$,那么 $PD$ 就是 $P$ 到三角形平面的距离。
根据平面方程,我们可以得到,三角形平面 $ABC$ 的方程为:
其中
作直线 $PD$ ,其中 $D$ 为 $P$ 到三角形平面 $ABC$ 的垂足,其方程为:
带入平面方程解得,那么直线 $PD$ 的参数方程为:
那么 $P$ 到三角形平面 $ABC$ 的垂足 $D$ 的坐标为:
我们这里把 $D=-(n_xx_A+n_yy_A+n_zz_A)$ 带入上式有:
2. 判断 $D$ 是否在 $ABC$ 内
判断 $D$ 是否在 $ABC$ 内,我们可以用向量叉积来判断。
我们知道,如果 $D$ 在 $ABC$ 内,那么三角形 $ABC$ 的面积等于三角形 $ABD$ ,$ACD$ ,$BCD$ 的面积之和。又$S_{ABC}=|AB|\cdot|AC|\cdot \sin(\theta)=|\vec{AB} \times \vec{AC}|$,那么如果$|\vec{DA} \times \vec{DB}|+|\vec{DB} \times \vec{DC}|+|\vec{DC} \times \vec{DA}|=|\vec{AB} \times \vec{AC}|$,那么$D$就在$ABC$内。
3. 求距离
1. $D$ 在 $ABC$ 内
如果 $D$ 在 $ABC$ 内,那么 $PD$ 就是 $P$ 到三角形平面的距离,即:
这里由 $D=-(n_xx_A+n_yy_A+n_zz_A)$ 带入有:
2. $D$ 在 $ABC$ 外
我们先求 $P$ 到 $AB$ 的距离,再求 $P$ 到 $BC$ 的距离,再求 $P$ 到 $CA$ 的距离,取最小值即可。
$P$ 到 $AB$ 的距离
我们先求 $P$ 到 $AB$ 的垂足 $E$ 的坐标。
设过 $P$ 点且垂直于 $AB$ 的平面为 $\pi$ ,那么 $\pi$ 的方程为:
那么我们联立直线 $AB$ 的方程:$\frac{x-x_A}{x_B-x_A} = \frac{y-y_A}{y_B-y_A} = \frac{z-z_A}{z_B-z_A}=t$ 和平面 $\pi$ 的方程,解得 $t$ 为:
其中我们限制 $t \in [0,1] $ ,如果其在外面,将其限制在靠近 $[0,1]$ 的边界。
这样我们就得到了 $P$ 到 $AB$ 的垂足 $E$ 的坐标为:
那么 $P$ 到 $AB$ 的距离为:
剩下的同理,这里不过多说明,值得注意的是,我们可以构造这样的函数来方便求三次距离。
代码实现
方法一
1 |
|
这里说明提示一下: 1. 由于 $\frac{n_x(x_p-x_A)+n_y(y_p-y_A)+n_z(z_p-z_A)}{n_x^2 + n_y^2 + n_z^2}$ 在此后的运算中至少要用到3次,那么不妨用这个作为 $D$ 的值。 2. 在计算点到线段的距离时,由于我们要限制 $t \in [0,1]$ ,那么我们可以用
C++
中的max
和min
函数来限制 $t$ 的范围,先用min
限制$t \leq 1$,然后再用max
限制 $t \geq 0$ 。
方法二
1 |
|
方法二和方法一没有本质的区别,只是把坐标系平移了一下,这样在计算投影点时,可以少计算一些量。