求解直线与平面的交点
求解直线与平面的交点
微信公众号:幼儿园的学霸
目录
文章目录
- 求解直线与平面的交点
- 目录
- 前言
- 数学模型推导
- 编程实现
- 参考资料
前言
直线与平面的交点求解相关的内容在网上已经有很多资料进行介绍,目前所看到的博文在数学模型建立上都是正确的,但是其编程实现却存在问题,导致只有部分情况下能够正确求出直线与平面的交点,另外一些情况下求出的交点却是错误的.本文对原理进行推导并实现正确的编码.
数学模型推导
已知经过两点 P 1 ( x 1 , y 1 , z 1 ) , P 2 ( x 2 , y 2 , z 2 ) P_1(x_1,y_1,z_1),P_2(x_2,y_2,z_2) P1(x1,y1,z1),P2(x2,y2,z2)的直线与平面 a x + b y + c z + d = 0 ax+by+cz+d=0 ax+by+cz+d=0相交于点P
,求点P
的坐标.
该问题几何模型如下:
求解该问题的一种方法是建立方程组,联立求解点的坐标.该方法在数学实现上非常直观,但是求方程组的解稍微麻烦.
另一种是通过向量法进行求解.推导过程如下:
设 m = P 1 P → P 1 P 2 → , 则 O P → = O P 1 → + P 1 P → = O P 1 → + m ∗ P 1 P 2 → 设 m = \frac{\overrightarrow {P_1P}}{\overrightarrow{P_1P_2}},则 \\ \overrightarrow {OP} = \overrightarrow {OP_1} + \overrightarrow {P_1P} =\overrightarrow {OP_1} + m*\overrightarrow {P_1P_2} 设m=P1P2 P1P ,则OP =OP1 +P1P =OP1 +m∗P1P2
其中:
m = P 1 P → P 1 P 2 → = P 1 D → P 1 D 2 → = ∣ P 1 D → ∣ ∣ P 1 D 2 → ∣ m = \frac{\overrightarrow {P_1P}}{\overrightarrow{P_1P_2}} = \frac{\overrightarrow {P_1D}}{\overrightarrow{P_1D_2}} = \frac{\lvert \overrightarrow {P_1D}\rvert } {\lvert \overrightarrow{P_1D_2} \rvert} m=P1P2 P1P =P1D2 P1D =∣P1D2 ∣∣P1D ∣
而
∣ P 1 D → ∣ \lvert \overrightarrow {P_1D}\rvert ∣P1D ∣为点P1
到平面的距离,计算公式如下:
∣ P 1 D → ∣ = ∣ a x 1 + b y 1 + c z 1 + d ∣ a 2 + b 2 + c 2 \lvert \overrightarrow {P_1D}\rvert = \frac{\lvert {ax_1+by_1+cz_1+d} \rvert} {\sqrt{a^2+b^2+c^2}} ∣P1D ∣=a2+b2+c2 ∣ax1+by1+cz1+d∣
另外:
∣ P 1 D 2 → ∣ = ∣ P 1 P 2 → ∣ c o s θ = ∣ P 1 P 2 → ∣ ∗ ∣ P 1 P 2 → ⋅ P 1 D 2 → ∣ ∣ P 1 P 2 → ∣ ∣ P 1 D 2 → ∣ = ∣ P 1 P 2 → ⋅ P 1 D 2 → ∣ P 1 D 2 → ∣ ∣ {\lvert \overrightarrow{P_1D_2} \rvert} = {\lvert \overrightarrow{P_1P_2} \rvert}cos{\theta} = {\lvert \overrightarrow{P_1P_2} \rvert} * \frac{\lvert{\overrightarrow{P_1P_2} \cdot \overrightarrow{P_1D_2} } \rvert} {\lvert{\overrightarrow{P_1P_2}} \rvert \lvert{\overrightarrow{P_1D_2}} \rvert} \\ =\lvert{ \overrightarrow{P_1P_2} \cdot \frac{\overrightarrow{P_1D_2}}{\lvert{\overrightarrow{P_1D_2}} \rvert} } \rvert ∣P1D2 ∣=∣P1P2 ∣cosθ=∣P1P2 ∣∗∣P1P2 ∣∣P1D2 ∣∣P1P2 ⋅P1D2 ∣=∣P1P2 ⋅∣P1D2 ∣P1D2 ∣
显然, P 1 D 2 → ∣ P 1 D 2 → ∣ \frac{\overrightarrow{P_1D_2}}{\lvert{\overrightarrow{P_1D_2}} \rvert} ∣P1D2 ∣P1D2 表示平面的单位法向量,其用坐标的形式表示如下:
P 1 D 2 → ∣ P 1 D 2 → ∣ = ( a , b , c ) a 2 + b 2 + c 2 \frac{\overrightarrow{P_1D_2}}{\lvert{\overrightarrow{P_1D_2}} \rvert} = \frac{(a,b,c)}{\sqrt{a^2+b^2+c^2}} ∣P1D2 ∣P1D2 =a2+b2+c2 (a,b,c)
因此:
∣ P 1 D 2 → ∣ = ∣ P 1 P 2 → ⋅ P 1 D 2 → ∣ P 1 D 2 → ∣ ∣ = P 1 D 2 → ∣ P 1 D 2 → ∣ = ∣ a ( x 2 − x 1 ) + b ( y 2 − y 1 ) + c ( z 2 − z 1 ) a 2 + b 2 + c 2 ∣ {\lvert \overrightarrow{P_1D_2} \rvert} = \lvert{ \overrightarrow{P_1P_2} \cdot \frac{\overrightarrow{P_1D_2}}{\lvert{\overrightarrow{P_1D_2}} \rvert} } \rvert = \frac{\overrightarrow{P_1D_2}}{\lvert{\overrightarrow{P_1D_2}} \rvert} \\ = \lvert{ \frac{a(x_2-x_1)+b(y_2-y_1)+c(z_2-z_1)}{\sqrt{a^2+b^2+c^2}} } \rvert ∣P1D2 ∣=∣P1P2 ⋅∣P1D2 ∣P1D2 ∣=∣P1D2 ∣P1D2 =∣a2+b2+c2 a(x2−x1)+b(y2−y1)+c(z2−z1)∣
综上,可得:
m = ∣ P 1 D → ∣ ∣ P 1 D 2 → ∣ = ∣ a x 1 + b y 1 + c z 1 + d a ( x 2 − x 1 ) + b ( y 2 − y 1 ) + c ( z 2 − z 1 ) ∣ O P → = O P 1 → + P 1 P → = O P 1 → + m ∗ P 1 P 2 → 或 ( x , y , z ) = ( x 1 , y 1 , z 1 ) + m ∗ ( x 2 − x 1 , y 2 − y 1 , z 2 − z 1 ) m = \frac{\lvert \overrightarrow {P_1D}\rvert } {\lvert \overrightarrow{P_1D_2} \rvert} = \lvert{\frac{ax_1+by_1+cz_1+d}{a(x_2-x_1)+b(y_2-y_1)+c(z_2-z_1)} } \rvert \\ \overrightarrow {OP} = \overrightarrow {OP_1} + \overrightarrow {P_1P} =\overrightarrow {OP_1} + m*\overrightarrow {P_1P_2} \\ 或 (x,y,z) = (x_1,y_1,z_1) + m*(x_2-x_1,y_2-y_1,z_2-z_1) m=∣P1D2 ∣∣P1D ∣=∣a(x2−x1)+b(y2−y1)+c(z2−z1)ax1+by1+cz1+d∣OP =OP1 +P1P =OP1 +m∗P1P2 或(x,y,z)=(x1,y1,z1)+m∗(x2−x1,y2−y1,z2−z1)
编程实现
/*!* 求直线与平面的交点* @param p1* @param p2 直线经过的两点p1,p2* @param plane 平面参数 ax+by+cz+d=0* @param crossP 交点* @return true--直线与平面相交;false--直线与平面平行(或者位于平面内)* @author liheng*/
bool GetLinePlaneCrossP(Eigen::Vector3f p1,Eigen::Vector3f p2,const Eigen::Vector4f& plane,Eigen::Vector3f& crossP)
{//求分子P1Dauto P1D = plane[0]*p1[0] + plane[1]*p1[1] + plane[2]*p1[2]+plane[3];//ax1+by1+cz1+d//or采用向量点乘方式P1D = std::abs( P1D );auto P2D = plane[0]*p2[0] + plane[1]*p2[1] + plane[2]*p2[2]+plane[3];P2D = std::abs( P2D );//保证P2离平面比较近if( P1D<P2D ){std::swap(p1,p2);//点交换P1D = P2D;//距离交换}const Eigen::Vector3f P1P2 = p2-p1;//求分母P1D2auto P1D2 = plane[0]*P1P2[0] + plane[1]*P1P2[1] + plane[2]*P1P2[2];P1D2 = std::abs(P1D2);if( P1D2<FLT_EPSILON )return false;//平行auto m = P1D/P1D2;crossP = p1 + m*P1P2;return true;
}下面函数同样可以
///*!
// * 求直线与平面的交点
// * @param p1
// * @param p2 直线经过的两点p1,p2
// * @param plane 平面参数 ax+by+cz+d=0
// * @param crossP 交点
// * @return true--直线与平面相交;false--直线与平面平行(或者位于平面内)
// * @author liheng
// */
//bool GetLinePlaneCrossP(const Eigen::Vector3f& p1,const Eigen::Vector3f& p2,const Eigen::Vector4f& plane,Eigen::Vector3f& crossP)
//{
// //求分子P1D
// auto P1D = plane[0]*p1[0] + plane[1]*p1[1] + plane[2]*p1[2]+plane[3];//ax1+by1+cz1+d//or采用向量点乘方式
//
// const Eigen::Vector3f P1P2 = p2-p1;
//
// //求分母P1D2
// auto P1D2 = plane[0]*P1P2[0] + plane[1]*P1P2[1] + plane[2]*P1P2[2];
// if( std::abs(P1D2)<FLT_EPSILON )
// return false;//平行
//
// auto m = P1D/P1D2;
// crossP = p1 - m*P1P2;//注意:此处是 负号- 同时求m时无绝对值符号
//
// return true;
//}int main(int argc, char ** argv )
{Eigen::Vector3f p1(0,0,5),p2(0,0,-10),crossP;Eigen::Vector4f plane(0,0,1,0);//z=0GetLinePlaneCrossP(p1,p2,plane,crossP);std::cout<<"crossP:"<<crossP<<std::endl;return 0;
}
上面的2个函数均可以求出直线与平面交点.不论输入的两点在平面两侧或位于平面同一侧,以及两点到平面的距离排序.
粗略的python版本如下
#!/usr/bin/env python3
#coding=utf-8#============================#
#Program:main.py
#
#Date:20-6-23
#Author:liheng
#Version:V1.0
#============================#import numpy as npx1,y1,z1 = 0,0,10
x2,y2,z2 = 0,0,5
a,b,c,d = 0,0,1,0# p1 = np.array([x1,y1,z1])#
# p2 = np.array([x2,y2,z2])
# plane_normal = np.array([a,b,c]) #a,b,c,d平面方程系数
#
# P1D = np.vdot(p1,plane_normal)+d
# P1D = np.abs(P1D)
#
# P2D = np.vdot(p2,plane_normal)+d
# P2D = np.abs(P2D)
#
# if P1D<P2D:#点1靠近平面,交换点1 2
# p1,p2 = p2,p1
# P1D = P2D
#
# P1D2 = np.vdot(p2-p1,plane_normal)
# P1D2 = np.abs(P1D2)
#
# n = P1D / P1D2
# p = p1 + n*(p2- p1)#所求交点
# print(p)//or
p1 = np.array([x1,y1,z1])#
p2 = np.array([x2,y2,z2])
plane_normal = np.array([a,b,c]) #a,b,c,d平面方程系数P1D = np.vdot(p1,plane_normal)+d
P1D2 = np.vdot(p2-p1,plane_normal)n = P1D / P1D2
p = p1 - n*(p2- p1)#所求交点
print(p)
参考资料
1求直线与平面的交点
2.空间内直线于平面交点
求解直线与平面的交点相关推荐
- Unity求一条直线与平面的交点
这个是面试官经常考的一个问题,我们先把它变成一个数学问题. 已知一个平面上的一点P0和法向量n,一条直线上的点L0和方向L,求该直线与该平面的交点P 如下图 首先我们分析一下我们知道平面和直线的法向量 ...
- Revit求直线与平面的交点
直线与平面的交点有两种情况,交点在平面内或平面外,计算出交点后需确定此交点是否在已知平面内. 代码如下: /// <summary> /// 计算直线与平面的交点 /// </sum ...
- 计算直线与平面的交点
设直线上一点 p,以及其方向 dir 则直线公式可写作 p+t*dir 设平面法向量为nml,平面上一点 p0 方法一: 直线与平面相交时,必满足 dot ( (p+t*dir-p0),nml)=0 ...
- 如何求直线与平面的交点(两种方式)
一:代数方式 我们假设它们的交点为P,既然我们有一个平面,那么平面上面的一个点P0和平面的normal(垂直于平面的向量)我们是肯定知道的. 根据3D数学知识,(P-P0) · normal = 0( ...
- 三维空间直线与平面交点
三维空间直线与平面交点 已知 公式推导 最后一个等式 已知 平面描述: 平面的法向 VP(x,y,z)V_{P}(x,y,z)VP(x,y,z), 平面上的一个点 PP(x,y,z)P_{P}(x, ...
- 计算三维空间中直线和三角形的交点
计算三维空间中直线和三角形的交点 前言 一.计算平面方程 1.1 平面不过原点 1.2 平面过原点 1.3 平面过 zzz 轴 1.4 平面为 yOzyOzyOz 平面 二.计算直线方程 三.计算交点 ...
- ad走线画直线_作为立体几何的热点,直线与平面的平行关系,到处都是考试的影子...
在高考数学里,空间直线与平面的平行有关的知识内容和题型,一直是近几年高考命题的热点,成为立体几何重要的基础考点.如何巧妙快速的判定空间直线与平面平行位置关系,如何在平面内寻找一条直线,探索该直线与平面 ...
- 直线与直线、直线与圆、直线与矩形的交点
求直线与直线.直线与圆.直线与矩形的交点 直线与直线的交点:a1x + b1x + c1x = 0 与 a2x + b2x + c2x = 0的交点坐标可直接根据公式x = (b1c2 - b2c1) ...
- 向量叉乘求三维空间中两直线(或线段)的交点
1.2D空间的直线相交 在二维空间中,利用两个直线方程y = kx + b我们可以直接计算出交点,但是这种方法麻烦了些,并且套用到三维空间用公式就更麻烦了,接下来介绍的是如何利用向量叉乘求出直线交点. ...
最新文章
- 一阵骚操作,我把SQL执行效率提高了10000000倍!
- 《head first java 》读书笔记(四)
- JDK5.0新特性系列---11.4线程 Condition
- ElementUI的el-cascader级联选择器各个属性的设置
- 【python】【scrapy】使用方法概要(三)
- WiFi---AP+STA共存模式(ESP8266)
- vba抓取网页数据到excel_抓取网页数据,上班也能看股票
- 【操作系统】对换、分页和分段方式-思维导图
- 使用HQL语句的按照参数名字查询数据库信息的时候 “=:”和参数之间不能存在空格,否则会报错...
- 操作系统-管程、进程和线程之间的差别
- 【数据治理】数据元、元数据、主数据、参考数据概述
- 手机屏碎了,怎样辨别是外屏坏还是内屏坏,看完这篇文章就明白了
- python如何设计一个排队系统
- Unity 判断鼠标点击的是单击还是双击
- spring注解开发配置spring父子容器
- Python 如何被证明是 2021 年的转折点语言
- QT作为设备接入阿里云平台
- centos安装Nvidia显卡驱动(3090)
- 墙裂推荐!Pycharm里6大神器插件!
- Xgen Animwires 随笔01