1、内容:
如何将空间点投影至一个给定平面
2、环境:
open3d
2、转载请注明出处:
https://blog.csdn.net/qq_41102371/article/details/121482108
空间点云投影到一个平面的问题,实际上就是一个点到平面的投影点问题
平面的一般方程为
A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0
其法向量为
n ⃗ = ( A , B , C ) \vec{n}=(A,B,C) n=(A,B,C)
现已知平面 α : ( A , B , C , D ) \alpha:(A,B,C,D) α:(A,B,C,D)以及平面外的一点 P 0 ( x 0 , y 0 , z 0 ) P_0\ (x_0,y_0,z_0) P0 (x0,y0,z0),求 P 0 P_0 P0到平面的投影点坐标
(图片来自同济高数第七版下册P29)
过 P 0 P_0 P0作垂线 N P 0 NP_0 NP0垂直于平面 α \alpha α, N ( x , y , z ) N(x,y,z) N(x,y,z)即为 P 0 P_0 P0在 α \alpha α上的投影点, P 1 P_1 P1是平面上的任意一点。
∵ N P 0 → ⊥ α \because \overrightarrow{NP_0} \perp \alpha ∵NP0⊥α
∴ N P 0 → ∥ n ⃗ \therefore \overrightarrow{NP_0} \parallel \vec{n} ∴NP0∥n
根据直线的点向式方程:
x 0 − x A = y 0 − y B = z 0 − z C = t \frac{x_0-x}{A}=\frac{y_0-y}{B}=\frac{z_0-z}{C}=t Ax0−x=By0−y=Cz0−z=t
则可以得到直线 N P 0 NP_0 NP0的参数方程:
{ x = x 0 − A t y = y 0 − B t z = z 0 − C t \begin{cases} x=x_0-At\\ y=y_0-Bt\\ z=z_0-Ct \end{cases} ⎩ ⎨ ⎧x=x0−Aty=y0−Btz=z0−Ct
因为点 N ( x , y , z ) N(x,y,z) N(x,y,z)在平面 α \alpha α上,因此:
A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0
A ( x 0 − A t ) + B ( y 0 − B t ) + C ( z 0 − C t ) + D = 0 A(x_0-At)+B(y_0-Bt)+C(z_0-Ct)+D=0 A(x0−At)+B(y0−Bt)+C(z0−Ct)+D=0
∴ \therefore ∴ t = A x 0 + B y 0 + C z 0 + D A 2 + B 2 + C 2 t=\frac{Ax_0+By_0+Cz_0+D}{A^2+B^2+C^2} t=A2+B2+C2Ax0+By0+Cz0+D
将t带入 N P 0 NP_0 NP0的参数方程:
x = x 0 − A A x 0 + B y 0 + C z 0 + D A 2 + B 2 + C 2 y = y 0 − B A x 0 + B y 0 + C z 0 + D A 2 + B 2 + C 2 z = z 0 − C A x 0 + B y 0 + C z 0 + D A 2 + B 2 + C 2 \begin{aligned} x & =& x_0-A\frac{Ax_0+By_0+Cz_0+D}{A^2+B^2+C^2}\\\\ y & =& y_0-B\frac{Ax_0+By_0+Cz_0+D}{A^2+B^2+C^2}\\\\ z & = & z_0-C\frac{Ax_0+By_0+Cz_0+D}{A^2+B^2+C^2} \end{aligned} xyz===x0−AA2+B2+C2Ax0+By0+Cz0+Dy0−BA2+B2+C2Ax0+By0+Cz0+Dz0−CA2+B2+C2Ax0+By0+Cz0+D
右侧完全已知,因此,只要知道任意空间点 P 0 P_0 P0的坐标以及给定平面 α \alpha α,就能计算出 P 0 P_0 P0在 α \alpha α上的投影点坐标 N ( x , y , z ) N(x,y,z) N(x,y,z)
def project_points2plane(src_npy, tgt_plane_coefficients):
"""
Args:
src_npy: numpy form of a point cloud
tgt_plane_coefficients: a given plane to project
Returns:
numpy form of points that projected to the given plane: n x 3
# @Author : Carlos_Lee
# @Blog :https://blog.csdn.net/qq_41102371/article/details/121482108
# References:
# https://www.cnblogs.com/nobodyzhou/p/6145030.html
# https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_plane
"""
project_plane = copy.deepcopy(src_npy)
a, b, c, d = tgt_plane_coefficients
x_i = project_plane[:, 0]
y_i = project_plane[:, 1]
z_i = project_plane[:, 2]
t = (a * x_i + b * y_i + c * z_i) / (a * a + b * b + c * c)
project_plane[:, 0] = x_i - a * t
project_plane[:, 1] = y_i - b * t
project_plane[:, 2] = z_i - c * t
'''
if we project a group of points to a plane,
some points will be projected to a same point on the plane, resulting in duplicate points,
we need to remove them
'''
# to remove the repeat points
project_plane = np.unique(project_plane, axis=0)
return project_plane
完整测试代码在GitHub:
https://github.com/Noel-Gallagher-Highflyingbirds/geometry
计算点在平面上的投影坐标: https://www.cnblogs.com/nobodyzhou/p/6145030.html
https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_plane
高等数学(第七版)(下册).高等教育出版社
https://zhuanlan.zhihu.com/p/267722955