分离轴定理及向量应用
通过判断任意两个 凸多边形 在任意角度下的投影是否均存在重叠,来判断是否发生碰撞。若在某一角度光源下,两物体的投影存在间隙,则为不碰撞,否则为发生碰撞。
算法简述1
从根本上来讲,分离轴定理(以及其他碰撞算法)的用途就是去检测并判断两个图形之间是否有间隙。分离轴定理中用到的方法使算法本身显得十分独特。
我所听到过分离轴定理的最好类比方式是这样的:
假想你拿一个电筒从不同的角度照射到两个图形上,那么会有怎样的一系列的阴影投射到它们之后的墙壁上呢?
如果你用这个方式从每一个角度上对这两个图形进行处理,并都找不到任何的间隙,那么这两个图形就一定接触。如果你找到了一个间隙,那么这两个图形就显而易见地没有接触。
从编程的角度来讲,从每个可能的角度上去检测会使处理变得十分密集。不过幸运的是,由于多边形的性质,你只需要检测其中几个关键的角度。
你需要检测的角度数量就正是这个多边形的边数。也就是说,你所需检测的角度最大数量就是你要检测碰撞的两个多边形边数之和。举个例子,两个五边形就需要检测10个角度。
代码实现2
原理很容易理解,这个算法的关键在于,如何找到这条轴。 在2D的情况下,两个多边形每条边的法向量包含了这条轴的所有可能性。所以我们只需要枚举两个多边形的每条边的法向量即可。
2D向量的法向量非常好求 向量(X,Y)的法向量为(Y,-X)或(-Y,X),这个算法不需要考虑方向,所以任选一种即可。
然后分别计算这两个多边形的所有点在此向量上的投影,并分别求出最大最小区域,如果没有重合,那么直接确定这两个多边形不重合,如果有重合,那么继续判断下一条边的法向量。
举例分析3
以下图为例:
图片引用自 知乎《 向量应用 分离轴定理》@mmtest012
以边1为例进行分析如下:
图片引用自 知乎《 向量应用 分离轴定理》@mmtest012
为了易于理解,示例图将坐标轴原点(0,0)放置于三角形边1投影轴的适当位置。
具体步骤:
1、首先根据1边的两个端点计算1边向量,进一步求出1边的法向量。( 向量(X,Y)的法向量为(Y,-X)或(-Y,X));
2、得到向量在投影轴上的长度:向量的点积的其中一个几何含义是:一个向量在平行于另一个向量方向上的投影的数值乘积。由于投影轴是单位向量(长度为1),投影的长度为 x1 * x2 + y1 * y2;
3、循环获取第一个多边形的每个点,并将它们投影到这个轴上(记录这个多边形投影到轴上的最高和最低点,形成一个投影线段);
4、分别得到这两个多边形在这个轴上的投影,并检测这两段投影是否发生重叠;
5、如果你发现了这两个投影到轴上的“阴影”有间隙,那么这两个图形一定没有相交。
如果没有间隙,它们仍有接触的可能,你需要继续检测直到把两个多边形的每条边都检测完。
如果你检测完每条边后,都没有发现任何间隙,那么它们是相互碰撞的。
这个算法基本就是如此的。
(顺带提一下,如果你记录了哪个轴上的投影重叠值最小(以及重叠了多少),那么你就能用这个值来分开这两个图形。)