obb碰撞检测算法原理
- 格式:docx
- 大小:11.68 KB
- 文档页数:3
基于包围盒的碰撞检测算法综述包围盒是一个简单的几何形状,通常是一个立方体或长方体,可以完全包围住一个物体。
它们的简单性和计算效率使得包围盒成为进行碰撞检测的理想选择。
基于包围盒的碰撞检测算法主要有以下几种。
1. AABB包围盒:AABB(Axis-Aligned Bounding Box)是指与坐标轴平行且不会旋转的包围盒。
AABB包围盒算法是最简单和最常用的碰撞检测算法之一、它通过比较两个对象的最小和最大坐标来检测碰撞。
2. OBB包围盒:OBB(Oriented Bounding Box)是指带有旋转的包围盒。
相比AABB,OBB相对更复杂,但也更准确。
OBB包围盒算法需要使用旋转矩阵和顶点集合进行计算,因此相对于AABB算法而言,计算量更大。
3.球体包围盒:球体包围盒是一种基于球体形状的包围盒。
它可以用来表示物体的位置和大小,并且具有高效的碰撞检测算法。
当物体形状不规则或者需要进行更精确的碰撞检测时,球体包围盒是一种比较适合的选择。
4. 层次包围盒树(Bounding Volume Hierarchy):层次包围盒树是一种将多个包围盒组织成树形结构的算法。
通过层次包围盒树,可以快速剔除掉与待检测物体无关的包围盒,从而提高碰撞检测的效率。
常见的层次包围盒树算法有BVH(Bounding Volume Hierarchy)和AABB树。
基于包围盒的碰撞检测算法的优点是简单、高效。
由于包围盒的几何形状简单,所以可以很快地进行计算,能够快速判断物体之间的碰撞关系。
此外,因为其计算消耗较小,可以处理大规模的碰撞检测任务。
但是,基于包围盒的碰撞检测算法也有一些局限性,比如对于一些复杂形状的物体,包围盒可能无法精确地判断碰撞关系。
综上所述,基于包围盒的碰撞检测算法是一种高效、简单的方法,可以应用于各种领域,如计算机图形学、物理引擎和虚拟现实等。
通过选择合适的包围盒类型和算法,可以在保证速度和准确性的同时,实现高效的碰撞检测。
虚拟场景中的碰撞检测算法作者:马登武, 孙隆和, 佟明安作者单位:西北工业大学,陕西,西安,710072刊名:火力与指挥控制英文刊名:FIRE CONTROL & COMMAND CONTROL年,卷(期):2004,29(4)被引用次数:15次参考文献(4条)1.Klosowski J T;Teld M Efficient Collision Detection Using Bounding Volume Hierarchies of K-DOPs[外文期刊] 1998(01)2.Moore M;Wilhelms J Collision Detection and Response for Computer Animation[外文期刊] 19883.Hubbard P M Collision Detection for Intersection Graphics Application[外文期刊] 1995(03)4.Gottschalk S;Lin M C;Manocha D OBBTree: A Hierarchical Structure for Rapid Interference Detection 1996引证文献(15条)1.陈亚东.胡建平.王丽城市地下三维管网建模技术研究[期刊论文]-计算机与现代化 2010(8)2.郭亨波.倪丽萍.蒋欣地下空间轴向包围盒树三维碰撞检测算法研究[期刊论文]-地下空间与工程学报 2010(4)3.基于Virtools的虚拟家居漫游系统的设计与实现[期刊论文]-计算机工程与科学 2009(12)4.王伟.马峻.刘伟基于OBB包围盒的碰撞检测研究与应用[期刊论文]-计算机仿真 2009(9)5.耿文涛.武旭东.刘虎.武哲基于Virtools的战斗机挂弹仿真[期刊论文]-飞机设计 2009(1)6.边美玲.任建平包围盒碰撞检测技术的研究[期刊论文]-机械管理开发 2008(2)7.何伟.李勇.苏虎碰撞检测中的包围盒方法[期刊论文]-重庆工学院学报(自然科学版) 2007(12)8.陈雷.伊明.陈二雷基于包围盒的碰撞检测算法研究[期刊论文]-电脑知识与技术(学术交流) 2007(14)9.彭巧梅.彭双根.陈玉德基于Virtools的碰撞检测技术的研究与应用[期刊论文]-佳木斯大学学报(自然科学版) 2007(3)10.董明助渔模块中鱼群仿真的研究[学位论文]硕士 200711.史晶晶.张桦.程朋亮智能化虚拟人感知模型的一种探索性研究[期刊论文]-天津理工大学学报 2006(4)12.李天信基于装配特征的快速装配仿真技术研究及应用[学位论文]硕士 200613.张红朴实时分布仿真环境下的视景仿真技术研究[学位论文]硕士 200614.王蕾工业智能监控软件中的可视化技术应用与研究[学位论文]硕士 200515.王忠五轴数控加工干涉检查技术的研究[学位论文]硕士 2005本文链接:/Periodical_hlyzhkz200404014.aspx。
ue4常用算法UE4常用算法一、简介UE4(Unreal Engine 4)是一款强大的游戏开发引擎,广泛应用于游戏开发、虚拟现实和增强现实等领域。
在UE4的开发过程中,使用一些常用算法可以帮助开发者更高效地实现各种功能。
本文将介绍UE4常用的几种算法及其应用。
二、碰撞检测算法1. AABB碰撞检测算法AABB(Axis-Aligned Bounding Box)是一种常用的碰撞检测算法,它适用于多种场景,如物体与物体之间的碰撞检测、射线与物体的相交检测等。
在UE4中,使用AABB碰撞检测算法可以实现游戏中的物体碰撞效果。
2. OBB碰撞检测算法OBB(Oriented Bounding Box)是一种基于物体自身旋转的碰撞检测算法。
与AABB碰撞检测算法不同的是,OBB碰撞检测算法可以处理旋转的物体,使得碰撞检测更加准确。
在UE4中,使用OBB碰撞检测算法可以实现更加真实的碰撞效果。
三、寻路算法1. A*算法A*(A-Star)算法是一种常用的寻路算法,它可以在一个给定的地图上找到两个给定点之间的最短路径。
在UE4中,使用A*算法可以帮助开发者实现游戏中的自动寻路功能,例如NPC角色的移动、敌人的追击等。
四、光照计算算法1. 光线追踪算法光线追踪算法是一种用于模拟光照效果的算法,它通过模拟光线从光源出发并在场景中反射、折射等过程,计算出最终的光照效果。
在UE4中,使用光线追踪算法可以实现逼真的光照效果,使游戏画面更加真实。
五、粒子系统算法1. 引力模拟算法引力模拟算法是一种常用的粒子系统算法,它通过模拟物体之间的引力作用来实现粒子的运动效果。
在UE4中,使用引力模拟算法可以实现粒子的自然下落、旋转等效果,使游戏中的粒子效果更加逼真。
六、物理模拟算法1. 刚体碰撞算法刚体碰撞算法是一种用于模拟物体之间碰撞效果的算法,它可以计算出物体之间的碰撞力、反弹效果等。
在UE4中,使用刚体碰撞算法可以实现物体之间的真实碰撞效果,使游戏中的物体行为更加真实。
obb最小包围盒算法摘要:1.OBB 最小包围盒算法概述2.OBB 最小包围盒算法的原理3.OBB 最小包围盒算法的实现4.OBB 最小包围盒算法的应用5.总结正文:【1.OBB 最小包围盒算法概述】OBB(Oriented Bounding Box)最小包围盒算法是一种在计算机图形学和碰撞检测领域广泛应用的算法。
它的主要作用是计算出一个物体在三维空间中的最小包围盒,即以最紧凑的方式包围物体的盒子。
这种算法相比其他包围盒算法,如轴向包围盒(AABB)和球形包围盒(Sphere),具有更低的计算复杂度和更高的精度。
【2.OBB 最小包围盒算法的原理】OBB 最小包围盒算法的原理可以概括为以下几个步骤:1) 计算物体的六个面(前、后、左、右、上、下)的边界框(bounding box)。
2) 通过计算物体的每个顶点与对面顶点的连线,找到每个面上的最小和最大坐标值。
3) 根据步骤2 的结果,计算出物体的最小包围盒。
【3.OBB 最小包围盒算法的实现】OBB 最小包围盒算法的实现过程如下:1) 首先,需要对物体的顶点进行排序,以便后续计算。
2) 计算每个面上的边界框。
对于每个面,可以通过计算该面上的四个顶点的最小和最大坐标值得到。
3) 对于每个面,找到对面的顶点,并计算该顶点在与该面相交的边上的坐标。
这样就可以得到物体的最小包围盒。
【4.OBB 最小包围盒算法的应用】OBB 最小包围盒算法在许多领域都有广泛应用,如计算机图形学、碰撞检测、场景管理等。
在碰撞检测中,OBB 算法可以高效地检测两个物体是否相交,从而为后续的物理模拟和渲染提供准确的数据。
【5.总结】OBB 最小包围盒算法是一种高效、精确的三维包围盒算法。
相较于其他包围盒算法,它具有更低的计算复杂度和更高的精度。
碰撞检测算法在游戏开发中的实现方法在游戏开发中,碰撞检测是一个非常重要的环节。
它负责检测游戏中的物体是否发生碰撞以及如何处理这种碰撞。
一种常用的碰撞检测算法是基于物体的边界框(Bounding Box)的碰撞检测算法。
边界框是一个简单的矩形或包围框,它完全包围了物体。
利用边界框,我们可以通过简单的矩形碰撞检测算法来判断两个物体是否相交。
这种算法的优势在于它的简单性和高效性。
下面我将介绍一些常见的碰撞检测算法。
1. AABB碰撞检测算法(Axis-Aligned Bounding Box)AABB碰撞检测算法是一种简单而高效的算法。
它基于矩形的边界框判断两个物体是否相交。
首先,需要获取两个物体的边界框,并判断两个边界框在X轴和Y轴上是否有重叠。
如果两个边界框在X轴上有重叠且在Y轴上也有重叠,那么可以判断这两个物体发生了碰撞。
2. OBB碰撞检测算法(Oriented Bounding Box)OBB碰撞检测算法是一种更为复杂的算法。
与AABB不同的是,OBB算法中的边界框可以是任意旋转的矩形。
OBB算法通过计算两个物体的边界框的碰撞轴来判断它们是否相交。
如果两个物体在每个碰撞轴上都有重叠区域,那么可以判断这两个物体发生了碰撞。
3. 圆形碰撞检测算法(Circle Collision Detection)圆形碰撞检测算法适用于游戏中的圆形物体。
对于两个圆形物体,我们可以通过计算它们的半径之和与它们的距离之差来判断是否发生了碰撞。
如果两个圆形物体的距离小于它们的半径之和,那么可以判断这两个物体发生了碰撞。
除了以上算法,还有一些更为复杂的碰撞检测算法,如分离轴定理(Separating Axis Theorem)和凸包碰撞检测算法(Convex Hull Collison Detection)。
这些算法更适用于处理具有复杂形状的物体的碰撞检测。
在实现碰撞检测算法时,可以利用游戏引擎的物理引擎来简化工作。
基于包围盒的碰撞检测算法研究碰撞检测是计算机图形学的重要组成部分,是实现自然和真实的计算机动画的关键技术。
本文将从基于包围盒的碰撞检测算法出发,研究碰撞检测算法的原理和实现,以及碰撞检测算法在计算机图形学领域的应用。
一、基于包围盒的碰撞检测算法碰撞检测是计算机图形学的主要类别之一,它的作用是根据事先定义的规则来检测物体之间的相互作用,检测结果可用于模拟物理效果。
基于包围盒的碰撞检测是检测碰撞的一种有效和常用的方式。
基于包围盒的碰撞检测算法的基本思想是将物体关联的几何模型用若干轴对齐的控制图形包围起来,形成一个外框,通常称为包围盒,以检测两个物体之间有没有碰撞。
碰撞检测的核心思想是根据两个物体的包围盒的位置和尺寸来判断两个物体之间的碰撞,也就是判断它们的可视范围是否有碰撞。
基于包围盒的碰撞检测算法可以分为两种,一种是偏斜包围盒(OBB)碰撞检测算法,另一种是三角形包围盒(TBB)碰撞检测算法。
偏斜包围盒(OBB)碰撞检测算法是由两个偏斜包围盒(OBBs)组成,两个偏斜包围盒之间判断其碰撞状态的算法称为Minkowski碰撞检测算法,他依赖于OBB模型的尺寸和位置,将两个包围盒投影到同一个坐标轴,比较投影之后的投影空间中实体的相对位置,从而判断物体是否相撞。
三角形包围盒(TBB)碰撞检测算法则采用两个三角形包围盒模型,判断两个三角形包围盒之间的碰撞状态则采用数学判定法,根据两个三角形包围盒的三角形点,计算出两个包围盒之间三角形点之间的距离,如果距离小于0,则表示发生碰撞,否则表示不发生碰撞。
二、碰撞检测算法的实现在计算机图形学领域中,实现碰撞检测算法的关键是创建几何模型,并根据不同的碰撞检测算法选择正确的几何模型。
几何模型通常有基本的几何模型,包括立方体、三棱柱、圆柱和球体等,也可以有更复杂的几何模型,如Torus、Bunny和Teapot等。
基本实现碰撞检测算法的步骤是:首先根据实际场景创建几何模型;然后根据不同的碰撞检测算法,按照几何模型的要求,获取各个包围盒的位置和尺寸;最后根据具体的碰撞检测算法,对这两个包围盒进行检测,判断物体之间是否发生碰撞。
OBBTree原理详解1. 引言OBBTree(Oriented Bounding Box Tree)是一种用于快速检索与三维物体相关的算法和数据结构。
它是基于包围盒(Bounding Box)和树状结构的思想构建而成,能够高效地处理三维物体的碰撞、相交等问题。
本文将详细介绍OBBTree的基本原理,包括数据结构、构建过程、查询过程以及应用场景等方面。
2. 数据结构OBBTree的数据结构包括两个主要部分:节点(Node)和包围盒(Bounding Box)。
2.1 节点(Node)节点是OBBTree的基本组成单元,每个节点代表一个三维物体或一组三维物体。
节点包含以下几个关键信息: - 包围盒(Bounding Box):用于表示该节点所代表的三维物体或物体组的边界范围。
包围盒是一个立方体,由最小点和最大点确定。
- 子节点(Children):指向该节点的子节点。
每个节点可以有零个或多个子节点。
- 父节点(Parent):指向该节点的父节点。
根节点的父节点为空。
- 数据(Data):存储与该节点相关的数据,如物体的属性信息。
2.2 包围盒(Bounding Box)包围盒是用于表示三维物体或物体组边界范围的几何形状。
它是一个立方体,由最小点和最大点确定。
包围盒的形状和大小与物体的形状和大小密切相关。
通过合理选择包围盒的大小和形状,可以提高OBBTree的查询效率。
3. 构建过程OBBTree的构建过程主要包括以下几个步骤:初始化、递归划分和叶节点处理。
3.1 初始化构建OBBTree之前,首先需要初始化根节点。
根节点的包围盒为整个三维场景的包围盒,即能够包围所有物体的最小立方体。
3.2 递归划分在初始化根节点之后,需要对根节点进行递归划分。
划分过程如下: 1. 选择一个合适的划分平面:根据根节点包围盒的形状和大小,选择一个合适的划分平面,将根节点划分为两个子节点。
2. 更新子节点的包围盒:根据划分平面,更新两个子节点的包围盒,使其能够包围相应的物体。
obb碰撞测试实现原理obb碰撞测试是计算机图形学中非常重要的一项技术,它可以用来检测两个物体之间是否发生了碰撞,为计算机游戏、动画和建筑模拟等应用提供了重要的支持。
这篇文章将从原理、实现方法和应用方面全面介绍obb碰撞测试。
1.obb碰撞测试原理obb(Oriented Bounding Box)指的是朝向包围盒,它是一种常用的包围盒形状。
obb碰撞测试的原理就是根据每个物体的obb,检测两个obb之间是否相交,如果相交则说明两个物体发生了碰撞。
obb包围盒会根据物体的形态和朝向自动变化,因此obb碰撞测试不仅可以精确检测物体间的碰撞,还能够适用于各种形态的物体。
obb包围盒的形状通常为长方体,既可以是正交长方体也可以是任意朝向的长方体。
2.obb碰撞测试实现方法obb碰撞测试的实现方法基本可以分为以下四步。
第一步,建立obb包围盒。
对于每个物体,都需要建立其obb包围盒,使其既能完全包含物体,同时又能尽量地减小其尺寸。
第二步,obb包围盒的系数计算。
需要计算出obb包围盒的中心点、长宽高和其他相关系数,以便后续的计算。
第三步,obb碰撞测试算法。
obb碰撞测试通常使用分离轴算法(Separating Axis Theorem,SAT)实现。
这个算法根据obb包围盒的外表面积来计算两个obb包围盒之间是否存在相交。
第四步,碰撞检测结果处理。
如果obb碰撞测试发现两个obb包围盒之间存在相交,就说明物体之间产生了碰撞,需要处理相应的碰撞结果。
3.obb碰撞测试的应用obb碰撞测试广泛应用于计算机游戏、动画和建筑模拟等领域,为这些应用提供了重要的支持。
obb碰撞测试可以用来检测游戏中的角色之间是否发生碰撞,帮助实现更加真实的游戏体验。
在3D建筑模拟领域,obb碰撞测试可以用来检测建筑物之间的碰撞,判断建筑物是否符合规范。
此外,obb碰撞测试还可以用于机器人导航、汽车碰撞检测和对象抓取等领域,为这些应用提供了更加可靠的检测方法,帮助人们更好地实现自己的目标。
obb碰撞方法OBB碰撞方法也被称为矩形包围盒碰撞检测,是一种经典的游戏碰撞检测方法。
OBB碰撞方法通常用于检测两个矩形是否相交,可以用于2D和3D游戏。
OBB碰撞方法的实现可以分为以下步骤:1.计算物体的矩阵变换在进行OBB碰撞检测之前,需要先计算出每个物体的矩阵变换。
矩阵变换包括平移、旋转和缩放等操作,以及一个矩阵传递物体的位置、方向和大小。
2.将物体信息转换为OBB包围盒然后我们需要将物体信息转换为OBB包围盒。
OBB包围盒包含矩形的中心点、旋转角度和半径。
这可以通过计算物体的顶点坐标来实现。
通过计算出所有顶点坐标的平均值得到OBB包围盒的中心点,然后把每个顶点的坐标减去中心点得到每个顶点相对于中心点的偏移量。
之后我们可以用偏移量来计算物体的旋转角度和半径。
3.进行矩形投影接着我们需要进行矩形投影。
我们在每个物体的OBB包围盒上取出3个相对抽象的向量(例如物体本身的X/Y/Z轴),然后将它们扩展成单位长度向量。
在接下来的检测中,我们将任意形状的物体转换为这三个向量所描述的矩形。
4.检测矩形是否相交最后,我们需要检测两个矩形是否相交。
这可以通过检查两个矩形在每个轴上的投影是否有重叠来实现。
我们可以计算出每个矩形在三个相对抽象的向量上的投影,然后用这些投影信息来检测两个矩形是否在某个轴上有重叠。
如果两个矩形在三个轴上都有重叠,则它们相交。
如果没有重叠,则它们没有碰撞。
由于计算过程涉及到向量的加法、减法和点积等操作,所以OBB碰撞方法需要一定的数学基础。
但是,这个方法的准确度非常高,因此在游戏碰撞检测中广泛应用。
三维物体碰撞检测包围盒算法分析随着计算机技术的发展,人们对虚拟现实、分布式交互仿真的需求大大推动了计算机图形学的发展。
碰撞检测,特别是软体碰撞检测问题开始成为研究的热点。
主要介绍AABB(沿坐标轴的包围盒)和OBB(方向包围盒)算法两种常用包围盒技术,并从效率、难易程度等方面对其进行比较,结合AABB算法和OBB算法,提出一种改进算法,在一个具有大量静态对象的场景中,先利用AABB算法测试静态物体和动态物体的碰撞,然后通过AABB算法过滤后的动态物体则使用OBB 算法进行碰撞检测。
试验结果表明,该方法在进行精确的碰撞检测时,性能有明显的提高。
标签:虚拟现实;碰撞检测;AABB;OBB;包围盒1 算法思想包围盒算法是目前三维交互软件中常用的碰撞检测算法,其优点是能够实现快速碰撞检测。
在这里最具代表性的就是AABB算法和OBB算法。
1.1 轴平行包围盒AABB 算法AABB(Axis-Aligned Bounding Box)是进行碰撞检测的三维几何体的外接平行六面体,它的每条边都平行于坐标轴。
因此描述一个AABB包围盒只需要六个标量,在构造AABB时,要沿着物体的局部坐标系的轴向进行构造。
故由AA BB 构造的包围盒具有一致的方向。
图1给出了一个使用AABB包围盒的例子,它可以很简单确定包围盒的尺寸,AABB内的任意一点P(x,y,z)都需满足: 从AABB包围盒的构造过程分析,它的优点有以下几点:(1)构造难度低。
因为只需分别计算物体各个元素顶点的x、y、z坐标的最大值和最小值,如果一个顶点的个数为n,只需6n次比较运算。
(2)存储量很小。
只需6个浮点数。
(3)相交测试复杂度低。
由于立方体有六个面,所以只需在xy、xz、yz 三个面投影两个物体6个面,故只需计算6次即可。
(4)变形物体碰撞适用度较大。
与OBB算法相比其缺点是紧密性较差,尤其是对具有凹凸面的多面体,用AABB将留下很大空隙,导致大量的冗余包围盒相交测试。
一种基于OBB的三维医学碰撞检测算法
赵军
【期刊名称】《兰州交通大学学报》
【年(卷),期】2008(027)003
【摘要】在三维医学可视化系统中,对绘制场景中的多个三维对象进行碰撞检测的研究具有很重要的意义.利用VTK的面绘制特性,在方向包围盒层次树的基础上,提出了一种新的快速碰撞检测算法.算法在继承了一般基于方向包围盒的碰撞检测算法优点的同时,对大部分不可能发生碰撞的三角面片进行了排除,并使用相交检测法进行碰撞的精确检测.实验结果证明,该算法提高了碰撞检测的效率.
【总页数】3页(P101-103)
【作者】赵军
【作者单位】兰州交通大学,电子与信息工程学院,甘肃,兰州,730070
【正文语种】中文
【中图分类】TP391.9
【相关文献】
1.一种基于OBB矩形碰撞检测算法的r堆取料机防碰撞方法 [J], 尹艳艳;吕崇晓
2.基于Sphere-OBB的改进碰撞检测算法及其应用 [J], 蒋健勋;方志刚;徐洁;王晓池
3.基于OBB包围盒碰撞检测算法的改进 [J], 刘超;蒋夏军;施慧彬
4.基于改进OBB包围盒的碰撞检测算法 [J], 史旭升;乔立红;朱作为
5.一种基于OBB的碰撞检测算法的改进 [J], 章勤;黄琨;李光明
因版权原因,仅展示原文概要,查看原文内容请购买。
基本原理碰撞测试在计算机图形学中,碰撞测试是一种用于判断两个或多个物体是否发生碰撞的技术。
在游戏开发中,碰撞测试是非常重要的,它可以用来确定物体的位置、运动轨迹以及与其他物体的交互。
其中,obb碰撞测试是一种基于轴对齐包围盒(Oriented Bounding Box,OBB)的碰撞测试方法。
轴对齐包围盒轴对齐包围盒是一个包围物体的最小的矩形盒子,它的边与坐标轴平行。
在二维情况下,它可以表示为一个矩形,其边与x轴和y轴对齐,以物体的位置和大小为基础进行设置。
在三维情况下,它可以表示为一个长方体,其边与x轴、y轴和z轴对齐。
轴对齐包围盒的主要作用是简化碰撞测试的计算,它可以快速判断物体之间是否相交。
OBB碰撞测试obb碰撞测试是一种基于轴对齐包围盒的碰撞测试方法,它可以判断两个obb是否相交。
obb的主要特点是可以沿任意轴进行旋转,因此obb碰撞测试可以处理具有不规则形状的物体。
obb碰撞测试主要包括以下几个步骤:1.计算obb的包围盒:将obb表示为轴对齐包围盒,计算其八个顶点的位置,得到obb的包围盒。
2.计算obb的法线:通过obb的旋转矩阵,可以计算出obb的法线。
3.计算obb的投影:将obb的包围盒在obb的每个法线上进行投影,得到obb在每个法线上的投影长度。
4.判断obb是否相交:对于两个obb,分别计算它们在各自的法线方向上的投影长度,如果两个obb在所有的法线方向上的投影长度都有重叠,则认为它们相交。
实现原理obb碰撞测试的实现原理是基于obb的包围盒和obb的投影来判断两个obb是否相交。
下面将详细解释obb碰撞测试的实现原理。
首先,我们需要计算obb的包围盒。
obb的包围盒可以通过obb的中心点、长宽高以及旋转角度来计算得到。
首先,我们将obb的中心点和长宽高转换成obb的八个顶点的位置。
通过obb的旋转矩阵,我们可以将obb的包围盒从obb的局部坐标系转换到世界坐标系。
接下来,我们需要计算obb的法线。
游戏中的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;}}}效果。
基于OBB碰撞检测的高效三角形相交测试李明博(韩国汉城国立大学计算机科学与工程系,汉城151-744)摘要:针对基于方向包围盒的碰撞检测,提出一种高效的三角形相交测试算法。
在测试两个方向包围盒的叶节点(例如矩形),许多中间计算结果可以在它们所包含的两个三角形相交测试中重复使用。
当我们在边界矩形的局部坐标而不是在物体的全局坐标中工作时,更容易检测冗余操作。
我们算法的性能改善就是基于这种消除冗余操作的观测。
与传统算法相比,我们在计算时间上已经有15-79%的改善。
我们将通过几个实验结果来验证此方法的效率。
关键字:三角形相交;方向包围盒;碰撞检测;坐标描述1.引言碰撞检测在各种各样的应用中都很重要,在这里仅举几个例子,如计算机图形学,动画,游戏以及机器人。
方向包围盒(OBB)的层次包围体(BVH)技术经常应用在三维空间带有三角网格的三围物体之间的碰撞检测[1]。
其他传统的边界包围体包括球体,轴对齐包围盒(AABB),k-discrete orientation polytope (k-DOP) ,以及line swept sphere(LSS)[2]。
BVH 是包围体构建的树。
BVH的每一个节点是限定基元相应设置的物体。
BVH的叶节点通常限定单基元。
本文专注于基于OBB的层次包围体技术和三角网格之间的碰撞检测,我们会展现如何通过使用检测OBB叶节点的结果加速三角形相交测试。
OBB树的叶节点是限定单一三角形的矩形。
因此,三角相交测试由限定它们的矩形的类似测试来计算。
通过循环计算矩形测试结果,我们可以让三角测试比以往从零开始进行相交测试的传统方法[3-6]更加高效。
在实验测试结果中,我们已经观测到计算时间有15-79%的改善。
测试两个三角形之间的相交测试的第一步是要将其中一个三角形坐标转换到另一个三角形的坐标系统中。
这是一个耗费大的程序。
在基于OBB的环境中,我们发现可以通过循环使用矩形包围体的相似转换来简化这个步骤。
基于obb的碰撞检测算法原理
概述
在计算机图形学和物理引擎中,碰撞检测是一项重要的技术,用于判断两个或多个物体是否发生了碰撞。
而obb(Oriented Bounding Box)是一种常用的包围盒形状,它可以用来近似表示一个物体的形状,并且相比于其他包围盒形状更加紧凑。
基于obb的碰撞检测算法利用obb包围盒来检测两个物体之间是否发生了碰撞。
本文将详细介绍obb碰撞检测算法的原理及实现方法。
碰撞检测原理
obb碰撞检测算法主要分为两个步骤:obb变换和obb之间的分离轴测试。
1. obb变换
首先,我们需要将每个物体的包围盒转化为一个与世界坐标系无关(即与旋转、缩放无关)的局部坐标系。
这样做是为了简化计算和提高效率。
对于每个物体,我们可以通过以下步骤来进行obb变换: 1. 计算物体的包围盒中心点。
2. 计算物体相对于包围盒中心点的坐标。
3. 计算物体的包围盒的旋转角度。
4. 计算物体的包围盒的缩放比例。
通过这些计算,我们可以得到每个物体在局部坐标系下的obb包围盒。
2. 分离轴测试
obb之间的分离轴测试是obb碰撞检测算法的核心部分。
它用于判断两个obb之间是否存在一个分离轴,如果存在,则说明两个obb不相交,即没有发生碰撞。
对于每一对obb(A和B),我们需要检查以下情况: 1. 对于A和B来说,它们各自的三个主轴(也可以是其他合适的轴)是否是分离轴。
2. 对于A和B来说,它们各自的三个边界框面(也可以是其他合适的面)是否是分离轴。
3. 对于A和B来说,它们各自的九个边界框边(也可以是其他合适的边)是否是分离轴。
如果在任何一个情况下都找到了一个分离轴,则说明两个obb不相交。
否则,它们发生了碰撞。
3. 分离轴测试详解
a) 主轴测试
对于主轴测试,我们需要判断obb的主轴是否是分离轴。
obb的主轴是obb包围盒的三个坐标轴,即x轴、y轴和z轴。
为了判断两个obb之间的碰撞,我们需要检查以下情况: 1. 对于A和B来说,它们各自的x轴是否是分离轴。
2. 对于A和B来说,它们各自的y轴是否是分离轴。
3. 对于A和B来说,它们各自的z轴是否是分离轴。
对于每个主轴,我们需要计算A和B在该主轴上的投影,并判断它们之间是否存在重叠。
如果不存在重叠,则说明该主轴是一个分离轴。
b) 边界框面测试
边界框面测试用于判断obb包围盒的面是否是分离轴。
obb包围盒有六个面,即前、后、左、右、上和下。
为了判断两个obb之间的碰撞,我们需要检查以下情况: 1. 对于A和B来说,它们各自的前面是否是分离轴。
2. 对于A和B来说,它们各自的后面是否是分离轴。
3. 对于A和B来说,它们各自的左侧面是否是分离轴。
4. 对于A和B来说,它
们各自的右侧面是否是分离轴。
5. 对于A和B来说,它们各自的上面是否是分离轴。
6. 对于A和B来说,它们各自的下面是否是分离轴。
对于每个面,我们需要计算A和B在该面上的投影,并判断它们之间是否存在重叠。
如果不存在重叠,则说明该面是一个分离轴。
c) 边界框边测试
边界框边测试用于判断obb包围盒的边是否是分离轴。
obb包围盒有12条边。
为了判断两个obb之间的碰撞,我们需要检查以下情况: 1. 对于A和B来说,它们各自的12条边是否是分离轴。
对于每条边,我们需要计算A和B在该边上的投影,并判断它们之间是否存在重叠。
如果不存在重叠,则说明该边是一个分离轴。
算法实现
基于obb的碰撞检测算法可以通过以下步骤进行实现:
1.计算每个物体的obb包围盒。
2.对于每一对物体(A和B),执行以下步骤:
–进行主轴测试:计算A和B在x、y、z轴上的投影,并判断是否存在重叠。
–进行边界框面测试:计算A和B在前、后、左、右、上和下面上的投影,并判断是否存在重叠。
–进行边界框边测试:计算A和B在每条边上的投影,并判断是否存在重叠。
–如果在以上任何一个步骤中找到了一个分离轴,则说明两个obb不相交,即没有发生碰撞。
–如果以上步骤都通过了,则说明两个obb发生了碰撞。
总结
obb碰撞检测算法是一种常用且有效的碰撞检测方法。
它利用obb包围盒来近似表
示物体形状,并通过obb变换和分离轴测试来判断两个obb之间是否发生了碰撞。
该算法可以应用于计算机图形学、物理引擎等领域,用于实现真实感的物体交互和碰撞效果。
需要注意的是,obb碰撞检测算法虽然简单易懂,但在处理大量物体或复杂场景时
可能会带来性能问题。
因此,在实际应用中需要根据具体情况选择合适的优化策略,例如使用层次包围盒(BVH)等数据结构来加速碰撞检测过程,从而提高算法的效
率和可扩展性。