分离轴定理SAT及碰撞检测

1.简介

分离轴理论,简称SAT(SeparatingAxisTheorem),通过判断任意两个凸多边形在任意角度下的投影是否均存在重叠,来判断是否发生碰撞。即两个不相交的多边形一定能找到一条轴,它们在这条轴上的投影不相交,可以理解为存在一个角度用电筒照这两个不相交多边形得到不相交的投影。此理论可以用于找到最小的渗透向量,此向量在物理模拟和其他很多应用中很有用。
注意:分离轴定理只适合凸多边形,所以如果是凹多边形的话需要转换成多个凸多边形。可以参考:二维多边形分解为凸块的库

2.分类

二维平面上常用的有三种:
在这里插入图片描述

2.1 球体

也就是将物体都等效为外接圆/外接球,利用球/圆来检测两个多边形是重合是及其方便的:圆心的距离和半径之和比较即可。

这种方法的优点缺点是如此明显:

优点:运算速度快
缺点:精度低
2.2 Axis Aligned Bounding Box(AABB)

从名称中大致能理解其中意思:沿着轴的包围盒子。也就是将物体用方形的盒子包围,这个方形的盒子的四条边都是和坐标轴平行的。

这种方法的相比于圆的碰撞检测,精度提高很多,

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SAT算法(Separating Axis Theorem,分离定理)是一种常用于二维和三维碰撞检测的算法。它的基本思路是,如果两个物体之间不存在分离(即二者的投影重叠),则它们一定发生了碰撞。下面我们以二维碰撞检测为例,给出一个基于SAT算法的示例。 假设我们有两个矩形,分别用四个顶点表示为: 矩形A:A1(x1, y1), A2(x2, y1), A3(x2, y2), A4(x1, y2) 矩形B:B1(x3, y3), B2(x4, y3), B3(x4, y4), B4(x3, y4) 首先,我们需要找到所有可能成为分离线。对于一个矩形而言,其边界上的法向量即可作为该矩形的分离。因此,我们需要计算出矩形A和矩形B的所有边界法向量,共计8条。具体计算方法如下: 矩形A的边界法向量: - AB1: (y2 - y1, -(x2 - x1)) - A1A4: (-(y2 - y1), x2 - x1) - A4A3: (y2 - y1, -(x2 - x1)) - A3A2: (-(y2 - y1), x2 - x1) 矩形B的边界法向量: - B1B2: (y4 - y3, -(x4 - x3)) - B2B3: (-(y4 - y3), x4 - x3) - B3B4: (y4 - y3, -(x4 - x3)) - B4B1: (-(y4 - y3), x4 - x3) 然后,我们需要将矩形A和矩形B分别投影到每个分离上,并计算它们在该上的投影重叠程度。如果存在任意一条分离上二者的投影不重叠,则二者一定不相交。具体计算方法如下: 对于一条分离(axis_x, axis_y),矩形A在该上的投影长度为: projA = (axis_x * x1 + axis_y * y1, axis_x * x2 + axis_y * y2, axis_x * x3 + axis_y * y3, axis_x * x4 + axis_y * y4) 即将矩形A的四个顶点坐标(x, y)带入分离的方程(ax + by = c)中,得到该点在该上的投影长度。 同理,矩形B在该上的投影长度为: projB = (axis_x * x3 + axis_y * y3, axis_x * x4 + axis_y * y4, axis_x * x1 + axis_y * y1, axis_x * x2 + axis_y * y2) 接下来,我们需要判断投影重叠程度。如果二者在该上的投影重叠,则它们在该上没有分离。否则,它们在该分离。判断投影重叠程度的方法如下: maxA = max(projA) minA = min(projA) maxB = max(projB) minB = min(projB) 如果maxA < minB 或者 maxB < minA,则二者在该分离。 最后,我们需要判断所有可能的分离上二者是否都有重叠。如果所有分离上二者都有重叠,则它们相交;否则,它们不相交。具体实现如下: def check_collision(A, B): for axis_x, axis_y in A.edges + B.edges: projA = [axis_x * x + axis_y * y for x, y in A.vertices] projB = [axis_x * x + axis_y * y for x, y in B.vertices] maxA, minA = max(projA), min(projA) maxB, minB = max(projB), min(projB) if maxA < minB or maxB < minA: return False return True 其中,A.edges和B.edges分别为矩形A和矩形B的所有边界法向量,A.vertices和B.vertices分别为矩形A和矩形B的所有顶点坐标。 以上就是一个基于SAT算法的碰撞检测示例。在实际开发中,我们可以将其应用于各种物体的碰撞检测,从而实现更加生动、丰富的游戏体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值