-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SAT 分离轴算法 #23
Labels
Comments
Open
有个问题想请教下,用投影长度大小来比较得到投影最边缘的两个点,应该有个前提是这个多边形所有的点必须是在x轴(或者Y轴)的同一侧吧? 要不然可能出现得到的点不是最边缘的点的情况 |
不是很理解你的意思,投影都是投影在法线上的,没有严格意义上的x或者y轴 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
基础知识
对于检测精度要求高的场景。包围盒便不能满足了,需要一种更加精确的检测方法。碰撞检测系统的细检测使用分离轴算法(SAT)。分离轴算法是一项用于检测凸多边形碰撞的技术。
试想一下,用照明灯照射两个相交多边形到墙上,按照日常经验,无论在哪个角度照射,两个多边形在墙上的投影一定会相互重叠(绿色线段表示投影的重叠部分):
但是,不相交的多边形在墙上的投影也可能相交:
然而,按照分离轴定律,两个不相交的多边形一定能找到一条轴,它们在这条轴上的投影不相交,也就是一定存在一个角度用电筒照这两个不相交多边形得到不相交的投影:
分离轴算法就是要验证:
两个多边形间是否存在这样一条轴,使得这个两个多边形在这条轴上的投影不相交,只要发现这样一条轴,即可马上判定两个多边形不相交,否则就是相交。这条轴就是分离轴。
要实现算法,即要枚举所有可能的轴判断是否存在投影没有交集的情况,而二维空间中有无数条轴,不可能做到全部遍历。但幸运的是,两个多边形的每条边的法向量包含了这条轴的所有可能性,所以只要枚举所有边的法向量即可。即遍历所有边的法向量,看该法向量是否要找的分离轴。
对于多边形和圆形的碰撞,只要找出多边形离圆形最近的那个顶点,该顶点与圆心之间的连线就是多边形和圆形间的分离轴。
而圆形与圆形间的碰撞的判断便更简单了,只要判断两圆心间的距离与两圆半径的和的大小关系便可。
算法实现
首先,要找出两个图形的所有候选分离轴:
getPolyAxes
和getCirAxes
具体实现如下:找到候选轴后,便要计算图形在候选轴上的投影长度,计算图形在向量上的投影实现如下:
有了这些准备,我们便可以编写用于判断多边形的分离轴算法的主函数:
对于判断两个图形在轴上是否相交,可以抽象为检测两条共线线段的相交,也就是可以利用上一节提到的
isOverlaps
函数。而对于圆形间碰撞的判断,可以另外单独判断:
由于图形间有多种碰撞可能:
多边形和多边形碰撞
多边形和圆形碰撞
圆形和圆形碰撞
所以,我们要对这些情况进行分类处理:
在最后,我们利用一个
SATDetection
对碰撞类型进行简单的分类。到这里,分离轴算法的内容已经大致介绍完毕,我们的碰撞检测系统也大致完成。但是,该算法有一个缺陷就是只能判断凸多边形的碰撞,我们要支持任意多边形的话,还要对多边形进行判断和分割。我们秉着对技术的追求,对碰撞系统进行最后的完善,下一节将介绍凹多边形的判别和分割算法的介绍和实现。
The text was updated successfully, but these errors were encountered: