`

基于2D多边形的碰撞检测和响应(三)

阅读更多

三、对快速移动的物体做进一步扩展

上述方法处理慢速移动物体时会取得非常好的效果。但是当物体移动的非常快时,碰撞系统将失去准确性,丢失碰撞,或者允许物体之间相互穿越,这可不是我们所期望的。
这里我们还是使用分离坐标轴的方法,并进一步扩展,并使用该算法检测未来某时刻的碰撞和交叠。
原理还是相同的,可以使用下面的图片解释:

现在需要使用投影数学。如果投影间隔没有相交,将速度投影到分离轴上,并计算两个间隔的碰撞时间。
相对于静态分离轴算法,我们需要测试一个扩展的轴。显然这个是速度矢量轴。
那么我们现在有3个选择:
1. 间隔交叠
2. 间隔不相交,但是将在未来某个时刻发生碰撞
3. 间隔不相交,并且不会在未来发生碰撞
第三种可能性意味着物体不会在该帧处发生碰撞,而且分离轴真正分离了物体。因此物体不会发生碰撞。
AxisSeparatePolygons()函数将反映这种现象,并返回重叠量或者碰撞时间。为了区别两者,当检测到交叠时,将返回一个负值。如果检测到未来的碰撞,将返回一个正值。该函数看起来如下:

bool AxisSeparatePolygons(Vector Axis, Polygon A, Polygon B, Vector Offset, Vector Vel, float& t, float tmax);

这里Offset是多边形A和多边形B之间的相对距离,并且Vel是多边形A相对于多边形B的相对速度。
求解碰撞平面的算法与MTD非常相似。只是碰撞将优于交叠,如果检测到未来的碰撞,将选择最新的一个。
如果没有发现碰撞并且只检测到了交叠,那么就像以前一样,选择交叠最小的那个轴。
碰撞检测函数将返回碰撞的法向,还有碰撞的深度(负值)和碰撞时间(正值)之一。最后的伪代码如下…

bool Collide(   const Vector* A, int Anum,
const Vector* B, int Bnum,
const Vector& xOffset, const Vector& xVel,
Vector& N, float& t)
{
if (!A || !B) return false;

// All the separation axes
// note : a maximum of 32 vertices per poly is supported
Vector xAxis[64];
float taxis[64];
int iNumAxes=0;

xAxis[iNumAxes] = Vector(-xVel.y, xVel.x);
float fVel2 = xVel * xVel;
if (fVel2 > 0.00001f)
{
if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))
return false;
iNumAxes++;
}

// test separation axes of A
for(int j = Anum-1, i = 0; i < Anum; j = i, i ++)
{
Vector E0 = A[j];
Vector E1 = A[i];
Vector E = E1 - E0;
xAxis[iNumAxes] = Vector(-E.y, E.x);

if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))
return false;

iNumAxes++;
}

// test separation axes of B
for(int j = Bnum-1, i = 0; i < Bnum; j = i, i ++)
{
Vector E0 = B[j];
Vector E1 = B[i];
Vector E = E1 - E0;
xAxis[iNumAxes] = Vector(-E.y, E.x);

if (!IntervalIntersect( A, Anum, B, Bnum, xAxis[iNumAxes], xOffset, xVel, taxis[iNumAxes], t))
return false;
iNumAxes++;
}

if (!FindMTD(xAxis, taxis, iNumAxes, N, t))
return false;

// make sure the polygons gets pushed away from each other.
if (N * xOffset < 0.0f)
N = -N;

return true;
}

bool AxisSeparatePolygons ( Vector N, Polygon A, Polygon B, Vector Offset, Vector Vel, float &t, float tmax)
{
float min0, max0;
float min1, max1;

CalculateInterval(N, A, min0, max0);
CalculateInterval(N, B, min1, max1);

float h = Offset dot N;
min0 += h;
max0 += h;

float d0 = min0 - max1; // if overlapped, do < 0
float d1 = min1 - max0; // if overlapped, d1 > 0

// separated, test dynamic intervals
if (d0 > 0.0f || d1 > 0.0f)
{
float v = Vel dot N;

// small velocity, so only the overlap test will be relevant.
if (fabs(v) < 0.0000001f)
return false;

float t0 =-d0 / v; // time of impact to d0 reaches 0
float t1 = d1 / v; // time of impact to d0 reaches 1
// sort the times.
if (t0 > t1)
{
float temp = t0;
t0 = t1;
t1 = temp;
}
// take the minimum positive
taxis = (t0 > 0.0f)? t0 : t1;

// intersection time too late or back in time, no collision
if (taxis < 0.0f || taxis > tmax)
return true;

return false;
}
else
{
// overlap. get the interval, as a the smallest of |d0| and |d1|
// return negative number to mark it as an overlap
taxis = (d0 > d1)? d0 : d1;
return false;
}
}


bool FindCollisionPlane (Vector* Axis, float* taxis, int iNumAxes, Vector& Ncoll, float& tcoll)
{
// find collision first
int mini = -1;
tcoll = 0.0f;
for(int i = 0; i < iNumAxes; i ++)
{
if (taxis[i] > 0.0f)
{
if (taxis[i] > tcoll)
{
mini = i;
tcoll = taxis[i];
Ncoll = Axis[i];
Ncoll.Normalise(); // normalise axis
}
}
}

// found a collision
if (mini != -1)
return true;

// nope, find overlaps
mini = -1;
for(int i = 0; i < iNumAxes; i ++)
{
float n = Axis[i].Normalise(); // axis length

taxis[i] /= n; // normalise interval overlap too

// remember, those numbers are negative, so take the closest to 0
if (mini == -1 || taxis[i] > tcoll)
{
mini = i;
tcoll = taxis[i];
Ncoll = Axis[i];
}
}

return (mini != -1);
}

现在,你拥有了一个可以检测未来碰撞的的检测系统,或者当重叠的时候,返回碰撞平面和碰撞深度/时间
分享到:
评论

相关推荐

    2D多边形碰撞算法及示例

    通过实践和理解这些概念,我们可以构建出高效且准确的2D多边形碰撞检测系统。"Polygon collision"压缩包中的资源可能包含了详细教程、源代码示例以及用OpenGL实现的动画展示,帮助读者更直观地理解和应用这些理论...

    基于OpenGL的碰撞检测源程序

    在这个基于OpenGL的碰撞检测源程序中,我们关注的核心是游戏开发和模拟中的一个重要概念:如何确定两个或多个对象是否在空间中相遇或相交,即碰撞检测。 碰撞检测在许多应用中至关重要,例如视频游戏、物理模拟和...

    二维多边形碰撞检测

    二维多边形碰撞检测是计算机图形学中的一个重要概念,尤其在游戏...总之,二维多边形碰撞检测是一个涉及几何、算法和编程技术的综合问题。通过学习和实践,开发者可以创建出更加真实的2D游戏环境,提高玩家的游戏体验。

    基于QT的C++的碰撞检测

    总的来说,这个项目展示了如何结合QT框架和C++来实现一个交互式的碰撞检测系统,允许用户通过鼠标滚轮动态调整视角,从而观察和分析碰撞情况。这涉及到图形用户界面的设计、事件处理、几何形状的碰撞检测算法以及2D...

    Cocos2d-x碰撞检测原理与英雄要打死怪物--之游戏开发《赵云要格斗》

    Box2D提供了一个强大的多边形碰撞检测系统,可以创建具有不同形状(如圆形、多边形)的物理体,并通过模拟真实世界的物理规则来检测碰撞。在Cocos2d-x中,你可以通过集成Box2D并创建`CCPhysicsWorld`,然后为每个...

    cocos2d-x游戏碰撞检测(中文翻译)毕设也肯定用的上

    - **精确形状碰撞检测**:对于更复杂的形状,如圆形、多边形,可以使用`b2World`提供的Box2D物理引擎进行精确的碰撞检测。 3. **Box2D物理引擎**: Box2D是cocos2d-x中集成的2D物理引擎,提供了强大的碰撞检测...

    2D碰撞实现-Demo

    2D碰撞检测的基本原理是基于几何形状的相互检验。常见的2D几何形状有矩形、圆形和多边形等。在室内碰撞的场景中,我们通常会遇到房间、家具等由矩形或多边形定义的障碍物。以下是一些关键的碰撞检测方法: 1. **轴...

    碰撞检测 有关C++

    5. **碰撞检测库**:在C++中,有许多现成的碰撞检测库,如Bullet、Box2D和Ogre3D等,它们提供了丰富的接口和功能,能快速实现各种碰撞检测需求。 6. **优化技巧**:为了提升性能,可以使用启发式方法,如动态优先...

    物理碰撞检测实例

    cocos2d-x 3.0的物理引擎提供了两种主要的碰撞检测方法:基于距离的检测和基于固定时间步长的检测。基于距离的检测会在每次更新时检查所有可能的碰撞,这种方法精度高但效率较低。而基于固定时间步长的检测则是在每...

    2D-Polygon-Collision-Detection

    接着,我们可以采用分离轴定理(Separating Axis Theorem, SAT),这是一种广泛应用于2D多边形碰撞检测的算法。该定理基于一个核心思想:如果两个多边形不相交,那么存在一个轴使得两个多边形的投影在该轴上没有重叠...

    Tiled Map中使用碰撞检测

    本篇文章将深入探讨如何在基于Tiled Map的游戏中实现碰撞检测,特别是使用cocos2d框架。cocos2d是一个强大的开源游戏引擎,广泛应用于iOS和Android平台,对于iPhone游戏开发尤其适用。 首先,我们需要理解Tiled Map...

    cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    cocos2d-x提供了一些内置的几何形状类,如`CCRect`(矩形)和`CCPolygon`(多边形),用于表示游戏对象的边界,并提供了相应的碰撞检测方法。对于坦克这类基本为矩形的物体,我们可以使用`CGRectIntersectsRect()`...

    xna中的碰撞检测

    本资源重点讲解如何在2D环境中实现碰撞检测,这对于创建像《超级玛丽》这样的平台跳跃游戏或者简单的弹球游戏至关重要。 首先,我们需要理解碰撞检测的基本概念。碰撞检测是指在游戏世界中,判断两个或多个物体是否...

    人物移动和碰撞检测

    在游戏开发中,人物移动和碰撞检测是两个至关重要的技术环节。它们决定了游戏中的角色如何在虚拟世界中行动,以及如何与环境互动。本资源包含了人物移动算法和碰撞检测技术的相关资料,帮助开发者深入理解并实现这些...

    ActionScript碰撞检测封装类

    2. **精确碰撞检测**:对于更复杂的形状,如圆形、多边形,可以使用更精确的算法,如分离轴定理(Separating Axis Theorem,SAT)或旋转包容体(Rotated Bounding Box,RBB)。这些算法能够处理不规则形状,并且在...

    cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理

    在cocos2d-x中,可以为每个游戏对象创建一个物理身体,设置其形状(如圆形、多边形等),并开启物理引擎进行实时碰撞检测。当发生碰撞时,会触发相应的物理碰撞事件。 在处理子弹与坦克的碰撞时,我们需要创建一个...

    OpenGL碰撞检测

    在这个系统中,我们使用OpenGL来实现图形的绘制,并结合碰撞检测算法来判断三维空间中的物体是否发生相互接触。 首先,我们要理解碰撞检测的基本概念。碰撞检测通常分为两个阶段:包围体检测和精确碰撞检测。包围体...

    碰撞检测源代码,欢迎下载,学习物理引擎的比较有用

    碰撞检测主要目的是确定两个或多个对象在三维空间中的相互位置,判断它们是否发生接触或者接近到足以影响彼此的行为。这种技术广泛应用于游戏中的角色碰撞、物体交互、物理模拟等方面。源代码则能够帮助开发者深入...

    opengl 碰撞检测

    OpenGL碰撞检测是计算机图形...总的来说,OpenGL碰撞检测是一个涉及几何、变换、算法和响应处理的综合过程。理解和掌握这个技术,不仅可以提升你的编程技能,还能帮助你在创建交互式3D应用时做出更加真实和动态的效果。

    cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测

    cocos2d-x提供了`CCRect`类用于矩形碰撞检测,而对于更复杂的形状,可以使用`CCPolygon`类进行多边形碰撞检测。 3. **碰撞检测算法**:cocos2d-x框架内嵌了基本的碰撞检测方法,如矩形与矩形、矩形与多边形的碰撞。...

Global site tag (gtag.js) - Google Analytics