序言

此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法。如有其它见解,可以跟作者商讨。(杨子剑,zijian_yang@yeah.net)。

在一个世界中,有多个物体,物体可以分为运动的物体和静止的物体和地形。而世界是很宽广的,本文致力在处理物体之间的碰撞,地形的碰撞后续处理。

处理流程

世界是宽广的,同样世界中物体也是多个的。每个物体一直频繁的检测是浪费效率的(毕竟运动的物体和根本碰不到的物体检测完全没必要)。

分为两个阶段:粗检测(筛选出来会碰撞到的物体) – 细检测(两两碰撞检测)

GJK算法

Gjk算法最初是用来算两个物体的具体,之后因为稳定和快捷,可以用来初检测碰撞。

原理:是算两个物体的顶点差,其实就是距离,得出顶点距离的集合,算出来的多边形是否包含原点,当包含则两物体相交。

SAT分离轴算法

分离轴算法,可以很好的检测出来碰撞点和碰撞点的深度。

原理:当两物体相交,那这两物体从任意方向看过去都是相交的。对应的就是在各个方向的投影都有交叠。

粗检测-空间分割

四叉树

面分割方法,世界大小的正方体是根节点,同等分割四份如果一个物体在一个分支中,找到最小能容纳他的正方体分支。一般情况是根据x y 来分割。

八叉树

空间分割法,其实是比四叉树多一个z的方向的分割,是三维的。

松散四叉树/八叉树

松散八叉树其实是为了解决边界问题,当一个物体在四叉树边缘不断的从一个区域到另一个区域会导致节点不断的更新节点,层级也会发生变化,为了解决这一问题,提出了两个概念。

  1. 入口边界,入口边界等于四叉树/八叉树的真正边缘。
  2. 出口边界,出口边界比四叉树/八叉树的真正边缘大。

 出口边缘具体大多少没有一个明确的定义,大多数为如果边缘的2倍。

当物体移动时,先判断是否出出口边缘,如果没出,则还在当前节点和深度,如果出了则从新寻找入口边缘找到对应的深度和节点。

层次包围盒树

层次包围树用于精确检测,当一个物体的形状是复杂的,多个不规则多边形组合在一起的时候,用此方法最好。例如人由头、身体、手、脚组成,当各个部位运动时,从下往上递归改变父节点的包围盒。

还有一种用法是,当其中一个物体在空间中改变位置的时候,pop形状-刷新分支节点包围盒-重新加入包围盒树,计算bvh。

一般包围盒形状是统一的,aabb、球、或者box。

球构造很快(圆心和半径)。

碰撞检测快,因为当父节点aabb不想交或者射线检测不到,则子节点无需检测。

细检测-运动中物体检测

当物体在代码中模拟运动的时候,是离散的状态,每次经过dt的时间计算下一次的碰撞。碰撞的两物体因为dt的时间长短,很有可能发生穿插的问题。下面介绍了两种检测方法。

连续碰撞检测

把这段状态积分化,或者函数化,求导数的极致,来求得最后在dt中某个时间的碰撞。大连理工大学机械工程学院《凸多面体连续碰撞检测的运动轨迹分离轴算法》- 2013

1月张应中发表,这篇论文实际是应用了gjk的理论,并加上射线检测,求得最终的碰撞点。里面的算法名称叫做lccd。

天津大学电气与自动化工程学院《基于gjk的凸体快速连续碰撞检测研究》-2014年10月刘丽发表,fccd算法,用于连续检测碰撞。

上述两种检测算法,因为都需要模拟中间一段的求极值得过程,实际效率并不如下面的非连续碰撞检测。优点则是可以准确的求得当前碰撞的时间和点。

非连续碰撞检测

非连续碰撞其实跟当前dt一样,求当前帧是否碰撞。但如果精度不够,可以继续缩小精度,当人物在dt的过程中,可以认为一切的变化都是线性的,所以可以通过线性求得dt/8(再细分8次)的过程的装态,判断8次中有没有碰撞。如果精度不够,则可以再继续划分精度,求得更精细的离散过程。中间当然可以先判断是否有可能在离散过程中可能碰撞。

物体与场景碰撞

其实是物体跟三角形求出最近点,不让穿透。射线检测求相交。

物体形状碰撞效率

多边形和不规则多边形的碰撞检测,有规律的多边形,一般为三角面,长方体(box),aabb包围盒、球体、胶囊体。圆柱等。

不规则的多边形需要是凸多边形(gjk和sat算法都需要是凸多边形),如果不是,需要通过算法来把一个物体变为多个形状。

现有的算法三角面、aabb、球体、胶囊体是可以通过他们的特殊性快读求得相交。而其他的需要通过sat具体来算出交点。Sat是a边型与b边型求交, 如果不交,则很快能得出, 相交需要判断O(a*b)。

总结

 算法最后还需要根据实际场景来选择。

世界碰撞算法原理和总结(sat gjk)的更多相关文章

  1. (转)RSA算法原理

    RSA算法原理(二)   作者: 阮一峰 日期: 2013年7月 4日 上一次,我介绍了一些数论知识. 有了这些知识,我们就可以看懂RSA算法.这是目前地球上最重要的加密算法. 六.密钥生成的步骤 我 ...

  2. 微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)

    1.点评 对于IM系统来说,如何做到IM聊天消息离线差异拉取(差异拉取是为了节省流量).消息多端同步.消息顺序保证等,是典型的IM技术难点. 就像即时通讯网整理的以下IM开发干货系列一样: <I ...

  3. 【PPT详解】曹欢欢:今日头条算法原理

    [PPT详解]曹欢欢:今日头条算法原理 悟空智能科技 4月8日 公众号后台回复:“区块链”,获取区块链报告 公众号后台回复:“sq”,进入区块链分享社群 热文推荐: 1000位专家推荐,20本区块链必 ...

  4. Paxos发展、算法原理

    Paxos 发展史 Leslie Lamport所提出的Paxos算法是现代分布式系统中的一项重要的基础性技术,得到广泛的应用. Paxos的整个发展过程大概可以分为三个阶段: 第一阶段:萌芽期,大致 ...

  5. 如何做系列(4)-微博URL短网址生成算法原理(java版、php版实现实例)

    短网址(Short URL),顾名思义就是在形式上比较短的网址.通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代 ...

  6. Bagging与随机森林算法原理小结

    在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...

  7. RSA算法原理

    一直以来对linux中的ssh认证.SSL.TLS这些安全认证似懂非懂的.看到阮一峰博客中对RSA算法的原理做了非常详细的解释,看完之后茅塞顿开,关于RSA的相关文章如下 RSA算法原理(一) RSA ...

  8. LruCache算法原理及实现

    LruCache算法原理及实现 LruCache算法原理 LRU为Least Recently Used的缩写,意思也就是近期最少使用算法.LruCache将LinkedHashMap的顺序设置为LR ...

  9. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

随机推荐

  1. C语言实现数据机构链表的基本操作(从键盘输入生成链表、读取数组生成链表)

    利用头插法实现逆置 下面简单介绍一下,算法思想结合图示看 算法思想:"删除"头结点与链表其他结点的原有联系(即将头结点的指针置空),再逐个插入逆置链表的表头(即"头插&q ...

  2. 原生JavaScript封装的jsonp跨域请求

    原生JavaScript封装的jsonp跨域请求 <!DOCTYPE html> <html lang="en"> <head> <met ...

  3. 记录jmeter使用beanshell断言获取复杂的json字符串参数值

    实战示例 测试场景 电商系统经常会涉及到商品的库存数量的压测,在用户下单前需要先做库存余量的判断,当余量不足时用户无法下单,保证商品的有效售卖 库存余量查询响应结果 响应结果一般是json字符串的形式 ...

  4. android.widget.TextView.setText() on a null object reference

    错误描述 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView. ...

  5. 【Vulhub】CVE-2019-3396 Confluence RCE漏洞复现

    CVE-2019-3396 Confluence RCE漏洞复现 一.环境搭建 选择的vulhub里的镜像,进入vulhub/Confluence/CVE-2019-3396目录下,执行 docker ...

  6. C# Redis分布式锁(RedLock) - 多节点

    Redis单节点的分布式锁只需要注意三点就可以了: 1.加锁并设置锁的过期时间必须是原子操作; 2.锁的value值必须要有唯一性; 3.释放锁的时候要验证其value值,不是自己加的锁不能释放. 但 ...

  7. MATLAB中exist函数的用法

    exist:exist主要有两种形式,一个参数和两个参数的,作用都是用于确定某值是否存在:1. b = exist( a)      若 a 存在,则 b = 1: 否则 b = 0:2. b = e ...

  8. Activity的常用控件

    TimerPick(时间控件)public Integer getCurrentHour() //返回当前设置的小时public Integer getCurrentMinute()//返回当前设置的 ...

  9. CentOS7.7 系统下 virbr0 虚拟网卡的维护与管理

    在 CentOS 7 系统的安装过程中,如果有选择相关虚拟化的的服务安装系统后,启动网卡时会发现有一个以网桥连接的私网地址的 virbr0 网卡,这个是因为在虚拟化中有使用到 libvirtd 服务生 ...

  10. Java防止文件被篡改之文件校验和

    Java防止文件被篡改之文件校验和转载:请注明出处,谢谢! 1.为什么要防止文件被篡改?  答案是显然的,为了保证版权,系统安全性等.之前公司开发一个系统,技术核心是一个科学院院士的研究成果,作为一款 ...