平面方程

 

平面方程

飘飘白云 译( http://www.cnblogs.com/kesalin)
(转载请注明出处以及作&译者信息,非商业用途)
平面方程

平面上的一点以及垂直于该平面的法线唯一定义了 3D 空间的一个平面。

Graph of a plane in 3D

(图一) 3D 空间中的平面

 

在图一中,给定法线向量 normal vector ,以及平面上的一点 P1,对于平面上的任意一点 P ,我们可以在平面上定义一个由 P1 指向 P 的向量:

                        

因为法线 normal vector 垂直于平面,它必定也垂直于位于平面上的向量 ,因此它们的点积为 0 :

 

                        

以上就是平面方程的向量形式,下面我们来看代数形式的,通过点积计算,我们得到:

                        equation of a plane

 

如果我们用  来替代上面表达式中的常数部分,就得到平面方程的代数形式

                                                                         equation of a plane

原点到平面的距离

如果法线是归一化的,那么平面方程中的常数表达式 d 就是原点到平面的距离。

Plane with unit normal 
(图二)平面和归一化法线

如图二中,给定归一化法线向量 (a1, b1, c1),以及平面上的一点 P1 (Da1Db1Dc1),我们来推导原点到平面的距离 D。 将法线向量(a1, b1, c1) 和点 P1 代入平面方程,得到:

 

 

因此,我们可以用标准平面方程除以法线的模(法线长度)来计算原点到平面的距离。举个例子,原点到以 (1, 2, 2) 为法线的平面(x + 2y + 2z - 6 = 0)的距离为 2,计算过程如下:

                                                                         

任意点到平面的距离

Distance between Plane and Point 
(图三) 任意点到平面的距离

如图三中,我们来推导空间中任意一点 P2 到平面的距离 D 的计算公式。P2 到平面的距离等于由 P1 指向 P2 的向量  在法线向量  上的投影。我们用点积来计算投影距离 D :

 

 

展开分子  :

            

 

代入前面的距离公式,得到最终的点到平面的距离公式

            

distance between plane and point

 

观察上面的式子,我们就可以发现距离 D 是将点 P2 代入平面方程中,再除以法线的模得到的。举个例子,点(-1, -2, -3)到平面 x + 2y + 2z - 6 = 0 的距离为:

                                                                  

 

注意:距离是有符号的!它可以为负值,我们可以通过这个符号来决定点位于平面的哪一边(D > 0,点在平面的正面-法线指向那一边;D < 0,带在平面的反面-法线相反方向的那一边,当然 D = 0 就是在平面上啦!)。

 

 

 

RANSAC(Random Sample Consensus,随机采样一致性)算法是一种基于随机采样的迭代算法,主要用于从一组包含大量噪声和异常值(外点)的数据中估计数学模型的参数,在确定平面方程系数时可按以下步骤进行: ### 基本原理 RANSAC算法的基本假设是将数据点分为内点(Inliers)和外点(Outliers)。内点是能够被假设的数学模型正确描述的数据点,即它们与模型预测的结果较为接近;外点是偏离正常范围很远、无法被模型描述的数据点,通常是由于噪声、测量错误或错误的数据关联等原因产生的 [^2]。 ### 确定平面方程系数步骤 1. **随机采样**:从数据集中随机选择三个不共线的点。由于三个不共线的点可以唯一确定一个平面,设这三个点为\(P_1(x_1,y_1,z_1)\),\(P_2(x_2,y_2,z_2)\),\(P_3(x_3,y_3,z_3)\)。 2. **计算平面方程系数**: - 平面方程的一般式为\(ax + by + cz + d = 0\)。 - 首先计算平面的法向量\(\vec{n}=(a,b,c)\),可以通过向量叉乘得到。设\(\vec{v_1}=\overrightarrow{P_1P_2}=(x_2 - x_1,y_2 - y_1,z_2 - z_1)\),\(\vec{v_2}=\overrightarrow{P_1P_3}=(x_3 - x_1,y_3 - y_1,z_3 - z_1)\),则法向量\(\vec{n}=\vec{v_1}\times\vec{v_2}\)。 - 根据向量叉乘公式\(\vec{n}=\begin{vmatrix} \vec{i}&\vec{j}&\vec{k}\\ x_2 - x_1&y_2 - y_1&z_2 - z_1\\ x_3 - x_1&y_3 - y_1&z_3 - z_1 \end{vmatrix}=\vec{i}((y_2 - y_1)(z_3 - z_1)-(y_3 - y_1)(z_2 - z_1))-\vec{j}((x_2 - x_1)(z_3 - z_1)-(x_3 - x_1)(z_2 - z_1))+\vec{k}((x_2 - x_1)(y_3 - y_1)-(x_3 - x_1)(y_2 - y_1))\),得到\(a=(y_2 - y_1)(z_3 - z_1)-(y_3 - y_1)(z_2 - z_1)\),\(b=-((x_2 - x_1)(z_3 - z_1)-(x_3 - x_1)(z_2 - z_1))\),\(c=(x_2 - x_1)(y_3 - y_1)-(x_3 - x_1)(y_2 - y_1)\)。 - 再将点\(P_1(x_1,y_1,z_1)\)代入平面方程\(ax + by + cz + d = 0\),可得\(d=-(ax_1 + by_1 + cz_1)\)。 3. **计算内点**:对于数据集中的每个点\(P(x,y,z)\),计算它到当前平面的距离。判断该点是否为内点通常有两种方式: - 方式一:计算\(fabs((x - x_1)*a+(y - y_1)*b+(z - z_1)*c)\) ,表示当前点的向量减去平面上的一个点的向量,然后把相减得到的向量乘以平面法向量\((a,b,c)\),若该值小于某个预设的阈值,则认为该点是内点 [^1]。 - 方式二:计算\(fabs(x*a + y*b + z*c + d)\) ,若该值小于某个预设的阈值,则认为该点是内点,这两种方法是等价的 [^1]。 4. **迭代优化**:重复步骤1 - 3多次,每次记录内点的数量。选择内点数量最多的那次采样所确定的平面方程系数作为最终结果。 ### 代码示例(Python) ```python import numpy as np def ransac_plane(data, num_iterations=1000, distance_threshold=0.01): best_inliers = [] best_coeffs = None for _ in range(num_iterations): # 随机选择三个不共线的点 indices = np.random.choice(len(data), 3, replace=False) p1, p2, p3 = data[indices] # 计算平面方程系数 v1 = p2 - p1 v2 = p3 - p1 normal = np.cross(v1, v2) a, b, c = normal d = -(a * p1[0] + b * p1[1] + c * p1[2]) # 计算内点 distances = np.abs(a * data[:, 0] + b * data[:, 1] + c * data[:, 2] + d) inliers = data[distances < distance_threshold] # 更新最佳结果 if len(inliers) > len(best_inliers): best_inliers = inliers best_coeffs = (a, b, c, d) return best_coeffs ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值