9

有人可以解释它的优缺点以及与之相关的任何数学吗?

4

7 回答 7

11

对于 2D:你不需要任何数学来解决这个问题,你只需要一个自定义的 bitblit-routine。您将通过在此表面上绘制其碰撞掩码并检查您只想绘制的像素是否为 (pixel != 0) 将碰撞候选者blit 到隐藏表面。然后你会发生碰撞。当然,如果可能发生碰撞,您应该通过边界矩形进行预检查。

对于 3D:您将需要数学(很多)!

基本上,您将检查演员的每个表面与敌人的每个表面。这将通过计算平面射线相交来完成。这里有很多优化可能,但这取决于你的 3d 表示。这也不是 Per-Pixel-Collision,而是 Per-Vertex-Collision

于 2008-10-06T05:06:18.847 回答
10

我将从回答逐像素碰撞检测的优缺点开始,然后再考虑数学方面。

每像素碰撞检测,也称为像素完美碰撞检测,也许更准确地说是基于图像的碰撞检测,正在寻找表示为图像的碰撞对象之间的碰撞。这种空间方法与更多的几何方法形成对比,后者使用多边形和其他几何形状来表示碰撞对象。

对于 2D,通常有 3 种不同的选项:

  • 基于图像
  • 简单的几何形状(轴对齐的边界框、圆形)
  • 复杂的几何形状(凸多边形、凹多边形、椭圆等)

基于图像的碰撞检测精确且易于使用和理解。对于使用图像进行绘图的游戏,使用基于图像的碰撞检测意味着每当屏幕上的精灵重叠时,它们也会在碰撞检测系统中重叠。它们对于需要可变形碰撞对象的游戏也很有用,例如可破坏地形的游戏,如 Worms 2D,因为通常很少涉及预计算。它们的主要缺点是与其他方法相比效率非常低,尤其是在旋转和缩放碰撞对象时。

简单的几何形状既易于使用又非常有效。如果不需要高精度,或者碰撞对象很适合简单的几何形状(例如,如果您的碰撞对象是球,圆形是完美的配合,有时甚至比图像更好)。它们的主要缺点是精度。对于基本形状不适合的高精度,您要么必须将简单形状组合成更复杂的形状,要么必须使用更通用和复杂的形状。在任何一种情况下,您都会采用第三种方法。

复杂的几何形状可能有些精确并且相对有效或低效,具体取决于用于表示碰撞对象的形状的复杂性。一个重要的缺点是易于使用。当碰撞对象不适合可用的几何形状时,要么精度受到影响,要么必须使用多个可能不同的形状来表示它,这需要时间。此外,有些形状很复杂,不容易创建,除非您可以从图像中自动生成它们。一个重要的优点是旋转和缩放通常是高效且容易的,尤其是与基于图像的碰撞检测相比。

基于图像的碰撞检测通常被视为一个糟糕的解决方案,因为它通常效率低下,尤其是在使用旋转和缩放时。然而,由于它如此灵活、精确且易于使用,我决定实现一个旨在解决效率问题的库。结果是PoxelColl,它使用自动预先计算的凸包来加速基于图像的碰撞检测。这提供了易用性、灵活性、精度和效率,并支持旋转和缩放。主要缺点是与纯几何解决方案相比,它并非在所有情况下都有效,并且它需要使用预计算,这意味着它对于可变形碰撞对象并不是非常低效。

对于 3D,选项和优势有些相似:

  • 基于体积
  • 简单的几何形状(轴对齐的边界框、圆形)
  • 复杂的几何形状(凸多边形、凹多边形、椭圆等)

需要注意的是,Peter Parker 的回答对于 3D 是错误的;2D 中的像素(图片元素)对应于 3D 中的体素(体积元素)。

一些重要的区别是 3D 的空间方法比 2D 的少得多。一个可能的原因是,由于 3D 增加了额外的维度,空间解决方案的效率变得更低,而简单的几何解决方案仍然有效。而在游戏中,碰撞检测一般是在线操作,需要一定程度的效率,因此效率很重要。因此,体积更常用于不需要在线确定碰撞的非游戏应用程序中。

有关基于体积的碰撞检测的碰撞检测示例,请参见可变形对象的体积碰撞检测,其中使用体积而不是几何形状意味着它们可以处理具有任意形状的封闭表面的可变形碰撞对象。

至于第二个问题,基于图像的碰撞所涉及的数学可以从简单到复杂。简单的情况基本上是对图像使用轴对齐的边界框,找到它们的交点,然后只检查交点中的图像。更复杂的解决方案包括我之前提到的库,其中需要凸多边形相交。对于 3D 案例,解决方案从简单到非常复杂。

于 2012-05-14T19:20:14.337 回答
2

它比顶点(或命中框等)更准确。我假设您在这里谈论的是 2d(3d 将是盒模型与顶点)。每像素可以让你有详细的精灵,小东西(比如导弹)会更真实地碰撞。

它比传统方法更数学且更慢,传统方法是画一个盒子(或其他一些简单的数学形状,如圆形)并说“这是演员,这里的任何东西都是他”。然而,它更准确。

于 2008-10-06T04:35:57.630 回答
2

在谈论利弊时,您还必须考虑碰撞响应。当检测到碰撞时你想做什么?如果您正在检测一个物体撞击另一个物体,结果是其中一个或两个物体被破坏,那么每像素碰撞检测是好的和准确的。如果您希望对象以其他方式做出反应,即靠墙滑动、弹跳等......那么您可能需要使用某种类型的边界矩形/圆形/椭圆形,这将使碰撞响应看起来更平滑和更多一致,卡住的机会更小。

于 2008-10-06T05:45:40.280 回答
1

优点已经提到:像素完美且公平,没有误报也没有误报。主要缺点是计算成本高,但如果你先做一个简单的边界框检查,这应该不是什么大问题。在 OpenGL 和 DirectX 时代还有一个问题:精灵数据通常是纹理,这意味着它们在 VRAM 中,您无法轻松地自己检查像素值。在 OpenGL 中,您可以使用该glReadPixels函数将两个精灵的相交部分返回 RAM 并检查碰撞,或者您可以使用遮挡查询. 遮挡查询方法应该具有更好的性能,因为您没有将数据从 GPU 移回,但并非所有地方都支持遮挡查询(即 OpenGL ES 不支持它们,如果我错了,请有人纠正我)。

于 2008-10-06T05:38:50.280 回答
0

考虑 OpenGL 和纹理案例:您可以预先计算图像的位矩阵并测试两个像素是否重叠。

于 2009-05-26T02:29:24.933 回答
0

每像素碰撞检测是过去的遗物,当时图形很简单,2D 硬件包括精灵和背景之间的自由碰撞检查,因为即使是基本的距离计算在计算上也是昂贵的。虽然今天的 2d 图形更加复杂,但很少使用逐像素碰撞检查,尤其是因为对象可见形状和碰撞形状通常不同。大多数情况下,圆圈或方框就足够了。此外,由于基于 opengl 的图形硬件无法再进行碰撞检查,因此您必须编写额外的渲染代码,使用 CPU 来进行碰撞检查,同时将额外的位图数据保存在系统内存中,因为无法直接访问图形内存.

于 2010-07-26T00:13:51.553 回答