3D空间中射线与三角形的交叉检測算法
引言
射线Ray,在3D图形学中有非常多重要的应用。比方,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检測等等都能够使用射线Ray来完毕。
所以,在本次博客中,将会简单的像大家介绍下。怎样进行Ray-Triangle的交叉检測。
Ray-Triangle交叉检測算法
在Tomas Moller的MT97论文中,提出了一种新的算法。这样的算法可以降低曾经进行Ray-Triangle交叉检測所须要的内存消耗。在曾经。进行Ray-Triangle交叉检測,主要是计算射线与三角形所构成的平面的交点,然后又一次推断交点是否在三角形上。从而来推断是否发生了交叉。
这样的方法非常直观,符合我们一直以来所学的数学知识。可是,这样的检測方法进行的计算较多。并且还须要依据三角形来求它所在的平面。这样又须要进行计算。同一时候也须要另外开辟空间来保存计算出来的平面。
数学之美,就在于可以找到其它的方法来取代这样的显而易见的方式,从而将问题简化到一定的程度。这样的简化的过程。不须要在代码中实现,仅仅须要我们事先依据条件,然后在草稿纸上计算出最后的结论,我们仅仅须要在我们的代码中直接使用终于得到的结论就可以。
在Tomas Moller的论文中,它提到了这种一个概念:
假设一个点在三角形V0。 V1, V2上,那么这个点就能够用例如以下的方式来表示:
T(u, v) = (1 - u - v) * V0 + u * V1 + v * V2 ;
这里u+v <= 1, u >= 0 , v >=0
而对于射线,我们一般使用例如以下的方程来表示它:
R (t)= O + t * D ; (O为射线的起始点,D为射线的方向)
所以,既然他们要有交点。我们就行直接使用例如以下的方法来得出:
O + t * D = (1 - u - v) * V0 + u * V1 + v * V2
然后在进行一系列的变换。终于得到结果。
感兴趣的读者能够自行阅读Tomas Moller的论文,论文中具体的解释了推导过程。这里不再赘述。
Ray-Triangle交叉检測算法实现
下面是Ray-Triangle交叉检測算法的Moller算法实现,基本上就是Tomas Moller论文中代码的拷贝,例如以下所看到的:
<span style="font-family:Microsoft YaHei;">bool Ray::intersectWithTriangle(VECTOR3 v0,VECTOR3 v1, VECTOR3 v2,bool bCull, float *t)
{VECTOR3 edge1, edge2, tvec, pvec, qvec ;float det, inv_det ;float u,v ;//Find vectors for two edges sharing vert0Vec3Sub(edge1, v1, v0);Vec3Sub(edge2, v2, v0);//Begin calculating determinant - also used to calculate U parameterVec3Cross(pvec, dir, edge2);//If the determinant is near zero, ray lies in plane of triangleVec3Dot(det, edge1, pvec);//If bCull is trueif(bCull){if(det < 0.00001f)return false ;//Calculate distance from vert0 to ray originVec3Sub(tvec, origin, v0);//Calculate U parameter and test boundsVec3Dot(u, tvec, pvec);if(u < 0.0 || u > det)return false ;//Prepare to test v parameterVec3Cross(qvec, tvec, edge1);//Calculate V parameter and test boundsVec3Dot(v, dir, qvec);if(v < 0.0f || u + v > det)return false ;//Calculate t , scale paramter, ray intersect triangleVec3Dot(*t, edge2, qvec);inv_det = 1.0f / det ;*t *= inv_det ;u *= inv_det ;v *= inv_det ;}else{if(det > -0.00001f && det < 0.00001)return false ;inv_det = 1.0f / det ;//calculate distance from v0 to ray originVec3Sub(tvec, origin, v0);//Calculate u parameter and test boundsVec3Dot(u, tvec, pvec);u *= inv_det ;if(u < 0.0 || u > 1.0)return false ;//prepare to test v parameterVec3Cross(qvec, tvec, edge1);//Calculate v parameter and test boundsVec3Dot(v, dir, qvec);v *= inv_det ;if(v < 0.0 || u + v > 1.0)return false ;//calculate t, ray intersect triangleVec3Dot(*t, edge2, qvec);*t *= inv_det ;}return true ;
}// end for intersectWithTriangle</span>
演示样例程序截图
这个图是在没有发生交叉的时候的情况。
下图是在发生了交叉之后的截图:
今天的笔记就此结束。以后会陆续出现这样的文章,请大家关注吧!
!
!
3D空间中射线与三角形的交叉检測算法相关推荐
- 3D空间中射线与三角形的交叉检测算法
http://blog.csdn.net/i_dovelemon/article/details/38332499 引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ra ...
- 3D空间中射线与三角形的交叉检测算法【转】
引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...
- 3D空间中射线与轴向包围盒AABB的交叉检测算法
引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是 ...
- 在3D空间中绘制四边形
在3D空间中绘制四边形 四边形 GL_QUADS OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形. 注意,在使用四边形时,必需记住一个重要规则:一个四边形的四个角必须 ...
- 使3D空间中物体朝向和其速度方向一致的旋转矩阵计算方案
在3D空间中的物体以某一速度运动,有时候需要这个物体的朝向和速度的方向一致, 为了实现这个目标我们一般借助旋转矩阵 M 来将物体旋转到对应的朝向. 例如速度方向矢量 spdV: Vector3D(1, ...
- 使用脑电图慢皮层电位重建3D空间中的手,肘和肩的实际和想象的轨迹
导读 从神经活动中解码想象运动的运动学的能力对于开发可以帮助行动不便的人的假肢设备至关重要.当前采用脑电图(EEG)等无创记录方法解码实际和想象的手运动轨迹来控制神经运动假体,通常通过应用多维线性回归 ...
- 3D 空间中拟合曲线
算法来源:C++/PCL:最小二乘拟合平面直线,平面多项式曲线,空间多项式曲线 以下是我改写的算法,未经验证正确性!!! // 3D 空间中拟合曲线 void fittingPolynomial3D( ...
- 3D空间中的点坐标转化为屏幕二维点坐标(一)
每个人在进入计算机图形学的世界中,都有一个同样的困惑,三维世界中的三维坐标是如何被转换成屏幕上的二维坐标的,我如何在屏幕上找到一个点(二维点)对应三维世界中的点(三维点)呢? 要理解其中的过程,对学习 ...
- 一般向量空间的基变换_向量几何--3-D空间中的基变换与坐标变换【转】 - 回到未来 - C++博客...
<6>3-D空间中的基变换与坐标变换-Twinsen编写 -本人水平有限,疏忽错误在所难免,还请各位数学高手.编程高手不吝赐教 -我的Email-address:popyy@netease ...
最新文章
- 只要一句话、一段文字,想让奥巴马说啥他就说啥
- mac安装git客户端
- sigquit信号默认忽略吗_linux下的信号列表
- JAVA增删查改的实现
- Django实现一个简单的中间件,不熟悉中间件的爬坑之路
- 【BZOJ4569】萌萌哒,ST表+并查集
- Python+turtle绘制虚线同心圆
- Protocol Buffers proto语言语法说明
- android碎片按钮,Android 碎片学习 之 如何在碎片调用Activity中的方法来进行赋值操作...
- Java基础(彩票小程序)
- 怎么用html实现QQ代挂功能,QQ等级每天有几种加速方式
- CDN最通俗易懂的CDN解释
- 阿凡题——智慧的背囊
- 双色球的实现(基于Vuejs)
- 美团、点评app抓包及参数分析
- SpringMVC:视图解析器(ViewResolver)
- 单独使用Quartz 2.1.7 时Job属性Spring无法注入
- WPS做论文的时候为什么文字后面不能添加下划线?
- 2020年的科技趋势:随时准备改变企业的未来!
- 大华服务器维护常使用的命令,大华平台软件简介
热门文章
- Gradle错误提示:Java home supplied via 'org.gradle.java.home' is invalid
- Ranorex通过Python如何将报告发送到邮箱。
- 淘淘商城第68讲——ActiveMQ简介
- springboot junit测试时环境变量问题 idea
- DuerOS - DuerOS对话式人工智能系统唤醒
- 学计算机的怎样当老师,“年薪50万,不如安心当老师”,过来人揭开千万人报考教资的真相...
- 32位和64位及其内存长度
- web前端模仿微信悬浮窗效果
- matlab中cplxpair是什么,colon_HCOLON什么意思
- itext破解pdf不能复制