多边形碰撞 -- SAT方法
检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理。

原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠。如果不重叠,则认为这两个多边形是分离的,否则找下一条向量来继续投影。我们不需要比较很多条向量,因为已经在数学上证明,多边形每条边的垂直向量就是我们需要的向量。
1.AABB
让我们首先以AABB开始(AABB是一种两边分别平行于X-Y轴的矩形)
判断两个AABB是否碰撞,我们只需要投影两次,分别是投影在平行于X轴和Y轴的向量上

由上图可以看见,因为在Y轴方向的投影是分离的,因此可以直接得出结论,即这两个AABB是分离的。
function AABBvsAABB(aabb1, aabb2) {
//check X axis
if(aabb1.xMin > aabb2.xMax)
return false;
if(aabb1.xMax < aabb2.xMin)
return false;
//check Y axis
if(aabb1.yMin > aabb2.yMax)
return false;
if(aabb1.yMax < aabb2.yMin)
return false;
return true;
}
效果:---点击运行---
(点击产生AABB,碰撞的变红,否则变黄)

2.圆
圆的碰撞检测也能用SAT,就是要把两个圆投影在两个圆心连线的向量上。比较半径和与圆心距离,如果半径和大于圆心距离则碰撞。

代码:
注:通常为了优化,都是用平方而不是开方(sqrt好慢的)
function CircleVsCircle(c1, c2) {
var xSqr = c1.centerX - c2.centerX;
xSqr *= xSqr;
var ySqr = c1.centerY - c2.centerY;
ySqr *= ySqr;
//get the distance^2
var distanceSqr = xSqr + ySqr;
var radiusSum = c1.radius + c2.radius;
if(distanceSqr <= radiusSum*radiusSum)
return true;
else
return false;
}
效果:---点击运行---
(点击产生圆)

3.多边形
(1)找出两个多边形所有边的垂直向量;

(2)将两个多边形投影到垂直向量上,判断投影是否相交,如果不相交则两个多边形不相交,否则选下一条垂直向量继续进行投影判断。

代码:
function PolyVsPoly(p1, p2) {
//check the normal in p1
for(var i = 0; i < p1.points.length-1; i++) {
var edge = Minus(p1.points[i], p1.points[i+1]);
var normal = Normal(edge);
var isOverlap = CheckCollide(normal, p1, p2);
if(!isOverlap)
return false;
}
//check normal in p2
for(var i = 0; i < p2.points.length-1; i++) {
var edge = Minus(p2.points[i], p2.points[i+1]);
var normal = Normal(edge);
var isOverlap = CheckCollide(normal, p1, p2);
if(!isOverlap)
return false;
}
return true;
}
function CheckCollide(axis, p1, p2) {
var min1 = Dot(p1.points[0], axis);
var max1 = Dot(p1.points[0], axis);
for(var k = 1; k < p1.points.length; k++) {
var v = Dot(p1.points[k], axis);
if(v > max1)
max1 = v;
if(v < min1)
min1 = v;
}
var min2 = Dot(p2.points[0], axis);
var max2 = Dot(p2.points[0], axis);
for(var k = 1; k < p2.points.length; k++) {
var v = Dot(p2.points[k], axis);
if(v > max2)
max2 = v;
if(v < min2)
min2 = v;
}
if(!IsOverlap(min1, max1, min2, max2))
return false;
return true;
}
效果:---点击运行---
(使用方向键来移动,碰撞的变红,否则变黄)


4.圆与多边形
(1)找出多边形每条边的垂直向量,多边形最接近圆心的点到圆形的直线的垂直向量
(2)将圆和多边形投影到垂直向量上,再进行判断。
(其实和多边形之间的碰撞很像,这里就不浪费篇幅了)
总结:
SAT很简单,就是投影 + 重叠判断。
SAT只适用于凸体,毕竟凹体中间空缺的部分在投影后信息就消失了。
一些关于SAT的网站:
多边形碰撞 -- SAT方法的更多相关文章
- 解决Hash碰撞冲突方法总结
Hash碰撞冲突 我们知道,对象Hash的前提是实现equals()和hashCode()两个方法,那么HashCode()的作用就是保证对象返回唯一hash值,但当两个对象计算值一样时,这就发生了碰 ...
- 2D多边形碰撞器优化器
http://www.unity蛮牛.com/thread-19827-1-1.html http://pan.baidu.com/s/1qW2mWS8 Asset Store Link: http: ...
- H5游戏开发之多边形碰撞检测
2D多边形碰撞检测介绍这是一篇论证如何在2D动作游戏中执行碰撞检测的文章(Mario,宇宙入侵者等),为了保证它的高效性和精确性,碰撞检测是以多边形为基础的,而不是以sprite为基础.这是两种不同的 ...
- [Unity2D]Box Collider 2D盒子碰撞器
盒子碰撞器(BoxCollider2D)是Unity2D中常用的碰撞器,所有为碰撞器,顾名思义,就是用于检测物体之间的碰撞情况的,Unity2D里面除了BoxCollider2D碰撞器之外还集成Box ...
- cocos 碰撞系统
前面的话 本文将简要介绍 Cocos Creator 中的碰撞系统,Cocos Creator 内置了一个简单易用的碰撞检测系统,支持圆形.矩形以及多边形相互间的碰撞检测 编辑碰撞组件 当添加了一个碰 ...
- 结合谷歌地图多边形(polygon)与Sql Server 2008的空间数据类型计算某个点是否在多边形内的注意事项
首先在利用 GEOGRAPHY::STPolyFromText(@GeoStr, 4326) 这样的函数把字符串转换为Geography类型时,字符串里经纬度的顺序是 “经度[空格]纬度”,即“lon ...
- HDOJ(1115)多边形重心
Lifting the Stone http://acm.hdu.edu.cn/showproblem.php?pid=1115 题目描述:输入n个顶点(整数),求它们围成的多边形的重心. 算法:以一 ...
- unity触发器和碰撞器
Unity中检测碰撞的方法有两种,一种是触发器一种是碰撞器,现在我来解释一下两种的区别. 触发器:有三种方法,分别是OnTriggerEnter,OnTriggerStay,OnTriggerExit ...
- iOS7 UIKit动力学-碰撞特性UICollisionBehavior 下
上文讲到了为window加一个边界.实现碰撞的效果,接下来我们将提到一个托付方法: - (void)collisionBehavior:(UICollisionBehavior *)behavior ...
随机推荐
- Windows10更新提示语言不同不能保留程序和设置
打开注册表编辑器(Win+R,输入regedit)定位到: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Nls\Language 在右边窗口中拉到最 ...
- HDU 3966 Aragorn's Story 树链剖分
Link: http://acm.hdu.edu.cn/showproblem.php?pid=3966 这题注意要手动扩栈. 这题我交g++无限RE,即使手动扩栈了,但交C++就过了. #pragm ...
- embed标签loop=true背景音乐无法循环
在html网页中加入背景音乐并设置为循环播放.一开始用<embed>标签,设置loop="true", 但是结果发现在IE浏览器可以,但是在chrome浏览器却无法实现 ...
- Windows7 + Ubuntu双系统安装过程记录
本文为在已安装Windows7系统的前提下安装Ubuntu Kylin 14.10系统的过程以及期间出现的各种问题的记录. Ubuntu系统下载 Ubuntu Kylin中文官方网站:http://w ...
- VMware中的Ubuntu网络设置
网络配置: VMware安装后会有两个默认网卡,分别是VMnet8(192.168.83.1)和VMnet1(192.168.19.1),当然不同的机器上,这两个网卡的 IP会不同的.在windows ...
- ecshop二次开发常用文件位置
语言包修改: /language/zh_cn/admin/common.php 商品详情页模板: /themes/**/goods.dwt (最下方有changePrice() 点选属性或改变数量时 ...
- VR系统的分类
转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 根据用户参与和沉浸感的程度,通常把虚拟现实分为4大类:桌面虚拟现实系统.沉浸式虚拟现实系统.增强虚拟现实 ...
- sql server 对象资源管理器(二)
SQL会缓存大量的数据页面,他还会缓存很多其他信息,包括存储过程的执行计划 ,特定用户的安全上下文等 如果这些信息没有在数据库中缓存,SQL都要重新计算一遍,花额外的时间,所以SQLSERVER对内存 ...
- codeigniter框架The URI you submitted has disallowed characters错误解决方法
CI中URI传递参数时,出现:The URI you submitted has disallowed characters.错误 .原因:这是由于uri中存在CI不允许的字符 . 解决办法:在con ...
- 3.通过现有的PDB创建一个新的PDB
实验说明:创建PDB除了可以通过种子PDB创建外,现在测试通过一个现有的用户PDB克隆创建新的PDB数据库 实验步骤: 1.创建测试数据 SQL> alter session set conta ...