Python/Pyglet中的分离轴定理

Python/Pyglet中的分离轴定理,python,opengl,collision-detection,pyglet,Python,Opengl,Collision Detection,Pyglet,我正试图用Pyglet在Python中复制小行星。我想我应该试着想象一下,用分离轴定理来做碰撞。我让它工作了,但问题是速度太慢了。我测试了玩家发射的子弹和屏幕上的小行星之间的碰撞,我认为这是二次循环,但当屏幕上出现大约6颗小行星和6颗子弹时,帧速率从60 fps下降到30 fps,这看起来非常慢,即使是对于非优化的碰撞检测方式 因此,我运行了一个分析器来确定程序在代码中的确切位置被挂起。在我将形状顶点转换为世界空间的方法中,它似乎被挂起(我定义原点周围的形状,并使用OpenGL代码转换为世界空间

我正试图用Pyglet在Python中复制小行星。我想我应该试着想象一下,用分离轴定理来做碰撞。我让它工作了,但问题是速度太慢了。我测试了玩家发射的子弹和屏幕上的小行星之间的碰撞,我认为这是二次循环,但当屏幕上出现大约6颗小行星和6颗子弹时,帧速率从60 fps下降到30 fps,这看起来非常慢,即使是对于非优化的碰撞检测方式

因此,我运行了一个分析器来确定程序在代码中的确切位置被挂起。在我将形状顶点转换为世界空间的方法中,它似乎被挂起(我定义原点周围的形状,并使用OpenGL代码转换为世界空间进行绘图,我认为这是正确的方法)。我从OpenGL中获取变换矩阵,将其转换为NumPy数组,然后将每个顶点乘以该矩阵,得到变换后的顶点。值得注意的是,每次碰撞检查我都会这样做:我以前使用XNA,当我在其中实现SAT时(我也在那里制作了一个小行星克隆),顶点也在原点周围定义,然后你必须使用世界矩阵对它们进行变换

最好存储(0,0)周围的顶点并变换每个调用,还是只存储变换后的顶点?我觉得算法不应该这么慢,所以我敢打赌我在实现某些东西时搞砸了。如果我更擅长分析(我对它很不熟悉),我可能会得到一个更完整的画面,但我希望你们能有一些想法


这里有一个指向其中包含Shape类的文件的直接链接,其中发生了所有冲突逻辑:。探查器似乎标记为瓶颈的具体方法是uu get_transformed_verts。显然,你也可以从那里得到整个回购协议,但要知道还有很多未被评论。

正如Nico在评论中所建议的,一个快速获得良好加速的方法是先检查更简单的几何体。对于一个小行星克隆,我想一个圆将是一个很好的适合(或三维球体)。如果圆(至少大到足以覆盖实际形状)没有重叠,则无需进行更昂贵的几何体测试

如果您有许多对象,您可能希望避免每帧进行n*n次测试。看看空间分区结构/算法。在2D中有大量移动对象的最简单方案是网格。然后,您只需要测试属于相同或相邻网格单元的对象是否发生碰撞


我注意到的另一件事是:每次测试碰撞时都会生成变换的顶点。对于未通过圆测试的每个对象,每个时间步(帧)只生成一次网格会更快。

网格有多少个顶点?一种极大提高性能的方法是首先检查与更简单的几何体(例如两个边界球体)的碰撞。子弹是4个顶点(正方形),小行星现在是9个顶点。我将接受你的建议,首先做一个球体测试,谢谢。我将尝试使用边界圆作为第一个测试,我还将研究一些空间分割算法,谢谢。我听说过一种叫做2D四叉树的东西,但也许一个规则的网格就足够了?我想你会看到一个大的速度与边界圈。您可能不需要任何类型的空间分区,除非您要增加需要测试的对象的数量。是的,四叉树是另一种选择。还可以查看“松散”的四叉树/八叉树。它们适用于动态场景,因为您可以非常快速地将对象插入到树中。