高级碰撞检测及响应算法——碰撞检测
碰撞检测算法

碰撞检测算法
碰撞检测是指在计算机图形学中,用于检测当图形物体移动时是否会相互发生碰撞。
碰撞检测一般使用物理定义来判断物体当前位置是否与其他物体重叠,从而实现移动物体
间的物理相互作用。
通常情况下,碰撞检测涉及计算两个物体在当前空间状态下是否相交,碰撞的检测的两个物体一般是由它们的几何外型所表征的;因此,碰撞检测一般由对物体
几何外型的描述子对应的空间状态来判断是否存在碰撞;更进一步地,碰撞检测还需要判
断相交点在物体表面上的位置,以实现物体间的物理相互作用。
最常用的碰撞检测算法有以下几类:
1. 物体边界检测:这是指基于物体边界外形的一种检测方法,判断物体是否发生碰撞。
这种方法最简单,易于实现,以线段为例,只要计算两条线段的端点之间的距离是否
小于指定的阈值,就可以认定这两条线段是否发生碰撞。
2. 空间栅格化:这种检测方法是将物体的表面看作是一个由许多小空间格子所组成
的网格;当一个物体移动时,只要计算其占据的空间格子是否有交叉的部分,就可以认定
发生碰撞。
3. 形状比对算法:这是一种更加精确的碰撞检测方法,不仅判断物体移动是否发生
碰撞,而且还可以精确判断碰撞点所在位置,实现精确的物理交互模拟。
形状比对算法主
要利用多边形的凸多边形表示来做碰撞检测,以凸包算法为基础,将物体表面中的点多边
形分割成更小的多边形,依据凸多边形的几何关系,实现物体的准确碰撞检测。
上述三种碰撞检测方法都有它们的优缺点,应用时需要结合场景具体要求,根据精度
以及实现复杂度,灵活选择最佳检测算法。
碰撞检测算法:点和矩形碰撞、点和圆形碰撞、矩形碰撞、圆形碰撞

碰撞检测算法:点和矩形碰撞、点和圆形碰撞、矩形碰撞、圆形碰撞⼀,原理介绍这回有点复杂,不过看懂了还是很好理解的。
当然,我不敢保证这种算法在任何情况下都会起效果,如果有同学测试时,发现出现错误,请及时联系我。
我们⾸先来建⽴⼀个以圆⼼为原点的坐标系:然后要检测碰撞就只有两种情况了。
情况⼀,矩形全部都在⼀个象限内,如图:当然,图中只是举个例⼦,不⼀定是只在第⼆象限,任何⼀个象限都⾏,只要是矩形全在该象限。
这种情况⽐较好解决,⾸先,我们计算出矩形每个⾓的坐标,然后⽤勾股定律依次算出这个⾓到圆⼼的距离是否⼩于或者等于半径。
设这个⾓与圆⼼横坐标之差为d1,纵坐标之差为d2,半径为r,公式表达如下:如果有⼀个⾓满⾜要求说明产⽣碰撞,返回true。
但是有朋友懵了,怎么判断矩形是不是在⼀个象限内呢?很简单,只要判断这个矩形左上⾓和右下⾓是否在同⼀个象限内就可以了。
于是我们得写个函数来实现判断某两个⾓是否在同⼀象限。
函数代码如下:[javascript] view plaincopyfunction isSameQuadrant(cood,objA,objB){var coodX = cood.x;var coodY = cood.y;var xoA = objA.x,yoA = objA.y,xoB = objB.x,yoB = objB.y;if(xoA-coodX>0 && xoB-coodX>0){if((yoA-coodY>0 && yoB-coodY>0) || (yoA-coodY<0 && yoB-coodY<0)){return true;}return false;}else if(xoA-coodX<0 && xoB-coodX<0){if((yoA-coodY>0 && yoB-coodY>0) || (yoA-coodY<0 && yoB-coodY<0)){return true;}return false;}else{return false;}}这个函数原本是准备写到lufylegend中LMath静态类中的,参数原本是LPoint对象,但是这⾥可以⽤json,因为LPoint⾥的x,y属性可以写到json⾥,函数也就同样取得出值了。
游戏开发中经常用到的算法详解

游戏开发中经常用到的算法详解作为游戏开发人员,算法是我们必须掌握的技能之一。
无论是小型独立游戏还是大型 AAA 游戏,算法都扮演了至关重要的角色。
在这篇文章中,我将为大家详细介绍游戏开发中经常用到的算法,帮助大家深入掌握游戏开发的核心技术。
一、碰撞检测算法碰撞检测算法是游戏开发中常用的一种算法,它可以判断两个物体是否相互接触。
在游戏中,我们需要不断地检测物体之间的碰撞,以保证游戏场景的正常运作。
最常用的碰撞检测算法包括了 AABB 碰撞检测算法、圆形碰撞检测算法、多边形碰撞检测算法等。
其中,AABB 碰撞检测算法是最简单的一种算法,它通过对物体的包围盒进行检测来判断物体是否相互接触。
如果两个物体的包围盒相交,那么这两个物体就存在碰撞。
圆形碰撞检测算法则是通过计算两个圆心之间的距离来判断两个圆形是否相交。
多边形碰撞检测算法则是通过计算两个多边形边之间的相对位置来判断两个多边形是否相交。
二、路径搜索算法路径搜索算法是游戏中常用的一种算法,它可以帮助我们找到两个地点之间最短的路径。
在游戏中,我们经常需要让角色沿着特定的路径移动,这时就需要使用到路径搜索算法。
最常用的路径搜索算法包括了 A* 算法、Dijkstra 算法等。
其中,A* 算法比较常用,它采用启发式函数来估算当前节点到目标节点的距离,以此来选择下一个要遍历的节点。
三、随机数生成算法在游戏开发中,我们经常需要生成随机数来实现一些功能,比如道具掉落、怪物生成、随机地图等。
随机数生成算法是这种情况下必不可少的。
目前常用的随机数生成算法包括了 Linear Congruential Generator(线性同余法)、Mersenne Twister 等。
其中,Mersenne Twister 算法是目前被广泛使用和认可的一种算法,它有着优秀的随机性和均匀性。
同时,需要注意的是,在游戏中使用随机数时,我们需要遵循一定的规则,以保证游戏的可玩性和公平性。
碰撞检测算法研究综述

碰撞检测算法研究综述
碰撞检测是计算机图形学、游戏开发、机器人学等领域中的一个重要问题。
它的目的是确定两个或多个物体是否在空间中发生了碰撞,并计算碰撞的位置和碰撞力等信息。
碰撞检测算法可以分为两大类:离散碰撞检测和连续碰撞检测。
离散碰撞检测算法将物体表示为一组多边形,并通过比较多边形的顶点来判断是否发生碰撞。
这种方法简单易实现,但是精度较低,难以处理复杂的形状和运动。
连续碰撞检测算法则将物体表示为一个数学模型,如球体、胶囊体、凸包等,并通过计算模型之间的距离和夹角来判断是否发生碰撞。
这种方法精度较高,但是计算复杂度较高,难以处理大规模的场景。
此外,还有一些基于物理引擎的碰撞检测算法,它们基于物体的物理特性来计算碰撞,如动量守恒、能量守恒等。
这些算法可以更准确地模拟物体的碰撞行为,但是需要对物体的物理特性有深入的了解。
在实际应用中,选择合适的碰撞检测算法需要考虑多个因素,如场景的复杂程度、物体的形状和运动、计算效率和精度等。
近年来,随着计算机硬件技术的发展,碰撞检测算法的效率和精度都得到了显著提高,并在许多领域得到了广泛应用。
总的来说,碰撞检测算法是计算机图形学、游戏开发、机器人学等领域中的一个重要问题,需要不断地进行研究和改进。
汽车碰撞检测算法研究

汽车碰撞检测算法研究随着社会科技的发展,汽车作为生活中必不可少的交通工具已经成为了人类文明的重要组成部分。
然而,汽车在使用过程中,由于各种原因,很可能发生碰撞事故,给人们的生命财产带来极大的危害。
因此,汽车碰撞检测算法的研究和发展具有重要的现实意义和实际应用价值。
1. 算法概述汽车碰撞检测算法是一种基于图像处理和计算机视觉技术的先进技术。
其基本原理是通过处理输入的驾驶员的摄像头和传感器信息,判断当前汽车是否存在碰撞风险,并及时作出相应的预警和措施,保障人员生命安全和财产的利益。
2. 算法应用随着汽车碰撞检测算法的不断发展和成熟,其应用范围也越来越广泛。
一方面,汽车碰撞检测算法在汽车安全系统中得到了广泛应用,为汽车驾驶员提供了重要的保障;另一方面,汽车碰撞检测算法在交通管理领域也发挥了重要的作用,帮助交通部门更好地管理交通状况,减少交通事故的发生。
3. 算法发展趋势随着人工智能技术的不断进步,汽车碰撞检测算法也面临着新的挑战和机遇。
未来,汽车碰撞检测算法将更加广泛地应用于人们的生产和生活中,成为重要的智能化基础设施。
同时,汽车碰撞检测算法的性能和精度也将得到不断提升,更好地服务于社会和人民的需要。
4. 算法优化策略汽车碰撞检测算法的优化策略是提升其性能和实用价值的关键。
其中,人工智能技术的发展和应用是优化汽车碰撞检测算法的重要途径之一。
另外,不断优化算法的算法原理和模型设计、提高算法的可靠性和鲁棒性、加强算法的实时性和稳定性也是优化汽车碰撞检测算法的重要手段。
5. 总结汽车碰撞检测算法是现代交通技术的重要组成部分,具有重要的现实意义和实际应用价值。
随着算法的不断发展和优化,其应用范围将更加广泛,为人们的生产和生活提供更加安全、便利的交通服务。
因此,我们应该注重汽车碰撞检测算法的研究和应用,提高其性能和实用价值,为建设更加智慧、安全、高效的交通管理体系做出更大的贡献。
碰撞检测的原理及应用

碰撞检测的原理及应用1. 碰撞检测的概述碰撞检测是一项在计算机图形学、物理仿真、游戏开发等领域广泛应用的技术。
它的主要目的是为了判断两个或多个物体是否发生碰撞,以此来模拟真实世界中的物理规律。
碰撞检测可以用于实现物体间的交互、碰撞反应以及处理碰撞后的动作。
2. 碰撞检测的原理碰撞检测的基本原理是通过判断两个或多个物体的边界是否相交来确定是否发生碰撞。
常见的碰撞检测算法包括包围盒检测、精确碰撞检测等。
2.1 包围盒检测包围盒检测是碰撞检测中最简单和高效的一种方法。
它将物体看作是一个能够包围其边界的矩形框或球体,在进行碰撞检测时,只需要比较包围盒之间是否相交即可。
包围盒检测的优点是计算速度快,适用于大部分场景,但精度较低。
2.2 精确碰撞检测精确碰撞检测是一种更为准确的碰撞检测方法,它通过对物体的几何形状进行分析,计算出物体的碰撞点、碰撞面等信息。
常见的精确碰撞检测算法有光线投射、多边形碰撞、凸包碰撞等。
精确碰撞检测的优点是精度高,适用于复杂的场景,但计算量较大。
3. 碰撞检测的应用碰撞检测在各个领域有着广泛的应用。
以下是其中的几个例子:3.1 计算机游戏在计算机游戏中,碰撞检测用于处理角色间的碰撞、子弹与物体的碰撞、障碍物的碰撞等。
通过碰撞检测,游戏可以实现真实的物理效果,增加游戏的可玩性和真实感。
3.2 虚拟现实碰撞检测在虚拟现实中也有重要的应用。
通过检测用户与虚拟物体之间的碰撞,可以实现用户与虚拟世界的交互,提高虚拟现实的沉浸感。
3.3 工程建模在工程建模领域,碰撞检测可以用于模拟物体之间的碰撞情况,比如机械装配、构件安装等。
通过检测碰撞情况,可以预测错误、优化设计,提高工程效率。
3.4 交通仿真碰撞检测在交通仿真领域也有重要的应用。
通过检测车辆之间的碰撞,可以预测交通事故的发生情况,为交通规划和设计提供重要参考。
4. 总结碰撞检测作为一项重要的技术,可以实现物体间的交互、模拟真实世界中的物理规律,并在计算机游戏、虚拟现实、工程建模、交通仿真等领域发挥重要作用。
碰撞检测

碰撞1.碰撞检测和响应碰撞在游戏中运用的是非常广泛的,运用理论实现的碰撞,再加上一些小技巧,可以让碰撞检测做得非常精确,效率也非常高。
从而增加游戏的功能和可玩性。
2D碰撞检测2D的碰撞检测已经非常稳定,可以在许多著作和论文中查询到。
3D的碰撞还没有找到最好的方法,现在使用的大多数方法都是建立在2D基础上的。
碰撞检测碰撞的检测不仅仅是运用在游戏中,事实上,一开始的时候是运用在模拟和机器人技术上的。
这些工业上的碰撞检测要求非常高,而碰撞以后的响应也是需要符合现实生活的,是需要符合人类常规认识的。
游戏中的碰撞有些许的不一样,况且,更重要的,我们制作的东西充其量是商业级别,还不需要接触到纷繁复杂的数学公式。
最理想的碰撞,我想莫过于上图,完全按照多边形的外形和运行路径规划一个范围,在这个范围当中寻找会产生阻挡的物体,不管是什么物体,产生阻挡以后,我们运动的物体都必须在那个位置产生一个碰撞的事件。
最美好的想法总是在实现上有一些困难,事实上我们可以这么做,但是效率却是非常非常低下的,游戏中,甚至于工业中无法忍受这种速度,所以我们改用其它的方法来实现。
最简单的方法如上图,我们寻找物体的中心点,然后用这个中心点来画一个圆,如果是一个3D的物体,那么我们要画的就是一个球体。
在检测物体碰撞的时候,我们只要检测两个物体的半径相加是否大于这两个物体圆心的实际距离。
这个算法是最简单的一种,现在还在用,但是不是用来做精确的碰撞检测,而是用来提高效率的模糊碰撞检测查询,到了这个范围以后,再进行更加精密的碰撞检测。
一种比较精密的碰撞检测查询就是继续这种画圆的思路,然后把物体细分,对于物体的每个部件继续画圆,然后再继续进行碰撞检测,直到系统规定的,可以容忍的误差范围以后才触发碰撞事件,进行碰撞的一些操作。
有没有更加简单的方法呢?2D游戏中有许多图片都是方方正正的,所以我们不必把碰撞的范围画成一个圆的,而是画成一个方的。
这个正方形,或者说是一个四边形和坐标轴是对齐的,所以运用数学上的一些方法,比如距离计算等还是比较方便的。
碰撞检测算法范文

碰撞检测算法范文碰撞检测算法是计算机图形学中的一个重要问题,它用于检测两个或多个物体是否发生碰撞。
在游戏开发、虚拟现实、物理仿真等领域中都有广泛的应用。
这个问题可以通过多种算法来解决,下面将介绍几种常用的碰撞检测算法。
1.矩形边界框碰撞检测算法(AABB碰撞检测算法):矩形边界框是一种简单的表示物体边界的方式。
这个算法利用矩形边界框的位置和尺寸信息来判断两个物体是否相交。
如果两个矩形边界框相交,那么可以认为物体发生了碰撞。
这个算法的时间复杂度较低,适用于处理大量物体,但是对于复杂形状的物体可能存在误判。
2.圆形碰撞检测算法:圆形碰撞检测算法适用于处理圆形物体之间的碰撞。
它利用圆心之间的距离与两个圆的半径之和进行比较,如果距离小于或等于半径和,则认为两个圆发生了碰撞。
这个算法较为简单,但是只适用于处理圆形物体。
3.分离轴定理(SAT碰撞检测算法):分离轴定理是一种用于判断多边形之间是否发生碰撞的算法。
它基于一个原理:如果两个多边形没有共用的分离轴,则它们一定发生了碰撞。
分离轴定理需要判断多个分离轴是否存在,对于复杂形状的物体,计算量较大。
4.基于包围体的碰撞检测算法:基于包围体的碰撞检测算法是一种将物体用较简单的几何形状包围起来,然后对包围体进行碰撞检测的方法。
常见的包围体形状有球体、盒子、球树等。
这种算法可以大大减少需要进行精确碰撞检测的物体数量,以提高性能。
5.网格碰撞检测算法:网格碰撞检测算法适用于处理三维物体之间的碰撞。
它将物体分解为离散的小三角形网格,然后通过对网格之间的关系进行遍历检测碰撞。
这个算法对于复杂的三维物体具有较高的准确性,但是计算量较大。
综上所述,碰撞检测算法在计算机图形学中是一个非常重要且复杂的问题。
不同的算法适用于不同的场景和物体形状,开发人员需要根据具体需求选择合适的算法。
同时,随着计算机硬件的不断升级和算法的不断改进,碰撞检测算法也在不断发展,相信未来会出现更加高效和准确的算法来解决这个问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
高级碰撞检测及响应算法——碰撞检测2010-11-18 22:351.概述移动的物体可以由椭球体近似表达,这种椭球体更容易逼近类人和动物的形状,比如说人的头,就是一个X-Y-Z轴半径相等的椭球体,髋骨,盆骨等都可以较好地用椭球体体现出来。
多个椭球体组成的集合的形状也使它们易于在障碍物上平滑地移动,这一点在3D游戏中显得特别重要,因为玩家绝不希望在激烈的战斗中自己被卡在某个死角里不能动弹。
我们希望能在场景中来回移动我们的物体(或者角色)。
它可以由一个椭球体表现,其中椭球体的中心位置代表了角色的位置,半径向量则定义了椭球体沿三个轴向的尺寸。
见图3.1。
图3.1:椭球体的半径向量通过对角色施加某方向的力,他就能在场景世界中移动。
这个过程由速度向量(velocity vector)表示。
我们希望椭球体能够在场景世界中移动,那么它的新的位置等于它当前位置加上速度向量。
见图3.2。
图3.2:通过一个速度移动椭球体但是我们还不清楚我们是否能成功完成这个移动,因为可能在过程中会出现一些事情,例如组成场景世界的一个或者多个三角片挡住了椭球体的去路。
我们不可能事先准确地知道椭球体会撞上哪个三角片,所以我们应该检查所有的三角片(这里,可以将一个大的网格体化分成一个八叉树,这个八叉树被用来帮助我们检查那些靠近角色的三角片)。
同时,我们还不能在检测到一个可能碰撞的三角片后就立即停止检测,因为我们要检测出所有潜在的障碍,近而找出最近的那一个碰撞。
如果我们检测到了一个与三角片A发生的碰撞后就停止,而没有继续检测其它的三角片,例如三角片B,那么将发生如图3.3所示的情况,即三角片B比三角片A更先发生碰撞。
图3.3:必须检测所有的三角片碰撞检测过程应该为后继的响应阶段提供至少两个必要的信息:* 球体在场景中的碰撞位置。
* 球体发生碰撞之前,沿速度方向到碰撞点的距离。
所以,对于单个三角片的碰撞检测,我们首先要清楚是否会发生碰撞(这将产生一个bool值),如果发生了碰撞,算法应该能够为碰撞响应提供上述两个必要的信息。
2.单个三角片的检测在e空间中,有一个三角片,它由p1,p2和p3三个顶点所定义,它们以顺时钟排序。
另外有一个球体,它位于基点,basePoint,并正沿着它的速度方向运动,速度大小为velocity。
如果我们用t 作为自变量,用方程表达球体的运动过程,那么我们有球体的位置方程:在三维空间中,一个球体可以由它的位置和半径唯一表示(在e空间中半径是1)。
对于运动的球体,半径是常数但是位置是不断变化的。
上面的公式给出了球体在任何时刻t 的位置,这就是所谓的扫掠球(swept sphere)。
图3.4表示了这种关系,这一点很重要。
由于velocity的大小不清楚,但它与时间的乘积直接影响着扫掠球的位置,而扫掠球每次所作的检测只在一个velocity的长度范围内。
那么问题可以转化为:能否在一个[ 0,velocity ]范围内找到碰撞的情况,或者说能否在[0,1]的范围内,找到能满足碰撞特征的t值。
在此过程中,解二次方程所得到的t 值的情况,跟velocity 的大小有关,图3.9说明了这种关系。
图3.9:速度大小与碰撞的可能情况同时,对于当前扫掠球的位置而言,可能与它所面对的三角片发生5种关系。
具体来讲:*** 当VN=0时,此时球体平行于平面运动,球体中心到平面的距离要么为1,要么小于等于1。
对于前一种情况,检测提前退出;对于后一种情况,显然在t[0,1]范围内的所有球体位置中,球体与平面均保持相交。
*** 当VN不等于0时,此时球体总会与平面发生碰撞(前提是速度方向有正对平面正面的分量),其形式无非有4种。
第一种就是与三角片平面相交,但是不与三角片相交。
*** 球体与三角片内部某点相交。
*** 球体与三角片某顶点相交。
*** 球体与三角片某边缘相交。
图3.4:球体的位置方程算法的检测程序就从这里开始。
其功能是用检测函数将一个扫掠球信息体(空间速度与位置、碰撞是否发生、什么地方发生和发生距离等)与单个三角片信息体(主要是三个顶点坐标信息)进行碰撞检测。
并不断循环调用该函数,同时更换函数中的三角片信息体,使当前扫掠球与所有的三角片都被检测到,最后整理并填入扫掠球信息体中的碰撞信息,并在响应过程中更新速度与位置信息。
下面,第一个任务是检测扫掠球是否与三角片所在的平面相交。
如果不相交,扫掠球当然不会跟三角片相交。
所以我们构造一个平面,叫三角片平面trianglePlane,它是由三角片的三个顶点所确定的平面。
如果我们有单位化的平面法向量N和平面常数Cp,那么我们可以计算点p到平面的有符号距离(signed distance):图3.5可以看出该方法的原理。
图3.5:点p到平面的有符号距离的计算图中OP为p点的方向向量,图中OI线段是N•p的绝对值,Cp是ON段所表示的距离,两者之和为p点到三角片平面的符号距离。
之所以叫符号距离,是因为当点p位于三角片的正面区域(即法向量所指的一侧)时,该距离为正值;如果点p位于三角片的反面区域,该距离为负值。
如果扫掠球与三角片平面相交,如果速度大小刚好合适,那么总存在一个时刻t0,扫掠球刚好位于平面的“前边”(front side),此时扫掠球(中心点)到三角片平面的有符号距离刚好为1;如果速度足够大,则它会穿越三角片平面,在某时刻t1,它刚好位于平面"后边"(back side),则在时间t∈[t0,t1]上,扫掠球与平面处于相交状态。
那么我们可以这样计算时刻t0:时刻t1 是扫掠球到三角片平面的有符号距离刚好为-1时的时间点。
同样,我们可以得到t1:如果t0和t1都不在[0,1]的范围内,即不在一次扫掠检测范围内,那么我们可以知道在速度方向上,扫掠球没有(或者说还没有)跟平面相交,于是不可能与三角片相交。
否则,我们知道碰撞应该发生在时刻tcollisoin∈[t0,t1]。
注意有一个特殊情况,如果N*velocity=0——那么我们不能使用上面的公式。
但是这种情况在什么时候发生呢?它发生在速度向量垂直于平面法向量,或者说球体平行于平面运动的时候。
这种情况下,有两种可能,一种是从basePoint点到三角片平面的绝对距离小于1,即嵌入三角片平面中。
如果是这样,我们直接将变量设为:t0=0、t1=1,那么扫扫掠球将在一次检测范围内总是与平面相交。
另一种是绝对距离大于1,那么我们知道碰撞不可能发生,可以提前结束检测。
既然我们知道了两个时刻t0和t1的值(可能两个值相同),那么出现了三种潜在的碰撞情况:* 在三角片内碰撞。
* 与三角片其中一个顶点碰撞。
* 与三角片其中一条边缘碰撞。
3.三角片内碰撞这种碰撞情况最常见(当然取决于三角片的面积),如果扫掠球确实在三角片内部相交,那么可以说与顶点或者边缘的碰撞几率将变得很小,所以如果我们能快速地检测出发生在三角片内的碰撞,那么我们将节约大量的用于检测发生在顶点或者边缘的碰撞情况的时间。
所以,我们先看这种情况。
注意,这种情况只会发生在球体并没有嵌入平面的时候,即N*velocity≠0时。
一个嵌入到平面的球体只可能与顶点或者边缘碰撞,就像游泳的人只能撞到岛屿的边缘或者顶角一样。
这里,主要计算出平面上的球体的接触点,我们将它叫作planeIntersectionPoint。
我们已经知道接触发生在时刻t0,该时刻是球体位于平面前边的临界时刻,但是这个接触点究竟在平面上哪个位置?这个平面接触点用如下的公式计算:图3.6解释了这个公式的具体意义。
球体上首先撞击平面的点由basePoint-planeNormal给出,接触点发生在时刻t0。
图3.6:三角片平面上的交点现在我们要做的就是检查planeIntersectionPoint是否在三角片内部。
有很多种函数方法完成这个功能。
如果点在三角片内,那么我们得到了碰撞检测的结论:* 三角片平面上的交点就是三角片内的碰撞点,intersectionPoint=planeIntersectionPoint* 速度方向上,当前位置与发生碰撞的位置之间的距离,intersectionDistance=t0*|velocity|4.扫掠测试(the sweep test)如果球体没有碰撞三角片内部,那么我们不得不进行扫掠测试,从而判断是否与三角片的顶点或者边缘碰撞。
这种情况下,主要的问题是检查是否存在一个时刻t,t∈[t0,t1]。
在这个时刻点,扫掠球与顶点或者边缘发生了碰撞。
我们先看两种最简单的情况——扫掠球与一个顶点p碰撞。
扫掠球与顶点的碰撞发生在什么时候呢?如果扫掠球中心与顶点之间的距离为1,那么认为两者发生了碰撞。
为了便于计算,当球中心与顶点中心的距离的平方是1时发生碰撞。
我们可以先定义一个等式:上面的式子可以化为一个二次方程的形式:这里,二次方程通常有两个解,这在此例中是有意义的。
扫掠球与顶点的距离为1的时间点可能有两个——三角片的正面与反面都存在这个时间点。
我们关心的是与顶点的第一个碰撞(或者说最先与之发生的碰撞),所以我们取最小值(因为解就是碰撞的时间值)。
如果有了合法的最小解x1,那么我们所需的交点数据可以得到:intersectPoint = pintersectionDistance=x1*|velocity|即使与顶点发生了碰撞,我们仍然要检测三角片的边缘,看是否可能在更短的时间点时,与某一个片边缘发生了碰撞。
这种检测比检测顶点碰撞更复杂,但是在本质上是一样的。
考虑由p1到p2的边缘,令首先我们检测是否存在某时间点,扫掠球与一条沿着边缘方向的直线(infinite line)发生碰撞。
这种情况发生在扫描球中心与无穷线的距离为1时。
图3.7描述了这种情况。
图3.7:扫掠球与边缘所在直线碰撞这个关系也可以得到一个二次方程,其中的方程变量系数为:如果该方程有最小值x1,那么我们知道扫掠球会与直线相交于同一点,但是我们还不知道这个点是否在三角边的边缘线段内。
所以,如果我们用函数 f 来描述直线L,使得L(f0),那么L(0)=p1,L(1)=p2,图3.8说明了f0的意义。
图3.8:判断交点是否在边缘线段内于是我们可以在直线上能过计算f0 判断交点是否在边缘线段内:如果f0∈[0,1],那么交点在边缘线段中,并且在时刻x1球碰撞了三角片的边缘。
有关交点的数据如下:intersectionPoint=p1+f0*edgeintersetionDistance=x1*|velocity|5.总结以上就是碰撞检测部分的全部内容。
总结一下整个流程:* 首先计算三角片平面* 然后找出扫掠球与三角片平面相交的时间点t0和t1* 接下来检测发生在三角片内部的碰撞。