当前位置:网站首页>空间直线到平面上的交点的计算证明及其源码
空间直线到平面上的交点的计算证明及其源码
2022-07-30 05:49:00 【夕阳染色的坡道】
目的:最近写C++代码,遇到一些基础的算法。需要空间直线和平面的交点。
直线的向量表达: L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0} L:r=P0+tN0;其中 P 0 → = ( x 0 y 0 z 0 ) \overrightarrow{P_0}=\begin{pmatrix} x_0 \\ y_0 \\ z_0 \end{pmatrix} P0=⎝⎛x0y0z0⎠⎞, N 0 → = ( n x 0 n y 0 n z 0 ) \overrightarrow{N_0}=\begin{pmatrix} n_x^0 \\ n_y^0 \\ n_z^0 \end{pmatrix} N0=⎝⎛nx0ny0nz0⎠⎞
平面的向量表达: π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0 π:N1T⋅X+d1=0;其中 N 1 → = ( n x 1 n y 1 n z 1 ) \overrightarrow{N_1}=\begin{pmatrix} n_x^1 \\ n_y^1 \\ n_z^1 \end{pmatrix} N1=⎝⎛nx1ny1nz1⎠⎞, d d d为标量。
对于直线到平面的交点它分为三种情况:
1)在平面上
2)平行平面
3)和平面相交
图示如下:
左图和中间图可以看到,它和平面没有交点。因此需要判断直线是否和平面相交。在传统的空间中,平面和直线平面的话,直线和平面的发向量是垂直的。因此可以通过计算 N 0 → \overrightarrow{N_0} N0和 N 1 → \overrightarrow{N_1} N1之间的夹角。如果它是垂直表面直线和平面平行。
c o s ( θ ) − > N 0 → T ⋅ N 1 → cos(\theta)->\overrightarrow{N_0}^T \cdot \overrightarrow{N_1} cos(θ)−>N0T⋅N1
如果它接近于0表示它平行。
下面将介绍相交的情况
如果平面和直线相交,对于直线来说,只需要计算 t t t即可。
L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0} L:r=P0+tN0带入公式 π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0 π:N1T⋅X+d1=0得到如下:
N 1 → T ⋅ ( P 0 → + t N 0 → ) + d 1 = 0 = > N 1 → T ⋅ P 0 → + t N 1 → T ⋅ N 0 → + d 1 = 0 t = ( − d 1 − N 1 → T ⋅ P 0 → ) / N 1 → T ⋅ N 0 → \overrightarrow{N_1}^T \cdot (\overrightarrow{P_0}+t\overrightarrow{N_0})+d_1=0 \\ =>\overrightarrow{N_1}^T \cdot \overrightarrow{P_0}+t \overrightarrow{N_1}^T \cdot \overrightarrow{N_0}+d_1=0 \\ t=(-d_1 - \overrightarrow{N_1}^T \cdot \overrightarrow{P_0})/\overrightarrow{N_1}^T \cdot \overrightarrow{N_0} N1T⋅(P0+tN0)+d1=0=>N1T⋅P0+tN1T⋅N0+d1=0t=(−d1−N1T⋅P0)/N1T⋅N0
因为向量 P 0 → \overrightarrow{P_0} P0, N 0 → \overrightarrow{N_0} N0, N 1 → \overrightarrow{N_1} N1都是已知,因此可以求的 t = t n t=t_n t=tn。
带入得到
r n → = P 0 → + t n N 0 → \overrightarrow{r_n}=\overrightarrow{P_0}+t_n\overrightarrow{N_0} rn=P0+tnN0
基于上述的公式,源码如下:
bool LineRayToPlanePnt(Eigen::Vector3f& o_orign, Eigen::Vector3f& o_dir, Eigen::Vector4f& fn, Eigen::Vector3f& inter_pnt)
{
Eigen::Vector3f N = Eigen::Vector3f(fn[0], fn[1], fn[2]);
float D = fn[3];
if (std::abs(o_dir.dot(N)) < 1e-8)
{
return false;
}
float t = -(o_orign.dot(N) + D) / (o_dir.dot(N));
inter_pnt = o_orign + t*o_dir;
}
边栏推荐
猜你喜欢

Vineyard: 开源分布式内存数据管理框架

网络协议04 - 物理层和数据链路层

关于memcache内核,全网最通俗的讲解

npm安装nodejs环境配置

The Force Plan Microservices | Centralized Configuration Center Config Asymmetric Encryption and Security Management

PXE高效批量网络装机

02-Use of Cycript

Shortcut keys commonly used in the use of Word

测试开发工程师成长日记003 - 接口自动化框架搭建

Build an intelligent network security management and control system for digital government
随机推荐
BlockingQueue详细介绍
Test Development Engineer Growth Diary 001 - Some Introduction to Agile Testing, CI/CD/CT, DecOps
Test Development Engineer Growth Diary 018 - Record of Required Questions for Test Interview (Continuous Update)
使用 Grafana 的 Redis Data Source 插件监控 Redis
MySQL common commands and mysqldump backup
Install MySQL under Linux (centos7)
使用Apifox测试套件自动化测试接口
如何将matlab数据导入modelsim仿真
OP 代币和不可转让的 NFT 致力于建立新的数字民主
Test development engineer diary 002 - starting from 0 interface automation
ParseException line 8:13 mismatched input ‘(‘ expecting ) near ‘int‘ in create table statement
PXE高效批量网络装机
LVM和磁盘配额
软件测试开发:发送第一封测试报告邮件
how to use xilinx's FFT ip
删除openstack中的僵尸实例
【无标题】
Redis下载与安装
prometheus-federation-tls加密
【Untitled】