contents
写在前面
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)
python代码
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
References
计算点在平面上的投影坐标: 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