线形对象与平面相交

2023-10-30 09:50
文章标签 对象 相交 平面 线形

本文主要是介绍线形对象与平面相交,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

三维空间中的线形对象包括直线、射线和线段,为了统一三者的表达,在三维图形学中一般使用一个点和方向向量的方式来描述这些线形对象。

假设有一个点P位于线形对象上,方向向量是 d⃗  ,那么这个线形对象可以使用下面的公式来表达:

L(t)=P+td⃗ 

基于这个表达式,直线方程可以描述为:

L(t)=P+td⃗ (t)

射线方程可以描述为(P是射线的端点):

R(t)=P+td⃗ (0t)

在描述线段时,使用一对点{ P0 P1 },则线段方程是:

S(t)=P0+t(P1P0)(0t1)

平面的描述方式很多,最简单的是使用一般式 ax+by+cz+d=0 ,向量 n⃗ =[a,b,c] 是平面的法向量。

1. 直线与平面相交

PlaneLineIntersection

如上图所示,直线方程L是 P+td⃗  , 平面方程是 ax+by+cz+d=0 ,假设二者有交点(交于点Q),那么直线上的Q点也一定满足平面方程,也就是:

Q=P+td⃗  满足 ax+by+cz+D=0 (为区别直线的方向向量,平面方程的常数项写成D),将Q点带入平面方程中,得到:

a(Px+tdx)+b(Py+tdy)+c(Pz+tdz)+D=0

t=(D+aPx+bPy+cPz)adx+bdy+cdz

写成向量的形式是:

t=(D+n⃗ P)n⃗ d⃗ 

针对这个表达式展开讨论:

  1. 如果 n⃗ d⃗ =0 那么说明直线平行于平面或者直线位于平面之内。怎么判断直线是否位于平面之内呢?很简单,判断直线的另一个点P是否位于平面内即可,也就是把P点带入平面方程中,如果满足平面方程,那么直线位于平面内,不满足则二者平行。
  2. 如果 n⃗ d⃗ 0 ,那么直线和平面有唯一的交点,将t值带入到 Q=P+td⃗  可以求出二者的交点坐标。

总结如下:

  1. n⃗ d⃗ =0 aPx+bPy+cPz+D=0 直线位于平面内
  2. n⃗ d⃗ =0 aPx+bPy+cPz+D0 直线与平面平行
  3. n⃗ d⃗ 0 直线与平面有唯一交点

在编码过程中由于浮点数的舍入误差,一般将结果与一个阈值 ϵ 进行比较,通过比较快速判断直线与平面是否相交。

2. 射线与平面相交

射线的方程表达式与直线类似,但是射线稍有不同的是它表达式中的 P一定是射线的端点,如果P是射线的端点,那么计算的过程与直线中的结论完全一样,只不过需要在判断相交的时候t的取值,如果取值范围 t0 ,那么就可以带入到射线方程中求出交点Q,否则(也就是 t<0 )二者没有交点。

总结如下:

  1. n⃗ d⃗ =0 aPx+bPy+cPz+D=0 直线位于平面内
  2. n⃗ d⃗ =0 aPx+bPy+cPz+D0 直线与平面平行
  3. n⃗ d⃗ 0 t0 射线与平面有唯一交点
  4. n⃗ d⃗ 0 t<0 射线与平面没有交点

3. 线段与平面相交

线段的计算过程同样与射线类似,可以通过直线方程

S(t)=P0+t(P1P0)(0t1)

来计算,需要注意的是线段的方向向量 d⃗  ,必须是 P1P0 ,这样t的取值范围就是在[0,1]区间,如果t的取值范围不是[0,1],那么线段与平面无交点。

总结如下:

  1. 直线方程的方向向量必须是 P1P0 (直线和射线只要方向相同即可,甚至可以单位化方向向量,但是线段必须是 P1P0
  2. n⃗ d⃗ =0 aPx+bPy+cPz+D=0 直线位于平面
  3. n⃗ d⃗ =0 aPx+bPy+cPz+D0 直线与平面平行
  4. n⃗ d⃗ 0 t[0,1] 射线与平面有唯一交点
  5. n⃗ d⃗ 0 t[0,1] 射线与平面没有交点

4. 算法实现

使用OpenSceneGraph实现线段和平面的相交判断的代码如下:


/* 
*  线段和平面的相交关系判断:返回值是0表示没有交点,返回值是1表示二者有唯一交点,返回值是2表示线段位于平面内
*
*/int intersectSegmentPlane(const osg::Plane& plane, const osg::LineSegment& lineSegment, osg::Vec3d& intersection)
{double epsilon = 1e-6;osg::Vec3d planeNorm = plane.getNormal();osg::Vec3d segmentDirection = lineSegment.end() - lineSegment.start();double dotPlaneNormSegDir = planeNorm * segmentDirection;osg::Vec4d planeParam = plane.asVec4();double lineInPlane = planeParam.x() * lineSegment.start().x() + planeParam.y() * lineSegment.start().y() +planeParam.z() * planeParam.z() + planeParam.w();if (fabs(dotPlaneNormSegDir) < epsilon){//如果直线端点满足平面方程,那么直线在平面内if (fabs(lineInPlane) < epsilon){return 2;}else{return 0;}}double planeNormDotP = -(planeParam.w() + planeNorm * lineSegment.start());double t = planeNormDotP / dotPlaneNormSegDir;if (t < 0 || t > 1)return 0;intersection = lineSegment.start() + segmentDirection*t;return 1;
}

5. 参考文献

  1. Line and Segment Intersections
  2. [书籍:Geometric Tools for Computer Graphics]

这篇关于线形对象与平面相交的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/307096

相关文章

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

java中VO PO DTO POJO BO DO对象的应用场景及使用方式

《java中VOPODTOPOJOBODO对象的应用场景及使用方式》文章介绍了Java开发中常用的几种对象类型及其应用场景,包括VO、PO、DTO、POJO、BO和DO等,并通过示例说明了它... 目录Java中VO PO DTO POJO BO DO对象的应用VO (View Object) - 视图对象

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.

poj 1127 线段相交的判定

题意: 有n根木棍,每根的端点坐标分别是 px, py, qx, qy。 判断每对木棍是否相连,当他们之间有公共点时,就认为他们相连。 并且通过相连的木棍相连的木棍也是相连的。 解析: 线段相交的判定。 首先,模板中的线段相交是不判端点的,所以要加一个端点在直线上的判定; 然后,端点在直线上的判定这个函数是不判定两个端点是同一个端点的情况的,所以要加是否端点相等的判断。 最后

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d