Eigen 由三点求平面方程及平面法向量

Eigen 由三点求平面方程及平面法向量

一、原理

  已知三点 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=(x2x1,y2y1,z2z1) 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=(x3x1,y3y1,z3z1),平面法向量和这两个向量都垂直,因此法向量 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| \begin{array}{ccc} 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 \end{array} \right|=ai+bj+ck=(a,b,c) n=V1×V2= ix2x1x3x1jy2y1y3y1kz2z1z3z1 =ai+bj+ck=(a,b,c)
其中:
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=(y2y1)(z3z1)(y3y1)(z2z1)b=(z2z1)(x3x1)(z3z1)(x2x1)c=(x2x1)(y3y1)(x3x1)(y2y1)

平面方程为: 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(xx1)+b(yy1)+c(zz1)=0,所以 d = − a ∗ x 1 − b ∗ y 1 − c ∗ z 1 d=-a*x_1-b*y_1-c*z_1 d=ax1by1cz1,平面方程为:
a x + b y + c z + d = 0 ax+by+cz+d=0 ax+by+cz+d=0

二、Eigen实现

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

最好用别的数据测试一下,这个测试数据太简单了。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值