本文转载自 https://blog.csdn.net/yorhomwang/article/details/54869018,感谢博主分享

本文翻译自@sevenson的文章Separating Axis Theorem (SAT) Explanation 。原文作者用的是ActionScript 3来编写算法,不过文中主要讲述的还是算法原理,我想一旦算法原理被我们掌握了,选择什么编程语言来实现算法都是次要的事情了。
本人并非英文专业,所以文中翻译得有不妥或疏漏之处,欢迎各位指正,谢谢!


正文如下:

分离轴定理(英文简称SAT)是一项用于检测凸多边形碰撞的技术。

我绝不是这个方面的专家,但当检测碰撞的需求出现在我面前之后,我做了大量的阅读并最终在ActionScript 3中实现了它。

我想,我应该把我所学到的分享给大家,希望大家不会在这方面被坑得很惨:)

当我发现我需要在flash中检测多边形碰撞时,我碰巧地遇到了一个叫“分离轴定理”的方法。但唯一的问题是,为了真正地掌握它,我可费了不少功夫。

在阅读了大量有关碰撞检测的资料,并参看了一些代码示例后,这个方法总算被我领悟了。

为了帮助其他那些不精通数学的开发者,我想我应该写下这一篇能快速阐明这个算法工作原理的简短介绍。我还在下文引入了一个使用分离轴定理实现的demo,以及供大家下载并使用的ActionScript 3源代码。(译者:demo和源代码请到原文中查看和下载)

注意:分离轴定理需要一点数学向量的知识,所以在深究这个算法前,你最好复习一下这方面的内容。

算法简述

从根本上来讲,分离轴定理(以及其他碰撞算法)的用途就是去检测并判断两个图形之间是否有间隙。分离轴定理中用到的方法使算法本身显得十分独特。

我所听到过分离轴定理的最好类比方式是这样的:

假想你拿一个电筒从不同的角度照射到两个图形上,那么会有怎样的一系列的阴影投射到它们之后的墙壁上呢?

如果你用这个方式从每一个角度上对这两个图形进行处理,并都找不到任何的间隙,那么这两个图形就一定接触。如果你找到了一个间隙,那么这两个图形就显而易见地没有接触。

从编程的角度来讲,从每个可能的角度上去检测会使处理变得十分密集。不过幸运的是,由于多边形的性质,你只需要检测其中几个关键的角度。

你需要检测的角度数量就正是这个多边形的边数。也就是说,你所需检测的角度最大数量就是你要检测碰撞的两个多边形边数之和。举个例子,两个五边形就需要检测10个角度。

如何在代码中实现

这是一个简易但比较啰嗦的方法,以下是基本的步骤:

步骤一:从需要检测的多边形中取出一条边,并找出它的法向量(垂直于它的向量),这个向量将会是我们的一个“投影轴”。

步骤二:循环获取第一个多边形的每个点,并将它们投影到这个轴上。(记录这个多边形投影到轴上的最高和最低点)

步骤三:对第二个多边形做同样的处理。

步骤四:分别得到这两个多边形的投影,并检测这两段投影是否重叠。

如果你发现了这两个投影到轴上的“阴影”有间隙,那么这两个图形一定没有相交。但如果没有间隙,那么它们则可能接触,你需要继续检测直到把两个多边形的每条边都检测完。如果你检测完每条边后,都没有发现任何间隙,那么它们是相互碰撞的。

这个算法基本就是如此的。

顺带提一下,如果你记录了哪个轴上的投影重叠值最小(以及重叠了多少),那么你就能用这个值来分开这两个图形。

那么如何处理圆呢?

在分离轴定理中,检测圆与检测多边形相比,会有点点奇异,但仍然是可以实现的。

最值得注意的是,圆是没有任何的边,所以是没有明显的用于投影的轴。但它有一条“不是很明显的”的投影轴。这条轴就是途经圆心和多边形上离圆心最近的顶点的直线。

在这以后就是按套路遍历另一个多边形的每条投影轴,并检测是否有投影重叠。

噢,对了,万一你想知道如何把圆投影到轴上,那你只用简单地把圆心投影上去,然后加上和减去半径就能得到投影长度了。

优点与不足

和其他的碰撞检测技术一样,分离轴定理算法有它自己的优点和不足。以下是其一些优点和不足的简要概述:

优点

(译者:原来老外也喜欢先谈优点啊~>~)

  • 分离轴定理算法十分得快——它完美地使用了基本的数学向量知识。只要间隙一旦被检测出来,那么你就能马上得出结果,消除不必要的运算。
  • 分离轴定理算法十分得准——至少据我所知是这样的。(译者:突然感觉作者好不靠谱啊,囧……)

不足

  • 分离轴定理算法只适用于凸多边形——复杂的图形(译者:指的是凹多边形,比如五角星)无法使用此方法,除非你把它们分成一些小的凸多边形,然后依次检验这些小的多边形。
  • 分离轴定理算法无法告诉你是那条边发生的碰撞——仅仅是告诉你重叠了多少和分开它们所需的最短距离。

可能这个算法会有更多优点和不足之处,但是我想这应该是最主要的几个了。

总结

我希望这篇文章能帮助你了解到分离轴定理算法。我已经尽可能地不提供过多的信息并讲解得十分简明了。(我绝不是数学方面的专家,所以如果我遗漏了什么,我深表歉意)

以下是一些帮助我理解分离轴定理算法的页面:

  • harverycartel.org——有更多详细的表述以及很多很酷的示例。我在这个页面上学到了很多。
  • GPWiki.org——有不错的讲解和代码示例,我用这些代码作为编写自己代码的基础。
  • Tony Pa——向量教程,学习向量的不错资源。
  • GameDev.net forum——一个论坛成员写的分离轴定理碰撞检测系统,带给了我一些计算方面的想法。

以下是译者补充的内容

我将文中的算法用JavaScript实现了一遍,大家有兴趣的话,可以到下面提供的链接中下载源代码或查看在线demo。

源代码下载

查看在线Demo

碰撞检测之分离轴定理算法相关推荐

  1. 碰撞检测之分离轴定理算法讲解

    本文翻译自@sevenson的文章Separating Axis Theorem (SAT) Explanation .原文作者用的是ActionScript 3来编写算法,不过文中主要讲述的还是算法 ...

  2. 【运动规划算法项目实战】如何使用分离轴定理算法实现碰撞检测(附ROS C++代码)

    文章目录 前言 一.分离轴定理简介 二. 碰撞检测流程 三.代码实现 3.1 计算物体的顶点坐标 3.2 计算出物体的所有边 3.3 检测两个三维物体是否发生碰撞 3.4 完整代码 3.5 RVIZ显 ...

  3. JavaScript实现碰撞检测(分离轴定理)

    概述 分离轴定理是一项用于检测碰撞的算法.其适用范围较广,涵盖检测圆与多边形,多边形与多边形的碰撞:缺点在于无法检测凹多边形的碰撞.本demo使用Js进行算法实现,HTML5 canvas进行渲染. ...

  4. 分离轴定理SAT及碰撞检测

    1.简介 分离轴理论,简称SAT(SeparatingAxisTheorem),通过判断任意两个凸多边形在任意角度下的投影是否均存在重叠,来判断是否发生碰撞.即两个不相交的多边形一定能找到一条轴,它们 ...

  5. 第6-8课:分离轴算法(SAT)与碰撞检测(图文篇)

    物体的碰撞检测是游戏软件中的关键算法之一,两个角色是否能够对话.子弹是否击中了物体,以及是否出现人物穿墙的 bug,都依赖于一套可靠的碰撞检测算法.有很多算法可以实现碰撞检测,基于算法几何的方法有轴对 ...

  6. 分离轴定理SAT凸多边形精确碰撞检测

    分离轴定理SAT凸多边形精确碰撞检测 定理 Separating Axis Theorem,缩写SAT,中文为分离轴理论或分离轴定理,通过判断凸多边形在分离轴上的投影是否重叠来判断是否发生碰撞. 所谓 ...

  7. 分离轴定理及向量应用

    分离轴定理及向量应用 通过判断任意两个 凸多边形 在任意角度下的投影是否均存在重叠,来判断是否发生碰撞.若在某一角度光源下,两物体的投影存在间隙,则为不碰撞,否则为发生碰撞. 算法简述1 从根本上来讲 ...

  8. 计算几何类------分离轴定理

    这是一般用于检测凸多边形是否重叠的理论,并简称为SAT 首先 我们先看一下知乎上对于分离轴定理的定义: 我们定义分离轴是这样一个方向轴,两个convex物体分别投影到这个轴上,同时这两个物体的投影互不 ...

  9. 碰撞检测中的K_DOPS算法的研究

    摘  要  K_DOPS碰撞检测算法是一类重要的碰撞检测算法,本文从K_DOPS的定义.包围盒的选择与计算.包围盒树的构造等几个方面对K_DOPS算法进行研究,并给出一种快速碰撞检测算法并对该算法进行 ...

最新文章

  1. 腾讯云物联网平台产品全面升级,全新生态运营策略构建消费电子智能生态
  2. 【转】C#解析HTML
  3. grid布局合并单元格
  4. python中进制chr_python中的chr() 如何返回字符?
  5. docker学习笔记(七)docker-swarm
  6. flink写入hive的时区问题
  7. 机器学习(三十七)——Integrating Learning and Planning(3)
  8. java重新_Java程序重新配置教程
  9. linux 有趣的命令
  10. gnuplot画图命令_Gnuplot科学绘图(二十六)——image 绘图
  11. C语言算术运算符介绍和示例
  12. 蛋疼! 注意了,千万不要在 MySQL 中使用 UTF-8
  13. 网站采集软件,全自动网站文章采集器,一键网页数据抓取
  14. Android软键盘删除键触发Activity的返回事件
  15. 华为手机USB调试搜不到设备
  16. 进入MySQL目录下的bin文件夹
  17. 【联盛德W806上手笔记】九、DMA
  18. poi2011 切题记
  19. 微信WIFI,帮你做好客流量统计
  20. Spring启动自动执行方法

热门文章

  1. 单片机发射红外c语言程序,单片机模拟红外发射源程序IR-send
  2. C++代码规范 学习笔记
  3. DGL API on PyTorch
  4. 吴恩达深度学习之风格迁移
  5. 「华熙生物」发来感谢信,企企通赋能生物科技领域数字化采购建设
  6. 电子科技大学微处理器与嵌入式实验报告实验四五
  7. kotlin中使用Room数据库
  8. Springboot毕设项目儿童医院问诊导诊系统aqy75(java+VUE+Mybatis+Maven+Mysql)
  9. Biome-BGC在模拟过程中,如何使用Linux、Python等,完成前处理和后处理工作???
  10. 微信关闭页面分享及其余功能