2d胶囊体碰撞检测算法

合集下载

二维碰撞判断方法

二维碰撞判断方法

二维碰撞判断方法全文共四篇示例,供读者参考第一篇示例:在游戏开发和计算机图形学中,碰撞检测是一项非常重要的技术,它用于确定两个或多个物体是否发生了碰撞。

二维碰撞检测方法是指在二维平面中判断两个物体是否相交或者相撞的技术。

本文将介绍几种常用的二维碰撞判断方法,并探讨它们的优缺点以及适用场景。

1. 基于边界框的碰撞检测基于边界框的碰撞检测是一种简单而高效的碰撞检测方法。

其基本思想是使用矩形或者其他简单形状的边界框来包围每个物体,然后检查这些边界框是否相交来判断物体是否发生了碰撞。

由于矩形之间的相交检测非常高效,因此这种方法在实时碰撞检测和大规模场景中得到了广泛应用。

由于边界框并不能完全准确地描述物体的形状,因此在一些情况下会产生误判。

2. 分离轴定理分离轴定理是一种准确而复杂的碰撞检测方法。

其基本思想是通过寻找两个物体之间的分离轴,来判断它们是否相交。

如果存在一条分离轴使得两个物体在这个轴上投影不重叠,则可以确定它们不相交。

尽管这种方法可以准确地检测出碰撞,但是需要进行复杂的数学计算,并且在处理复杂形状的物体时性能较低。

3. 面向像素的碰撞检测面向像素的碰撞检测是一种基于像素级别的碰撞检测方法。

其基本思想是将每个物体表示为一个像素矩阵,然后检查这些像素矩阵是否重叠来判断物体是否发生了碰撞。

这种方法可以非常准确地检测碰撞,但是对于大规模场景或者复杂形状的物体来说,计算成本会非常高昂。

4. 几何算法碰撞检测几何算法碰撞检测是一种基于几何形状的碰撞检测方法。

其基本思想是通过计算物体的几何属性来判断它们是否相交。

这种方法可以准确地检测出碰撞,并且对于复杂形状的物体也有较好的适应性。

由于需要进行复杂的几何计算,因此性能较差。

不同的二维碰撞检测方法各有优缺点,适用于不同的场景和要求。

在实际开发中,可以根据具体情况选择合适的碰撞检测方法,或者结合多种方法来达到更好的效果。

在未来,随着计算机硬件和算法的不断发展,相信会有更多高效、准确的二维碰撞检测方法被提出,并得到应用。

碰撞检测算法研究综述

碰撞检测算法研究综述

碰撞检测算法研究综述
碰撞检测是计算机图形学、游戏开发、机器人学等领域中的一个重要问题。

它的目的是确定两个或多个物体是否在空间中发生了碰撞,并计算碰撞的位置和碰撞力等信息。

碰撞检测算法可以分为两大类:离散碰撞检测和连续碰撞检测。

离散碰撞检测算法将物体表示为一组多边形,并通过比较多边形的顶点来判断是否发生碰撞。

这种方法简单易实现,但是精度较低,难以处理复杂的形状和运动。

连续碰撞检测算法则将物体表示为一个数学模型,如球体、胶囊体、凸包等,并通过计算模型之间的距离和夹角来判断是否发生碰撞。

这种方法精度较高,但是计算复杂度较高,难以处理大规模的场景。

此外,还有一些基于物理引擎的碰撞检测算法,它们基于物体的物理特性来计算碰撞,如动量守恒、能量守恒等。

这些算法可以更准确地模拟物体的碰撞行为,但是需要对物体的物理特性有深入的了解。

在实际应用中,选择合适的碰撞检测算法需要考虑多个因素,如场景的复杂程度、物体的形状和运动、计算效率和精度等。

近年来,随着计算机硬件技术的发展,碰撞检测算法的效率和精度都得到了显著提高,并在许多领域得到了广泛应用。

总的来说,碰撞检测算法是计算机图形学、游戏开发、机器人学等领域中的一个重要问题,需要不断地进行研究和改进。

胶囊和凸多边形的动态碰撞检测

胶囊和凸多边形的动态碰撞检测

胶囊和凸多边形的动态碰撞检测在使用广义碰撞阶段迅速排除了大量物体以后,将会使用精确到多边形级别的精确碰撞,比如两个凸包之间的碰撞,凸包和面片之间的碰撞,以及2次曲面和多边形面片的碰撞,在游戏中常用的两次曲面有,椭圆体,圆柱体,胶囊,球体等等。

对于两个凸包之间的碰撞算法目前比较流行的是SAT,分离轴测试算法可以静态和动态的计算出两个凸包之间的碰撞时间法向量等等。

但是对于面数较多的凸包以及2次曲面却不大适合,此时一般使用GJK算法但是GJK算法本身强壮性的实现问题一直是一个较难的问题。

在我的一项使用BSP进行碰撞检测的实验中,人物以胶囊来模拟,房屋内部通过非SOLID 的LEAFY BSP来构造,在使用BSP剔除了大量面片以后,遇到这样一个问题:如何在最后筛选下的三角形面片进行碰撞测试,以确定碰撞发生的时间,法向量等。

本文提出一种简单,易懂,准确的方法用来确定一个以速度v前进的胶囊和一个凸多边形第一次发生碰撞的时间。

首先一个胶囊是所有到某根线段的距离等于某个值r的点的集合:如图:虚线表示该线段这里以ab表示,r代表所有点到该线段的长度;首先观察静态情况下的碰撞情况。

当一个多边形面片和胶囊碰撞的时候,实际上是该多边形面片中存在一些点,这些点到线段ab的距离小于了r,这是因为在胶囊外部的点到线段ab的距离均大于r(胶囊是所有到某根线段的距离等于某个输r的点的集合)。

所以在两个物体都静止的情况下相交测试实际上是测试线段ab到多边形的最短距离,如果该距离<r那么存在碰撞,否则不存在碰撞:如图这里以一个三角形为例子,左图中该三角形的所有点到线段ab的距离均大于r所以和该胶囊不相交,而右图中三角形的黑色区域中的点到线段ab的距离小于r所以该三角形和胶囊相交。

所以实际上只要计算一条线段到某个多边形的距离,然后和r作比较就可以知道是否发生碰撞。

而一条线段和一个多边形的距离计算,需要分以下几个步骤(以三角形为例)A将线段ab的2个端点投影到三角形所在平面,并检查投影点是否落在三角形内部,如果是的话将该投影距离作为一个候选值B分别计算线段ab和三角形的三条边的最短距离点对,并检查该点对中的点是否落在线段中(ab线段和三角形的边线段中)如果是的话将该点对的距离作为一个候选值。

“等一下,我碰!”——常见的2D碰撞检测

“等一下,我碰!”——常见的2D碰撞检测

“等⼀下,我碰!”——常见的2D碰撞检测转⾃:https://aotu.io/notes/2017/02/16/2d-collision-detection/在 2D 环境下,常见的碰撞检测⽅法如下:外接图形判别法轴对称包围盒(Axis-Aligned Bounding Box),即⽆旋转矩形。

圆形碰撞圆形与矩形(⽆旋转)圆形与旋转矩形(以矩形中⼼点为旋转轴)光线投射法分离轴定理其他地图格⼦划分像素检测下⽂将由易到难的顺序介绍上述各种碰撞检测⽅法:外接图形判别法 > 其他 > 光线投射法 > 分离轴定理。

另外,有⼀些场景只要我们约定好限定条件,也能实现我们想要的碰撞,如下⾯的碰壁反弹:当球碰到边框就反弹(如x/y轴⽅向速度取反)。

if(ball.left < 0 || ball.right > rect.width) ball.velocityX = -ball.velocityXif(ball.top < 0 || ball.bottom > rect.height) ball.velocityY = -ball.velocityY再例如当⼀个⼈⾛到100px位置时不进⾏跳跃,就会碰到⽯头等等。

因此,某些场景只需通过设定到适当的参数即可实现碰撞检测。

外接图形判别法轴对称包围盒(Axis-Aligned Bounding Box)概念:判断任意两个(⽆旋转)矩形的任意⼀边是否⽆间距,从⽽判断是否碰撞。

算法:rect1.x < rect2.x + rect2.width &&rect1.x + rect1.width > rect2.x &&rect1.y < rect2.y + rect2.height &&rect1.height + rect1.y > rect2.y两矩形间碰撞的各种情况:在线运⾏⽰例(先点击运⾏⽰例以获取焦点,下同):缺点:相对局限:两物体必须是矩形,且均不允许旋转(即关于⽔平和垂直⽅向上对称)。

2D游戏中常见的碰撞检测处理(仅碰撞体)【持续更新】

2D游戏中常见的碰撞检测处理(仅碰撞体)【持续更新】

2D游戏中常见的碰撞检测处理(仅碰撞体)【持续更新】写在前⾯嗯...打算开始每天写点啥了,不知道能坚持多久。

准备以⼀周为单位来进⾏更新,周⼀~周三写⼀些图形⽅⾯的内容,四~六是和图形没有什么太⼤关联的内容(意会就好),周⽇作为⼀个更新重点试着写⼀些乱七⼋糟的东西。

那么就这样开始更新了w~在现今的游戏中,碰撞检测可以说是⼀个基础的不能再基础的技术。

它关乎能否正确判断玩家的攻击有没有击中⽬标,判断玩家有没有踩在地板上,判断某两个物体有没有碰撞在⼀起,进⽽衍⽣出其它的各种⾏为。

⽽碰撞检测是建⽴在碰撞体上的。

碰撞体是对⼀个物体“边界”的确切描述,它描述了每个需要进⾏碰撞检测的物体的边界,并依靠数学⽅法判断这些边界是否相交,进⽽产⽣碰撞检测的结果。

(“⽼鹰⽤⽖⼦抓到了兔⼦”)如上图所⽰,代表⽼鹰⽖⼦的两个蓝⾊圆和代表兔⼦的淡黄⾊圆“相交”了,由此我们判定鹰抓到了兔⼦,进⾏⼀系列的后续操作。

在这个过程中,我们不在意鹰的⽖⼦具体是什么样⼦的,⽽只在意它的边界在哪⾥。

在这个例⼦中,边界就是⼀个单纯的圆形。

在电⼦游戏发展早期,碰撞体和实际的轮廓之间还存在着巨⼤的差异,只是能够概括其⼤概的边界⽽已。

尽管现在我们有许多丰富的⼿段来让我们的碰撞体尽可能的接近真实的外形,但多数情况下并不会这么做——归根结底,这么做没给游戏的真实程度带来什么太⼤的提升,反⽽还糟蹋了游戏的运⾏速度。

那让我们从⼀个最基本的开始吧。

1)圆形碰撞体圆形碰撞体可以说是最简单的⼀种碰撞体,其计算速度也是最快的,算法也⾮常容易理解。

回想⼀下初中数学中关于两圆“相交”的定义:两圆圆⼼的距离⼤于半径和,我们就可以按照它来判断两圆是否相交。

1bool IsHit(double x1, double y1, double x2, double y2, double r1, double r2)2 {3//勾股定理4return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) < (r1+r2)*(r1+r2);5 }它也可以⾮常⽅便的扩展到三维球。

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法【最新版】目录1.2D 胶囊体碰撞检测算法的概述2.2D 胶囊体碰撞检测算法的原理3.2D 胶囊体碰撞检测算法的实现步骤4.2D 胶囊体碰撞检测算法的优缺点5.2D 胶囊体碰撞检测算法的应用案例正文一、2D 胶囊体碰撞检测算法的概述2D 胶囊体碰撞检测算法是一种用于检测两个二维胶囊体是否发生碰撞的算法。

在这个算法中,胶囊体被视为具有一定大小和形状的物体。

这种算法广泛应用于计算机图形学、物理模拟等领域,尤其在游戏开发中具有重要意义。

二、2D 胶囊体碰撞检测算法的原理2D 胶囊体碰撞检测算法的核心思想是计算两个胶囊体的边界框(bounding box)之间的交点。

具体来说,首先需要计算出每个胶囊体的边界框,然后判断这两个边界框是否存在交点。

如果存在交点,那么就说明两个胶囊体发生了碰撞。

三、2D 胶囊体碰撞检测算法的实现步骤1.计算胶囊体的边界框:对于一个具有中心点(x, y)和半径 r 的圆形胶囊体,其边界框为矩形,左上角坐标为 (x - r, y - r),右下角坐标为 (x + r, y + r)。

2.判断边界框是否存在交点:可以通过计算两个边界框的交点来判断它们是否发生碰撞。

如果两个边界框的交点数量大于 0,则说明两个胶囊体发生了碰撞。

3.计算交点:可以通过计算两个矩形的交点来实现。

首先计算两个矩形的左上角坐标和右下角坐标,然后对这些坐标进行插值,得到交点的坐标。

四、2D 胶囊体碰撞检测算法的优缺点优点:1.计算简单,易于实现。

2.可以快速检测胶囊体之间的碰撞。

缺点:1.对于非矩形边界框的胶囊体,需要进行额外的计算。

2.对于一些特殊情况,如胶囊体之间存在嵌套关系时,算法可能失效。

五、2D 胶囊体碰撞检测算法的应用案例1.游戏开发:在游戏中,角色和怪物通常用胶囊体表示,通过 2D 胶囊体碰撞检测算法可以判断角色和怪物是否发生碰撞,从而实现游戏的基本功能。

2.物理模拟:在物理模拟中,物体之间的碰撞检测通常采用 2D 胶囊体碰撞检测算法,以计算物体间的相互作用。

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法2D胶囊体碰撞检测算法是一种用于计算机图形学和物理仿真中的算法,用于检测和处理胶囊体(由两个半径不同的圆柱体组成)之间的碰撞。

本文将逐步解释2D胶囊体碰撞检测算法的原理、实现和应用。

第一步:胶囊体模型在讨论碰撞检测算法之前,我们首先需要了解胶囊体的基本概念和数学模型。

胶囊体由两个半径不同的圆柱体组成,其中一个是胶囊体的主体,而另一个是在主体两端延伸,形成胶囊体的两个半球形末端。

胶囊体可以用以下参数来表示:1. 中点(Capsule Center):胶囊体主体的中点坐标。

2. 方向(Capsule Direction):表示胶囊体主体的朝向,可以是一个单位向量。

3. 高度(Capsule Height):表示胶囊体主体的高度。

4. 半径(Capsule Radius):胶囊体主体和末端的半径。

第二步:胶囊体碰撞检测算法原理胶囊体碰撞检测的目标是判断两个胶囊体是否发生碰撞,如果发生碰撞,则需要计算出碰撞点和碰撞法线。

胶囊体碰撞检测算法的基本原理如下:1. 计算两个胶囊体的最短距离:通过计算两个胶囊体中心之间的距离,可以判断是否发生碰撞。

如果两个胶囊体的距离小于它们半径之和,则发生碰撞;如果距离大于等于它们半径之和,则没有碰撞。

2. 确定碰撞点:如果胶囊体发生碰撞,我们还需要计算碰撞点的位置。

碰撞点可以通过以下步骤确定:a. 计算两个胶囊体之间的最近点:首先,我们需要计算出两个胶囊体之间的最近点。

可以通过将两个胶囊体视为线段,并使用线段相交检测算法来找到最近的点。

b. 确定碰撞点位置:根据最近点和两个胶囊体的半径,可以确定碰撞点的位置。

具体来说,碰撞点位于最近点沿相交线段的方向移动两个胶囊体半径之和。

3. 确定碰撞法线:碰撞法线是垂直于碰撞点的方向向量。

可以通过以下步骤确定碰撞法线:a. 计算碰撞点到两个胶囊体中心的向量:通过将碰撞点位置减去两个胶囊体中心的位置,可以得到两个向量。

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

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

高级碰撞检测及响应算法——碰撞检测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值),如果发生了碰撞,算法应该能够为碰撞响应提供上述两个必要的信息。

碰撞检测

碰撞检测

二维碰撞检测算法碰撞检测(Collision Detection,CD)也称为干涉检测或者接触检测,用来检测不同对象之间是否发生了碰撞,它是计算机动画、系统仿真、计算机图形学、计算几何、机器人学、CAD\ CAM等研究领域的经典问题。

碰撞物体可以分为两类:面模型和体模型。

面模型是采用边界来表示物体,而体模型则是使用体元表示物体。

面模型又可根据碰撞后物体是否发生形变分为刚体和软体,刚体本身又可根据生成方式的不同分为曲面模型和非曲面模型。

目前对于碰撞的研究多集中于面模型的研究,因为体模型是一种三维描述方式,对它进行碰撞检测代价较高。

而在面模型的研究中,对刚体的研究技术更为成熟。

下面列举几种常用的碰撞检测技术:1:包围盒(bounding box)是由Clark提出的,基本思想是使用简单的几何形体包围虚拟场景中复杂的几何物体,当对两个物体进行碰撞检测时,首先检查两个物体最外层的包围盒是否相交,若不相交,则说明两个物体没有发生碰撞,否则再对两个物体进行检测。

基于这个原理,包围盒适合对远距离物体的碰撞检测,若距离很近,其物体之间的包围盒很容易相交,会产生大量的二次检测,这样就增大了计算量。

包围盒的类型主要有AABB(Aligned Axis Bounding Box)沿坐标轴的包围盒、包围球、OBB(Oriented Bounding Box)方向包围盒和k-DOP(k Discrete Orientation Polytopes)离散方向多面体等。

AABB是包含几何对象且各边平行于坐标轴的最小六面体,两个AABB包围盒相交当且仅当它们三个坐标轴上的投影均重叠,只要存在一个方向上的投影不重叠,那么它们就不相交。

AABB间的相交测试和包围体的更新速度比其他算法效率高,因此使用最广泛,尤其适用于多物体运动的大规模环境和变形体碰撞检测。

OBB包围盒的相交测试基于分离轴的理论的,它的构造关键在于包围盒最佳方向的确定,最佳方向必须保证在该方向上包围盒的尺寸最小。

机器鱼2D仿真平台碰撞检测算法

机器鱼2D仿真平台碰撞检测算法
p o o e a c li i n d t c i n a g rt m a e n d s r t . h l o i m a i g 2 s mu a i n p a f r a a e o r p s o lso e e to l o i h b s d o ic e e T e a g rt h t k n D i l t l to m sb s ,c mb n d o ie
2 1 1 O1 . 2
3 (2 0 1)
d i 1 .9 9 .s .0 6 17 .0 11 .2 o: 03 6 /i n1 0 —5 62 1 .20 3 js
兵 工 自 动 化 Or na e I u t y Au o a i n d nc nd s r t 2 D仿 真 平 台碰 撞检 测 算法
任 静 ,谢 广 明 ( 京大 学工 学 院 ,北 京 1 0 7 ) 北 081
摘要 : 为 了实现 机 器鱼 2 仿真 平 台各 个对 象 间完整 的碰 撞 检 测 ,提 出一种 基 于 离散碰撞 检 测 的算 法 。该 算法 D
e ce c , r cs e t r s i f in y p e iefau e .
Ke wo d : i l to l to m ; o o i s ; o lso e e t n; o n i g v l m e e a a i g a i y r s s mu a i n p a f r r b tc f h c li i n d t c i i o b u dn — ou ;s p r tn x s
同时 采用运 动插值 技 术 ,减 小 步长 并键 入 中间运 动模 态 ,实现 了模 拟连 续碰 撞检 测,进 一 步提 高 了碰 撞检 测准确 度 。 实验 结果 证 明 :该 方法 实现 了模 拟 连 续碰 撞检 测 ,具 有 高效 、精 准 的特 点 。

Box2D教程5-碰撞检测

Box2D教程5-碰撞检测

大伦子de空间/大伦子转载来源: Coming X原文链接: Box2D教程5-碰撞检测——————————————–之前我们已经了解了如何通过Box2D创建一个物理世界,给刚体添加复杂材质,鼠标交互。

在游戏开发里面我们通常要判断两个物体相互碰撞了,然后进行相应的操作。

比如―愤怒的小鸟‖,当小鸟碰撞到箱子的时候,我们需要知道这两个物体碰撞了,然后判断碰撞的力度(后面的教程会讲),然后对箱子进行操作。

这个教程就是用来处理Box2D的碰撞检测问题。

这个教程仍然基于先前的教程,关于如何创建一个物理世界,这里就不解释了。

为了要实现碰撞检测,需要使用到Box2D的B2ContactListener类。

该类是一个抽象类,不能直接被实例化,它包含四个方法:BeginContact, EndContact, PreSolve, PostSolve,我们必须先继承它创建自定义的ContactListener,然后override你需要的方法。

这个教程主要检测两个物体产生碰撞以及碰撞结束。

因此我们override BeginContact(开始碰撞)和EndContact(碰撞结束)方法。

首先我们创建一个简单的物理世界,四个边框和三个球体,这在先前的教程有详细说明1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738 package{import Box2D.Collision.Shapes.b2CircleShape;import Box2D.Collision.Shapes.b2PolygonShape;import Box2D.Collision.Shapes.b2Shape;import Box2D.Collision.b2AABB;import mon.Math.b2Vec2;import Box2D.Dynamics.Joints.b2MouseJoint;import Box2D.Dynamics.Joints.b2MouseJointDef;import Box2D.Dynamics.b2Body;import Box2D.Dynamics.b2BodyDef;import Box2D.Dynamics.b2DebugDraw;import Box2D.Dynamics.b2Fixture;import Box2D.Dynamics.b2FixtureDef;import Box2D.Dynamics.b2World;import mon.Console;import mon.CustomContactListener;import comingx.jingle.events.CollisionEvent;import erdata.BallUserData;import flash.display.GradientType;import flash.display.Sprite;import flash.events.Event;import flash.events.MouseEvent;import flash.geom.Matrix;import flash.text.TextField;import flash.text.TextFieldAutoSize;import flash.text.TextFormat;[SWF(width="500",height="300",frameRate="30")]public class Box2DCheckCollision extends Sprite{//屏幕像素单位转换成物理世界的距离单位private const PIXEL_TO_METER:Number = 30;//物理世界private var world:Box2D.Dynamics.b2World;3940414243444546474849505152535455565758596061626364656667686970717273747576777879808182private var _mouseXWorldPhys:Number;private var _mouseYWorldPhys:Number;private var _mouseXWorld:Number;private var _mouseYWorld:Number;private var _mousePVec:b2Vec2 = new b2Vec2();private var _groundBody:b2Body;private var _mouseJoint:b2MouseJoint;private var mouseDown:Boolean = false;private var console:Console;public function Box2DCheckCollision(){drawBackground();createWorld();createWall();createBall();createDebugDraw();addEventListener(Event.ENTER_FRAME, handleEnterFrame);addEventListener(MouseEvent.MOUSE_DOWN,handleMouseDown);addEventListener(MouseEvent.MOUSE_UP,handleMouseUp);addEventListener(MouseEvent.CLICK,handleMouseUp);addEventListener(Event.MOUSE_LEAVE,handleMouseUp);}private function createWorld():void{//重力向量var gravity:b2Vec2 = new b2Vec2(0,9.0);//是否休眠var doSleep:Boolean = true;world = new b2World(gravity,doSleep);world.SetWarmStarting(true);}private function createWall():void8384858687888990919293949596979899 10 0 10 1 10 2 10 3 10 4 10 5 10 6 10 7 10 8 10 9 11 0 11 1 11 2 11{//1.需要创建的墙刚体var leftWall:b2Body;//2.刚体定义var leftWallBodyDef:b2BodyDef = new b2BodyDef();//刚体类型和位置leftWallBodyDef.type = b2Body.b2_staticBody;//注意刚体的注册中心都是在物体的中心位置leftWallBodyDef.position.Set(10/PIXEL_TO_METER, stage.stageHeight/2/PIXEL_TO_METER);//工厂模式创建刚体leftWall = world.CreateBody(leftWallBodyDef);//3.刚体修饰物定义var leftWallFixtureDef:b2FixtureDef = newb2FixtureDef();//密度leftWallFixtureDef.density = 1.0;//摩擦粗糙程度leftWallFixtureDef.friction = 0.3;//力度返回程度(弹性)leftWallFixtureDef.restitution = 1.0;//4.创建墙形状var leftWallShape:b2PolygonShape = newb2PolygonShape();//此处参数为宽和高度的一半值leftWallShape.SetAsBox(10/PIXEL_TO_METER,stage.stageHeight/2/PIXEL_TO_METER);//将形状添加到刚体修饰物leftWallFixtureDef.shape = leftWallShape;leftWall.CreateFixture(leftWallFixtureDef);//下面创建其他三面墙,共用leftwall的几个变量leftWallBodyDef.position.Set((stage.stageWidth-10)/PIXEL_TO_METER ,stage.stageHeight/2/PIXEL_TO_METER);var rightWall:b2Body =world.CreateBody(leftWallBodyDef);rightWall.CreateFixture(leftWallFixtureDef);3 114 115 116 117 118 119 12 0 12 1 12 2 12 3 12 4 12 5 12 6 12 7 12 8 12 9 13 0 13 1 13 2 13 3 13 4 13leftWallBodyDef.position.Set( stage.stageWidth/2/PIXEL_TO_METER, (stage.stageHeight-10)/PIXEL_TO_METER);var bottomWall:b2Body =world.CreateBody(leftWallBodyDef);leftWallShape.SetAsBox(stage.stageWidth/2/PIXEL_TO_METER,10/PIXEL_TO_METER);bottomWall.CreateFixture(leftWallFixtureDef);leftWallBodyDef.position.Set( stage.stageWidth/2/PIXEL_TO_METER, 10/PIXEL_TO_METER);var topWall:b2Body =world.CreateBody(leftWallBodyDef);topWall.CreateFixture(leftWallFixtureDef);}private function createBall():void{var ballDef:b2BodyDef = new b2BodyDef();ballDef.type = b2Body.b2_dynamicBody;ballDef.position.Set(50/PIXEL_TO_METER,30/PIXEL_TO_METER);var ballBig:b2Body = world.CreateBody(ballDef);var circleShape:b2CircleShape = newb2CircleShape(30/PIXEL_TO_METER);var ballFixtureDef:b2FixtureDef = newb2FixtureDef();ballFixtureDef.shape = circleShape;ballFixtureDef.density = 1.0;ballFixtureDef.restitution = 0.5;ballBig.CreateFixture(ballFixtureDef);ballDef.position.Set(200/PIXEL_TO_METER,30/PIXEL_TO_METER);var ballMedium:b2Body = world.CreateBody(ballDef);circleShape = newb2CircleShape(20/PIXEL_TO_METER);5 136 137 138 139 14 0 14 1 14 2 14 3 14 4 14 5 14 6 14 7 14 8 14 9 15 0 15 1 15 2 15 3 15 4 15 5 15 6 15ballFixtureDef.shape = circleShape;ballMedium.CreateFixture(ballFixtureDef);ballDef.position.Set(400/PIXEL_TO_METER,30/PIXEL_TO_METER);var ballSmall:b2Body = world.CreateBody(ballDef);circleShape = newb2CircleShape(15/PIXEL_TO_METER);ballFixtureDef.shape = circleShape;ballSmall.CreateFixture(ballFixtureDef);}private function createDebugDraw():void{//创建一个sprite,可以将测试几何物体放入其中var debugSprite:Sprite = new Sprite();addChild(debugSprite);var debugDraw:b2DebugDraw = new b2DebugDraw();debugDraw.SetSprite(debugSprite);//设置边框厚度debugDraw.SetLineThickness(1.0);//边框透明度debugDraw.SetAlpha(1.0);//填充透明度debugDraw.SetFillAlpha(0.5);//设置显示对象debugDraw.SetFlags(b2DebugDraw.e_shapeBit);//物理世界缩放debugDraw.SetDrawScale(PIXEL_TO_METER);world.SetDebugDraw(debugDraw);}private function handleEnterFrame(evt:Event):void{UpdateMouseWorld();mouseDrag();var timeStep:Number = 1/30;var velocityInterations:int = 10;var positionIterations:int = 10;world.Step(timeStep,velocityInterations,positionIterations);//在2.1版本清除力,以提高效率7 15 8 15 9 16 0 16 1 16 2 16 3 16 4 16 5 16 6 16 7 16 8 16 9 17 0 17 1 17 2 17 3 17 4 17 5 17 6 17 7 17 8 17world.ClearForces();//绘制world.DrawDebugData();}private function drawBackground():void{var bg:Sprite = new Sprite();var matrix:Matrix = new Matrix();matrix.translate(100,100);bg.graphics.beginGradientFill(GradientType.RADIAL,[0xffffff,0xffa a00],[0.3,0.2],[0,255],matrix);bg.graphics.drawRect(0,0,stage.stageWidth,stage.stage.stageHeight );bg.graphics.endFill();addChild(bg);//tipsvar tf:TextField = new TextField();tf.text = "拖动球产生碰撞";tf.autoSize = TextFieldAutoSize.LEFT;var fomat:TextFormat = new TextFormat("Kai,华文楷体","20", 0x555555);tf.setTextFormat(fomat);tf.x = tf.y = 30;addChild(tf);}private function UpdateMouseWorld():void{_mouseXWorldPhys = this.mouseX/ PIXEL_TO_METER;_mouseYWorldPhys = this.mouseY/ PIXEL_TO_METER;_mouseXWorld = this.mouseX;_mouseYWorld = this.mouseY;}private function getBodyAtMouse(includeStatic:Boolean = false):b2Body{_mousePVec.Set(_mouseXWorldPhys,_mouseYWorldPhys);var aabb:b2AABB = new b2AABB();9 18 0 18 1 18 2 18 3 18 4 18 5 18 6 18 7 18 8 18 9 19 0 19 1 19 2 19 3 19 4 19 5 19 6 19 7 19 8 19 9 20 0 20aabb.lowerBound.Set(_mouseXWorldPhys -0.001,_mouseYWorldPhys -0.001);aabb.upperBound.Set(_mouseXWorldPhys +0.001,_mouseYWorldPhys +0.001);var body:b2Body = null;var fixture:b2Fixture;functiongetBodyCallback(fixture:b2Fixture):Boolean{var shape:b2Shape = fixture.GetShape();if(fixture.GetBody().GetType() !=b2Body.b2_staticBody || includeStatic){var inside:Boolean =shape.TestPoint(fixture.GetBody().GetTransform(), _mousePVec);if(inside){body =fixture.GetBody();return false;}}return true;}world.QueryAABB(getBodyCallback, aabb);return body;}private function mouseDrag():void{if(mouseDown&&!_mouseJoint){var body:b2Body = getBodyAtMouse();if(body){var md:b2MouseJointDef = newb2MouseJointDef();md.bodyA =world.GetGroundBody();md.bodyB = body;md.target.Set(_mouseXWorldPhys,_mouseYWorldPhys);1 202 203 204 205 206 207 208 209 21 0 21 1 21 2 21 3 21 4 21 5 21 6 21 7 21 8 21 9 22 0 22 1 22 2 22md.collideConnected = true;md.maxForce = 300.0*body.GetMass();_mouseJoint =world.CreateJoint(md) as b2MouseJoint;body.SetAwake(true);}}if(!mouseDown){if(_mouseJoint){world.DestroyJoint(_mouseJoint);_mouseJoint = null;}}if(_mouseJoint){var p2:b2Vec2 = newb2Vec2(_mouseXWorldPhys,_mouseYWorldPhys);_mouseJoint.SetTarget(p2);}}public function handleMouseDown(e:MouseEvent):void{mouseDown = true;}public function handleMouseUp(e:MouseEvent):void{mouseDown = false;}}}3 224 225 226 227 228 229 23 0 23 1 23 2 23 3 23 4 23 5 23 6 23 7 23 8 23 9 24 0 24 1 24 2 24 3 24 4 2424 6 24 7 24 8 24 9 25 0 25 1 25 2 25 3 25 4 25 5 25 6 25 7 25 8 25 9 26 0 26 1 26 2 26 3 26 4 26 5 26 6 2626 8 26 9 27 0 27 1 27 2 27 3 27 4 27 5 27 6 27 7 27 8 27 9 28 0 28 1 28 2 28 3 28 4 28 5 28 6 28 7 28 8 2829291292下面为关键代码1. 创建自定义的ContactListener1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334 package mon{import Box2D.Dynamics.Contacts.b2Contact;import Box2D.Dynamics.b2ContactListener;import comingx.jingle.events.CollisionEvent;import erdata.BallUserData;import flash.events.EventDispatcher;public class CustomContactListener extends b2ContactListener{public var eventDispatcher:EventDispatcher;public function CustomContactListener(){eventDispatcher = new EventDispatcher();}override public functionBeginContact(contact:b2Contact):void{var collisionEvent:CollisionEvent = new CollisionEvent(CollisionEvent.COLLISION_START);//墙的userdata为null,排除与墙的碰撞if(contact.GetFixtureA().GetBody().GetUserData() != null&& contact.GetFixtureB().GetBody().GetUserData() != null){collisionEvent.bodyAName = (contact.GetFixtureA().GetBody().GetUserData() as BallUserData).name;collisionEvent.bodyBName = (contact.GetFixtureB().GetBody().GetUserData() as BallUserData).name;353637383940414243eventDispatcher.dispatchEvent(collisionEvent);}}override public functionEndContact(contact:b2Contact):void{var collisionEvent:CollisionEvent = new CollisionEvent(CollisionEvent.COLLISION_END);if(contact.GetFixtureA().GetBody().GetUserData() != null&& contact.GetFixtureB().GetBody().GetUserData() != null){collisionEvent.bodyAName = (contact.GetFixtureA().GetBody().GetUserData() as BallUserData).name;collisionEvent.bodyBName = (contact.GetFixtureB().GetBody().GetUserData() as BallUserData).name;eventDispatcher.dispatchEvent(collisionEvent);}}}}b2ContactListener的是个方法将会每次Box2D计算时执行,因此它会不停的运行,只要有物体产生碰撞。

unity碰撞检测的公式

unity碰撞检测的公式

unity碰撞检测的公式Unity中的碰撞检测是通过使用物理引擎来实现的,主要有两种方法:碰撞器和物理材质。

碰撞器是一种组件,可以附加在游戏对象上,用于检测碰撞。

物理材质则用于定义物体的物理属性,例如摩擦力和弹性系数。

下面将详细介绍Unity中碰撞检测的公式。

1.碰撞器Unity中常用的碰撞器有四种:盒子碰撞器(Box Collider)、球形碰撞器(Sphere Collider)、胶囊碰撞器(Capsule Collider)和网格碰撞器(Mesh Collider)。

不同的碰撞器会使用不同的检测公式。

- 盒子碰撞器(Box Collider)盒子碰撞器用于检测具有四个相等正面的盒子形状的物体之间的碰撞。

碰撞器的位置和大小可以通过修改中心(center)属性和尺寸(size)属性来进行调整。

碰撞器的公式可以简化为使用点是否位于盒子的边界上进行判断。

- 球形碰撞器(Sphere Collider)球形碰撞器用于检测球形物体之间的碰撞。

碰撞器的位置和半径可以通过修改中心(center)属性和半径(radius)属性来进行调整。

碰撞器的公式可以简化为检查两个球心之间的距离是否小于等于两个球的半径之和。

- 胶囊碰撞器(Capsule Collider)胶囊碰撞器用于检测具有两个球形端点和一个连接两个球形端点的圆柱体的物体之间的碰撞。

碰撞器的位置、高度和半径可以通过修改中心(center)属性、高度(height)属性和半径(radius)属性来进行调整。

碰撞器的公式可以简化为通过检查两个球形端点以及两个球以及圆柱体之间的距离来进行判断。

- 网格碰撞器(Mesh Collider)网格碰撞器用于检测基于网格的物体之间的碰撞,例如复杂的模型或地形。

该碰撞器的形状和大小与物体的实际网格形状和大小完全一致。

碰撞器的公式通常使用边缘检测算法(例如GJK算法或SAT算法)来进行检测。

2.物理材质Unity中的物理材质被用于定义物体的物理属性,例如摩擦力和弹性系数。

双移动工业机器人系统碰撞检测方法

双移动工业机器人系统碰撞检测方法

机器人技术Robotics《自动化技术与应用》2020年第39卷第12期双移动工业机器人系统碰撞检测方法**基金项目:“高档数控机床与基础制造装备”国家科技重大专项(2018ZX04014001)收稿日期:2019-09-18郑义,田威,胡俊山,孙新月(南京航空航天大学机电学院,江苏南京210016)摘 要:现有的工业机器人碰撞检测技术大多是面向基座固定的机器人系统,针对更易发生碰撞的基座移动的情况,提岀了一种用于移动工业机器人系统的碰撞检测方法。

建立固定于地面的坐标系,作为机器人移动的参考,利用球体和胶囊体两种空间几何体对机器人本体进行简化,将碰撞检测问题转换为求解几何体间最小距离问题。

将碰撞检测算法应用于两台搭载KUKA 机器人的AGV 组成的双移动工业机器人系统,利用VC++完成算法的计算,在DELMIA 中进行碰撞仿真,仿真结果验证了该算法的正确性。

关键词:双移动工业机器人;碰撞检测,模型简化;最小距离中图分类号:TP242.2文献标识码:A 文章编号:1003-7241(2020)012-0082-05Collision Detection Method for Dual MobileIndustrial Robot SystemZHENG Yi, TIAN Wei, HU Jun-shan, SUN Xin-yue(Nanjing University of A eronautics and Astronautics, Nanjing 210016 China )Abstract: Most of the existing industrial robot collision detection technologies are facing robot systems that are fixed to the ground.For the movement of base that is more prone to collision, a collision detection method for the mobile industrial robot sys ­tem is proposed. The coordinate system fixed on the ground is established as a reference for the movement of the robot.The space body of the sphere and the capsule is used to simplify the robot body, and the collision detection problem is con­verted into the minimum distance problem between the geometric bodies. The collision detection algorithm is applied to the dual mobile industrial robot system composed of two AG V s equipped with KUKA robot. The calculation of the algo­rithm is completed by VC 卄,and the collision simulation is carried out in DELMIA. The simulation results verify the cor ­rectness of the algorithm.Key words: dual mobile industrial robot; collision detection; model simplification; minimum distance1 引言航天大型构件尺寸大、结构复杂、精度要求高、载荷 重、材料特殊,并伴有薄壁结构等特点,对机器人的动作流程和可靠性等都提出了较高的要求,且要求其具有良好的作业柔性与可扩展性。

二维游戏碰撞检测算法的优化与应用

二维游戏碰撞检测算法的优化与应用

二维游戏碰撞检测算法的优化与应用【摘要】本文首先对游戏的发展和常用二维游戏碰撞检测算法进行了概括与分析.然后讨论常用二维游戏碰撞检测算法的原理及其优点与缺点,例如:地图格子划分检测(将地图划分为N个小格子进行检测)、矩形检测(利用规则四边形的X、Y坐标进行检测)、圆形检测(利用类圆图形的圆心距离与半径之和的关系进行检测)、像素检测(利用物体碰撞部分像素深度进行检测)、四叉树检测(多个物体的碰撞检测)。

其次,采用在SAT(Separating Axis Theorem)的碰撞检测算法的基础之上,与其它碰撞检测算法进行比较,进而根据SAT的性质定理,将SAT应用在判断凸多边形的旋转碰撞检测。

而基于SAT改进的碰撞检测算法,它比其它算法对于旋转凸多边形的碰撞检测而言更加的快速,并且应用的范围也相对广泛。

然后,在基于VC++6.0开发环境下,采用二维游戏开发技术,对SAT算法在旋转凸多边形的碰撞检测的应用测试的基础之上,进行计算机控制角色与玩家控制角色的碰撞检测。

最后,对文中所涉及到的碰撞检测算法在游戏应用中的优点与缺点,进行分析、比较、总结。

【关键词】地图格子划分检测矩形检测圆形检测像素检测四叉树检测SATTwo-Dimensional Games of Collision Detection AlgorithmOptimization and Application【Abstract】Firstly, the development of the game and used Two-Dimensional Game of Collision Detection Algorithm is summarized and analyzed. And then discuss the commonly used Two-Dimensional Game of Collision Detection Algorithm to the principle and its advantages and disadvantages, for example: Map Detected (the map is divided into N small squares for testing), Rectangle Detection(using the rules of the quadrilateral X, Y coordinates of the test), Circle Detection (using class graph of the center circle radius and the distance and the relationship between the test),Pixel Detection (use of objects and collision detection part of the pixel depth), Quadtree Detection (multiple objects collision detection).Secondly, the use of the SAT (Separating Axis Theorem) the collision detection algorithm based on, and other collision detection algorithms were compared, and then according to theInature of SAT theorem, SAT application in determining the rotation of convex polygon collision detection. Improved SAT-based collision detection algorithm than other algorithms for the rotation in terms of convex polygon collision detection is more rapid, and relatively wide range of applications.Then, based on the VC++6.0 development environment, using two-dimensional game development technology, the SAT algorithm in rotating convex polygon collision detection based on the application of the test, the computer-controlled characters and the player controls the character collision detection.Finally, the paper involved in the collision detection algorithm in the game's pros and cons of the application, analysis, comparison and summary.【Key words】Map Detected Rectangle Detection Circle Detection Pixel Detection Quadtree Detection SAT目录绪论 (1)1 研究概述 (2)1.1 研究背景 (2)1.2 课题来源 (2)1.3 国内外研究现状 (3)1.4 论文主要工作 (3)1.5 论文结构 (3)2 相关算法概念 (4)2.1 地图格子划分检测 (4)2.2 矩形检测 (5)2.3 圆形检测 (7)2.4 像素检测 (8)2.5 四叉树检测 (9)3 基于SAT多边形旋转碰撞检测算法 (12)3.1 什么是SAT (12)3.2 基于SAT的旋转多边形碰撞检测 (14)3.3 算法的改进与优化 (19)4.2 实现步骤 (20)4.1 设计思路流程图 (20)4.2 程序的具体实现 (22)4.2.1 创建游戏窗口 (22)4.2.2 添加背景图片 (24)4.2.3 添加角色图片 (25)4.2.4 按键消息处理 (26)4.2.5 SAT在程序中的应用 (31)5 测试 (31)总结 (33)参考文献 (34)附录 (35)致谢...................................................... 错误!未定义书签。

碰撞检测

碰撞检测

碰撞检测在游戏中,经常需要进行碰撞检测的实现,例如判断前面是否有障碍以及判断子弹是否击中飞机,都是检测两个物体是否发生碰撞,然后根据检测的结果做出不同的处理。

进行碰撞检测的物体可能有些的形状和复杂,这些需要进行组合碰撞检测,就是将复杂的物体处理成一个一个的基本形状的组合,然后分别进行不同的检测。

碰撞问题包括碰撞检测和碰撞响应两个方面的内容。

碰撞检测用来检测不同对象之间是否发生了碰撞,碰撞响应是在碰撞发生后,根据碰撞点和其他参数促使发生碰撞的对象作出正确的动作,以反映真实的动态效果。

碰撞检测方法:按照对象所处的空间分:二维平面碰撞检测和三维空间碰撞检测按检测的方法长区分为:空间分解法,层次包围盒法空间分解法:将虚拟空间分解为体积相等的小单元格,只对占据同一单元格或相邻单元格的几何对象进行相交测试,典型的空间分解法有八叉树法和二分空间剖分法。

层次包围盒方法是利用体积略大于对象空间而形状简单的几何对象包裹起来,在碰撞检测时首先进行包围盒之间的相交测试;如果包围盒相交,再进行盒内几何对象之间的精确碰撞检测。

轴向包围盒(AABB)、方向包围盒(OBB)、离散方向多面体(k-DOP)、时空包围盒(STBB)检测算法的等。

一、平面碰撞:下面先简单介绍一下两种最基本的形状进行碰撞的时候进行的处理。

1、矩形和矩形进行碰撞一般规则的物体碰撞都可以处理成矩形碰撞,实现的原理就是检测两个矩形是否重叠。

我们假设矩形1的参数是:左上角的坐标是(x1,y1),宽度是w1,高度是h1;矩形2的参数是:左上角的坐标是(x2,y2),宽度是w2,高度是h2。

在检测时,数学上可以处理成比较中心点的坐标在x和y方向上的距离和宽度的关系。

即两个矩形中心点在x方向的距离的绝对值小于等于矩形宽度和的二分之一,同时y方向的距离的绝对值小于等于矩形高度和的二分之一。

下面是数学表达式:x方向:| (x1 + w1 / 2) – (x2 + w2/2) | < |(w1 + w2) / 2|y方向:| (y1 + h1 / 2) – (y2 + h2/2) | < |(h1 + h2) / 2|在程序中,只需要将上面的条件转换成代码就可以实现了。

游戏中的2DOBB碰撞模型的碰撞算法介绍和实践

游戏中的2DOBB碰撞模型的碰撞算法介绍和实践

游戏中的2DOBB碰撞模型的碰撞算法介绍和实践前⾔上⼀篇博⽂说道,射线与场景中模型上的所有三⾓形求交时,会⼤幅度影响效率且花费⽐较多的时间,因此会采取使⽤包围盒的形式,进⾏⼀个加速求交。

在此⽂中介绍OBB碰撞模型的碰撞算法OBB的碰撞模型有没有想过为什么需要⽤到OBB模型呢,假设⼀个场景内两个⼈物相撞了,你怎么判断它们是否相撞呢,⼤概就是它们的碰撞体接触在了⼀起就相撞了。

那怎么算碰撞在⼀起呢(此处只讨论2D规则的包围盒模型)?⽅向包围盒OBB"("Oriented Bounding Box)是⽬前⽐较流⾏的⼀种包围盒,OBB最⼤的特点是其⽅向的任意性,这使得可以根据被包围的对象的形状特点尽可能紧密地包围对象,Unity中的BoxCollider的其实就是OBB模型,它不是轴对称模型,⽽是有⽅向的OBB模型与之相反的是AABB模型,是轴对称模型,即它的边⼀定与坐标轴平⾏,算法简单,但使⽤的局限性⽐较⼤,更多还是使⽤OBB模型碰撞算法分析想要判断两个OBB模型碰撞,也就是两个矩形相交,我们分为⼏个步骤,⾸先先转换问题,什么时候两个矩形不相交,两个矩形相离可看成有多个直线可将它们之间分开。

当逐渐移动某个矩形,使得某个时刻,两个矩形只有⼀个交点,交点属于矩形的某条边上,此时为临界状态,当且仅当只有⼀条直线将他们两个分开,此时这条直线必定与某条边平⾏。

所以我们只需找两个矩形的四条边分别作为轴,两个矩形的xVt、yVt分别进⾏投影,看投影后的两个线段是否相离,如果相离则在这个轴上可以将这两个进⾏分开,故此时两个矩形不相交,反之若相交,则继续接着其他轴进⾏判断,若所有轴都不能分开,则这两个矩形相交我们观察 AB proj 与 boxA、boxB 的 xVt proj 、yVt proj 之间的关系,可以得出结论:AB proj > sum(Vt proj) ,则矩形相离AB proj = sum(Vt proj) ,则矩形相切AB proj < sum(Vt proj) ,则矩形相交参考⽹上某⼤佬的代码参考博⽂:分别取两个矩形的两个边,总共进⾏四次投影对称,作为对称轴axis1 = (P1 - P0).normalized;axis2 = (P3 - P0).normalized;axis3 = (other.P1 - other.P0).normalized;axis4 = (other.P3 - other.P0).normalized;mDebugInternalAxisIndex = 0;bool isNotIntersect = false;isNotIntersect |= ProjectionIsNotIntersect(this, other, axis1);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis2);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis3);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis4);这⾥是取带符号的长度,⽤来⽐较投影后的线段是否相交float x_p0 = xProject_P0.magnitude * Mathf.Sign(Vector3.Dot(xProject_P0, axis));float x_p1 = xProject_P1.magnitude * Mathf.Sign(Vector3.Dot(xProject_P1, axis));float x_p2 = xProject_P2.magnitude * Mathf.Sign(Vector3.Dot(xProject_P2, axis));float x_p3 = xProject_P3.magnitude * Mathf.Sign(Vector3.Dot(xProject_P3, axis));相交判断:if (yMin >= xMin && yMin <= xMax) return false;if (yMax >= xMin && yMax <= xMax) return false;简约的⽰例图using UnityEngine;// OBB.cspublic class OBB : MonoBehaviour{public bool enableDebug;public int debug_axisIndex;int mDebugInternalAxisIndex;public Vector2 size;public Color gizmosColor = Color.white;Vector2 P0 { get { return transform.localToWorldMatrix.MultiplyPoint3x4(-size * 0.5f); } }Vector2 P1 { get { return transform.localToWorldMatrix.MultiplyPoint3x4(new Vector3(size.x * 0.5f, -size.y * 0.5f, 0)); } } Vector2 P2 { get { return transform.localToWorldMatrix.MultiplyPoint3x4(size * 0.5f); } }Vector2 P3 { get { return transform.localToWorldMatrix.MultiplyPoint3x4(new Vector3(-size.x * 0.5f, size.y * 0.5f, 0)); } } Vector2 axis1, axis2, axis3, axis4;// 较参考博⽂添加以下变量,⽤来缓存向量减少gcVector3 xProject_P0;Vector3 xProject_P1;Vector3 xProject_P2;Vector3 xProject_P3;Vector3 yProject_P0;Vector3 yProject_P1;Vector3 yProject_P2;Vector3 yProject_P3;public bool Intersects(OBB other){axis1 = (P1 - P0).normalized;axis2 = (P3 - P0).normalized;axis3 = (other.P1 - other.P0).normalized;axis4 = (other.P3 - other.P0).normalized;mDebugInternalAxisIndex = 0;bool isNotIntersect = false;isNotIntersect |= ProjectionIsNotIntersect(this, other, axis1);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis2);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis3);isNotIntersect |= ProjectionIsNotIntersect(this, other, axis4);return isNotIntersect ? false : true;}bool ProjectionIsNotIntersect(OBB x, OBB y, Vector2 axis){xProject_P0 = Vector3.Project(x.P0, axis);xProject_P1 = Vector3.Project(x.P1, axis);xProject_P2 = Vector3.Project(x.P2, axis);xProject_P3 = Vector3.Project(x.P3, axis);float x_p0 = xProject_P0.magnitude * Mathf.Sign(Vector3.Dot(xProject_P0, axis));float x_p1 = xProject_P1.magnitude * Mathf.Sign(Vector3.Dot(xProject_P1, axis));float x_p2 = xProject_P2.magnitude * Mathf.Sign(Vector3.Dot(xProject_P2, axis));float x_p3 = xProject_P3.magnitude * Mathf.Sign(Vector3.Dot(xProject_P3, axis));yProject_P0 = Vector3.Project(y.P0, axis);yProject_P1 = Vector3.Project(y.P1, axis);yProject_P2 = Vector3.Project(y.P2, axis);yProject_P3 = Vector3.Project(y.P3, axis);float y_p0 = yProject_P0.magnitude * Mathf.Sign(Vector3.Dot(yProject_P0, axis));float y_p1 = yProject_P1.magnitude * Mathf.Sign(Vector3.Dot(yProject_P1, axis));float y_p2 = yProject_P2.magnitude * Mathf.Sign(Vector3.Dot(yProject_P2, axis));float y_p3 = yProject_P3.magnitude * Mathf.Sign(Vector3.Dot(yProject_P3, axis));float xMin = Mathf.Min(x_p0, x_p1, x_p2, x_p3);float xMax = Mathf.Max(x_p0, x_p1, x_p2, x_p3);float yMin = Mathf.Min(y_p0, y_p1, y_p2, y_p3);float yMax = Mathf.Max(y_p0, y_p1, y_p2, y_p3);if (enableDebug){if (debug_axisIndex == mDebugInternalAxisIndex){Debug.DrawRay(Vector3.Project(x.P0, axis), Vector3.one * 0.1f);Debug.DrawRay(Vector3.Project(x.P2, axis), Vector3.one * 0.1f);Debug.DrawRay(Vector3.Project(y.P0, axis), Vector3.one * 0.1f, Color.white * 0.9f);Debug.DrawRay(Vector3.Project(y.P2, axis), Vector3.one * 0.1f, Color.white * 0.9f);Debug.DrawRay(Vector3.zero, Vector3.one * 0.1f, Color.black);Debug.DrawRay(Vector3.zero, axis, Color.yellow);Debug.DrawRay(xMin * Vector3.right, Vector3.one * 0.1f, Color.blue);Debug.DrawRay(xMax * Vector3.right, Vector3.one * 0.1f, Color.cyan);Debug.DrawRay(yMin * Vector3.right, Vector3.one * 0.1f, Color.red * 0.5f);Debug.DrawRay(yMax * Vector3.right, Vector3.one * 0.1f, Color.red * 0.5f);Debug.Log("(yMin >= xMin && yMin <= xMax): " + (yMin >= xMin && yMin <= xMax) + " frame count: " + Time.frameCount); Debug.Log("(yMax >= xMin && yMax <= xMax): " + (yMax >= xMin && yMax <= xMax) + " frame count: " + Time.frameCount); Debug.Log("(xMin >= yMin && xMin <= yMax): " + (xMin >= yMin && xMin <= yMax) + " frame count: " + Time.frameCount); Debug.Log("(xMax >= yMin && xMax <= yMax): " + (xMax >= yMin && xMax <= yMax) + " frame count: " + Time.frameCount); }mDebugInternalAxisIndex++;}if (yMin >= xMin && yMin <= xMax) return false;if (yMax >= xMin && yMax <= xMax) return false;// 此处只需做两次判断即可,参考博⽂做了四次判断// if (xMin >= yMin && xMin <= yMax) return false;// if (xMax >= yMin && xMax <= yMax) return false;return true;}void OnDrawGizmos(){Gizmos.matrix = transform.localToWorldMatrix;Gizmos.color = gizmosColor;Gizmos.DrawWireCube(Vector3.zero, new Vector3(size.x, size.y, 1f));}}using System.Collections;using System.Collections.Generic;using UnityEngine;// OBBTest.cspublic class OBBTest : MonoBehaviour{public OBB a;public OBB b;void Update(){var isIntersects = a.Intersects(b);if (isIntersects){a.gizmosColor = Color.red;b.gizmosColor = Color.red;}else{a.gizmosColor = Color.white;b.gizmosColor = Color.white;}}}效果。

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法

2d胶囊体碰撞检测算法摘要:1.2D 胶囊体碰撞检测算法的背景和意义2.2D 胶囊体的定义和特点3.碰撞检测算法的基本原理4.2D 胶囊体碰撞检测算法的具体步骤5.算法的优点和局限性6.应用场景和案例正文:1.2D 胶囊体碰撞检测算法的背景和意义在计算机图形学和游戏开发领域,碰撞检测是一个重要的研究课题。

在众多碰撞检测算法中,2D 胶囊体碰撞检测算法因其高效、简洁的特点而备受关注。

该算法主要用于检测两个2D 胶囊体(具有圆形和矩形部分的实体)是否发生碰撞,广泛应用于游戏角色设计、场景布局和动画制作等方面。

2.2D 胶囊体的定义和特点2D 胶囊体是一个具有圆形和矩形部分的二维图形元素,可以看作是一个具有方向的矩形和与其相连接的圆形。

胶囊体的特点是其圆形部分可以与其他物体的圆形部分相接触,而矩形部分则负责连接圆形部分与物体的其他部分。

3.碰撞检测算法的基本原理碰撞检测算法的基本原理是判断两个物体是否发生了相互作用,即它们的距离是否小于等于一定值。

对于2D 胶囊体碰撞检测算法来说,需要判断两个胶囊体的圆形部分是否相交,以及它们的矩形部分是否相连。

4.2D 胶囊体碰撞检测算法的具体步骤(1)判断两个胶囊体的圆形部分是否相交。

如果相交,进入下一步;如果不相交,则两个胶囊体不发生碰撞。

(2)判断两个胶囊体的矩形部分是否相连。

如果相连,则两个胶囊体发生碰撞;如果不相连,则两个胶囊体不发生碰撞。

5.算法的优点和局限性2D 胶囊体碰撞检测算法的优点在于其高效性和简洁性,尤其在处理大量物体的碰撞检测时,具有较高的性能优势。

然而,该算法的局限性在于其仅适用于2D 胶囊体,对于其他类型的物体碰撞检测,需要进行相应的调整和优化。

6.应用场景和案例2D 胶囊体碰撞检测算法广泛应用于游戏开发、计算机动画、虚拟现实等领域。

基于VR的二维触发式碰撞检测算法①

基于VR的二维触发式碰撞检测算法①

基于VR的二维触发式碰撞检测算法①王坤【期刊名称】《计算机系统应用》【年(卷),期】2013(000)009【摘要】Virtual reality technology is often used in virtual scene to set the movement range of a certain role, where collision detection algorithm between objects has been a crucial technology. Common algorithm based on graphics and image is effective and widely used but is incapable of event handling, unefficient and occupies too many system resources. Therefore, an efficient algorithm for two-dimensional array collision detection is introduced to meet the needs of high efficiency and less precise collision detection.%在虚拟场景中经常会用到虚拟现实技术设置某精灵的移动范围和区域,物体与物体之间碰撞检测的算法成为技术关键,常用的基于图形图像的算法虽然很有效应用范围广,但是无事件处理能力,并且执行效率低和占用大量的系统资源。

本文介绍一种利用二维数组高效的碰撞检测算法,满足执行效率高但精度要求不高的碰撞检测。

【总页数】5页(P139-143)【作者】王坤【作者单位】四川信息职业技术学院信息工程系,广元,628017【正文语种】中文【相关文献】1.基于VR的碰撞检测算法研究 [J], 李林;谢振华;吴卫玲;陈遵银2.一种基于OBB矩形碰撞检测算法的r堆取料机防碰撞方法 [J], 尹艳艳;吕崇晓3.二维动画设计中的碰撞检测算法 [J], 谭睿璞4.结合二维算法的三维快速碰撞检测算法 [J], 邹承明;汤智勇5.结合二维算法的三维快速碰撞检测算法 [J], 邹承明; 汤智勇因版权原因,仅展示原文概要,查看原文内容请购买。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2d胶囊体碰撞检测算法
【原创版】
目录
1.2D 胶囊体碰撞检测算法的背景和意义
2.2D 胶囊体的定义和特点
3.碰撞检测算法的基本原理
4.算法的具体实现步骤
5.算法的优缺点分析
6.算法的应用案例
正文
2D 胶囊体碰撞检测算法是计算机图形学中常见的算法之一,主要用于检测两个 2D 胶囊体是否发生碰撞。

在计算机图形学、物理模拟等领域有着广泛的应用。

2D 胶囊体是一种特殊的几何体,由一个圆形和一个矩形组成,具有一定的方向性。

在计算机图形学中,胶囊体通常用于表示物体的边界,例如,在物理模拟中,胶囊体可以表示物体的形状和大小。

碰撞检测算法的基本原理是,通过计算两个胶囊体的边界是否相交,来判断它们是否发生碰撞。

具体来说,就是计算两个胶囊体的边界矩形的交点,如果有交点,则说明两个胶囊体发生了碰撞。

算法的具体实现步骤如下:
1.首先,计算两个胶囊体的边界矩形。

对于一个胶囊体,其边界矩形可以通过将其圆形部分和矩形部分扩展一定距离得到。

2.然后,计算两个边界矩形的交点。

这可以通过计算两个矩形的交点来实现。

3.最后,判断两个边界矩形的交点是否在两个胶囊体的边界矩形内部。

如果在内部,则说明两个胶囊体发生了碰撞。

该算法的优点是计算简单,速度快,适用于实时模拟。

缺点是只能检测到胶囊体的边界碰撞,不能检测到内部碰撞。

2D 胶囊体碰撞检测算法在计算机图形学、物理模拟等领域有着广泛
的应用。

相关文档
最新文档