已知三点
P
1
(
x
1
,
y
1
,
z
1
)
P1(x_1,y_1,z_1)
P1(x1,y1,z1)、
P
2
(
x
2
,
y
2
,
z
2
)
P2(x_2,y_2,z_2)
P2(x2,y2,z2)、
P
3
(
x
2
,
y
2
,
z
2
)
P3(x_2,y_2,z_2)
P3(x2,y2,z2),要求该三点所确定的平面方程及法向量。我们知道两点共线,三点一定共面,平面的法向量一定垂直于平面中任意两点之间的连线。所以求解的思路就是找到一个向量
n
n
n与平面的两条不平行的直线垂直即可,即计算
n
n
n与平面中两个向量的叉乘。
做平面中的两个向量
V
1
=
P
1
P
2
=
(
x
2
−
x
1
,
y
2
−
y
1
,
z
2
−
z
1
)
V_1=P_1P_2=(x_2-x_1,y_2-y_1,z_2-z_1)
V1=P1P2=(x2−x1,y2−y1,z2−z1)和
V
2
=
P
1
P
3
=
(
x
3
−
x
1
,
y
3
−
y
1
,
z
3
−
z
1
)
V_2=P_1P_3=(x_3-x_1,y_3-y_1,z_3-z_1)
V2=P1P3=(x3−x1,y3−y1,z3−z1),平面法向量和这两个向量都垂直,因此法向量
n
n
n:
n
=
V
1
×
V
2
=
∣
i
j
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
∣
=
a
i
+
b
j
+
c
k
=
(
a
,
b
,
c
)
n=V_1 \times V_2 = \left| ijkx2−x1y2−y1z2−z1x3−x1y3−y1z3−z1
其中:
a
=
(
y
2
−
y
1
)
∗
(
z
3
−
z
1
)
−
(
y
3
−
y
1
)
∗
(
z
2
−
z
1
)
b
=
(
z
2
−
z
1
)
∗
(
x
3
−
x
1
)
−
(
z
3
−
z
1
)
∗
(
x
2
−
x
1
)
c
=
(
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=(z_2-z_1)*(x_3-x_1)-(z_3-z_1)*(x_2-x_1)\\ c=(x_2-x_1)*(y_3-y_1)-(x_3-x_1)*(y_2-y_1)
a=(y2−y1)∗(z3−z1)−(y3−y1)∗(z2−z1)b=(z2−z1)∗(x3−x1)−(z3−z1)∗(x2−x1)c=(x2−x1)∗(y3−y1)−(x3−x1)∗(y2−y1)
平面方程为:
a
(
x
−
x
1
)
+
b
(
y
−
y
1
)
+
c
(
z
−
z
1
)
=
0
a(x-x_1)+b(y-y_1)+c(z-z_1)=0
a(x−x1)+b(y−y1)+c(z−z1)=0,所以
d
=
−
a
∗
x
1
−
b
∗
y
1
−
c
∗
z
1
d=-a*x_1-b*y_1-c*z_1
d=−a∗x1−b∗y1−c∗z1,平面方程为:
a
x
+
b
y
+
c
z
+
d
=
0
ax+by+cz+d=0
ax+by+cz+d=0
void getNormalBy3Points(
const Eigen::Vector3d &P1,
const Eigen::Vector3d &P2,
const Eigen::Vector3d &P3,
Eigen::Vector3d &normal)
{
Eigen::Vector3d V1=P1-P2;
Eigen::Vector3d V2=P1-P3;
normal=V1.cross(V2);
}
void getPlaneBy3Points(
const Eigen::Vector3d &P1,
const Eigen::Vector3d &P2,
const Eigen::Vector3d &P3,
Eigen::Vector4d &plane_coeff)
{
Eigen::Vector3d V1=P1-P2;
Eigen::Vector3d V2=P1-P3;
Eigen::Vector3d normal;
normal=V1.cross(V2);
plane_coeff.block<3,1>(0,0)=normal;
plane_coeff(3)=-plane_coeff(0)*P1(0)-plane_coeff(1)*P1(1)-plane_coeff(2)*P1(2);
}
主函数代码如下:
Eigen::Vector3d P1(0,0,0);
Eigen::Vector3d P2(1,0,0);
Eigen::Vector3d P3(0,1,0);
Eigen::Vector3d normal;
Eigen::Vector4d plane_coeff;
getNormalBy3Points(P1,P2,P3,normal);
getPlaneBy3Points(P1,P2,P3,plane_coeff);
std::cout<<normal.transpose()<<std::endl;
std::cout<<plane_coeff.transpose()<<std::endl;
输出如下:
0 0 1
0 0 1 -0
最好用别的数据测试一下,这个测试数据太简单了。