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 vert0
Vec3Sub(edge1, v1, v0);
Vec3Sub(edge2, v2, v0); //Begin calculating determinant - also used to calculate U parameter
Vec3Cross(pvec, dir, edge2); //If the determinant is near zero, ray lies in plane of triangle
Vec3Dot(det, edge1, pvec); //If bCull is true
if(bCull)
{
if(det < 0.00001f)
return false ; //Calculate distance from vert0 to ray origin
Vec3Sub(tvec, origin, v0); //Calculate U parameter and test bounds
Vec3Dot(u, tvec, pvec);
if(u < 0.0 || u > det)
return false ; //Prepare to test v parameter
Vec3Cross(qvec, tvec, edge1); //Calculate V parameter and test bounds
Vec3Dot(v, dir, qvec);
if(v < 0.0f || u + v > det)
return false ; //Calculate t , scale paramter, ray intersect triangle
Vec3Dot(*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 origin
Vec3Sub(tvec, origin, v0); //Calculate u parameter and test bounds
Vec3Dot(u, tvec, pvec);
u *= inv_det ;
if(u < 0.0 || u > 1.0)
return false ; //prepare to test v parameter
Vec3Cross(qvec, tvec, edge1); //Calculate v parameter and test bounds
Vec3Dot(v, dir, qvec);
v *= inv_det ;
if(v < 0.0 || u + v > 1.0)
return false ; //calculate t, ray intersect triangle
Vec3Dot(*t, edge2, qvec);
*t *= inv_det ;
} return true ;
}// end for intersectWithTriangle</span>
演示样例程序截图
这个图是在没有发生交叉的时候的情况。
下图是在发生了交叉之后的截图:
今天的笔记就此结束。以后会陆续出现这样的文章,请大家关注吧!
!
!
3D空间中射线与三角形的交叉检測算法的更多相关文章
- 3D空间中射线与三角形的交叉检测算法【转】
引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...
- 3D空间中射线与轴向包围盒AABB的交叉检测算法【转】
引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是 ...
- 3D空间中射线与轴向包围盒AABB的交叉检测算法 【转】
http://blog.csdn.net/i_dovelemon/article/details/38342739 引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法. 但是,我们应该知道, ...
- WebGL和ThreeJs学习6--射线法确定3D空间中所选物体
一.在 threejs 中如何确定下图3D空间中鼠标点击位置的 object 对象? 二.射线法确定步骤及代码 //Three.js提供一个射线类Raycaster来拾取场景里面的物体.更方便的使用鼠 ...
- 2D和3D空间中计算两点之间的距离
自己在做游戏的忘记了Unity帮我们提供计算两点之间的距离,在百度搜索了下. 原来有一个公式自己就写了一个方法O(∩_∩)O~,到僵尸到达某一个点之后就向另一个奔跑过去 /// <summary ...
- OpenGL ES 3D空间中自定义显示空间
在Android中,我们所熟知的是在ES管线中,其在图元装配时,会进行图元组装与图元分配,这样就回剪裁出来视景体中的物体.但是如果我想在3D场景中规定一个区域,凡是在这个区域中的物体就能显示出来,非这 ...
- 利用opencv中的级联分类器进行人脸检測-opencv学习(1)
OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...
- 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測
在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...
- Direct3D 11 Tutorial 4: 3D Spaces_Direct3D 11 教程4:3D空间
概述 在上一个教程中,我们在应用程序窗口的中心成功渲染了一个三角形. 我们没有太注意我们在顶点缓冲区中拾取的顶点位置. 在本教程中,我们将深入研究3D位置和转换的细节. 本教程的结果将是渲染到屏幕的3 ...
随机推荐
- oracle数据库连接无响应的解决
昨天中午时,查询到服务器的数据流水最晚记录是早上8点的,现场查看服务日志很奇怪,日志输出显示挂死在数据库连接这一步.多次调试无果,随后百度发现有资料显示oracle 10.2.1的版本有登录无响应的B ...
- WM_PAINT消息小结
WM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作. 1. 系统何时发送WM_PAINT消息? 系统会在多个不同的时机发送WM_PAINT消息:当第 ...
- Android实现异步处理 -- HTTP请求
原帖:http://www.cnblogs.com/answer1991/archive/2012/04/22/2464524.html Android操作UI的方法不是线程安全的,也就是说开发者自己 ...
- 01-OC介绍
目录 一.OC语言介绍 二.ios系统 三.在OC语言开发中使用C语言语法 四.面向对象 回到顶部 一.OC语言介绍 1 早在20世纪80年代早期,BardCox发明了Objective-C,扩充了C ...
- 关于callContext
coding们肯定有这种需求,在程序中,方法一级级调下去,比如A->b->C->D.... ->Z.在调用过程中,希望在调用函数之间传递一些数据,常见的是将特定的数据从高往低处 ...
- DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)
函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...
- Sed常用实例总结
[Sed简介] sed是一个文件处理工具,本身是一个管道命令,主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等.sed以行为单位,一次处理一行内容,处理时,把当前处理的行存储在临时 ...
- 深入浅出 消息队列 ActiveMQ(转)
一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...
- SonicUI在MFC中的使用
SonicUI是一个GUI引擎,提供了一些简单的UI组件实现高效率的UI效果,例如:自绘按钮.异形窗体.动画.超链接和图像操作方法.此项目作者开源到CodeProject,地址为:http://www ...
- 挺苹果的声音,iPhone 5s的两处进步
苹果iPhone 5s发布后的两处重大进步让我很关注,但看了网上众多网友的点评,又深深的被中国当前手机发烧友圈的这种屌丝文化所震撼,这不是一条正确的道路,这将把中国的手机产业引向歧途,所以我不得不说几 ...