如何在不容易多边形分割的物体中检测碰撞

How to detect collision in not easily polygon divided body

假设我们正在 Javascript 中编写代码,我们有一个物体,比如一个苹果,并且想要检测向其投掷的石头的碰撞:这很容易,因为我们可以简单地将苹果视为一个圆圈。 但是,例如,我们有一个 "very complex" 分形怎么样?然后就没有与它相似的多边形,我们也无法在不付出巨大努力的情况下将它分解成更小的多边形。在这种情况下,有什么方法可以检测到完美碰撞,而不是制作一些 "kind" 的作品,比如将分形视为多边形(不完美,因为即使在空白处也会检测到碰撞)?

如果您有多边形的坐标,您可以使用 Javascript Clipper

使主题多边形和剪辑多边形相交

这个问题没有提供太多碰撞对象的信息,但通常任何东西都可以表示为一定精度的多边形。

编辑:

实时渲染应该足够快(取决于多边形的复杂性)。如果多边形很复杂(很多自相交 and/or 很多点),有很多方法可以加速相交检测:

  • 使用 ClipperLib.JS.Lighten() 减少点数。它删除了对轮廓没有影响的点(例如重复点和边缘上的点)
  • 使用 ClipperLib.JS.BoundsOfPath() 或 ClipperLib.JS.BoundsOfPaths() 获取多边形的第一个边界矩形。如果边界矩形没有碰撞,则不需要进行交集操作。这个函数非常快,因为它只得到 x 和 y 的 min/max。
  • 如果多边形是静态的(即它们的 geometry/pointdata 在动画期间不会改变),您可以在动画开始之前照亮并获取路径边界并将多边形添加到 Clipper。然后在每一帧中,您只需付出最小的努力即可获得实际的交叉点。

编辑 2:

如果你担心帧率,你可以考虑使用一个实验性的浮点(双)Clipper,它比 IntPoint 版本快 4.15 倍,当 IntPoint 版本需要大整数时,浮点版本是 8.37x比 IntPoint 版本更快。最终速度实际上有点高,因为 IntPoint Clipper 需要坐标先按比例放大(到整数)然后再按比例缩小(到浮点数),并且在上面的测量中没有考虑这个缩放时间。但是float版本没有经过全面测试,在生产环境中应谨慎使用。

实验浮动版代码:http://jsclipper.sourceforge.net/6.1.3.4b_fpoint/clipper_unminified_6.1.3.4b_fpoint.js

演示:http://jsclipper.sourceforge.net/6.1.3.4b_fpoint/main_demo3.html

游乐场:http://jsbin.com/sisefo/1/edit?html,javascript,output

编辑 3:

如果您没有对象的多边形点坐标并且对象是位图(例如png/canvas),您必须先跟踪位图,例如.使用 Marching Squares 算法。一种实现是在 https://github.com/sakri/MarchingSquaresJS.

你得到了一个轮廓点数组,但是因为这个数组包含了大量不需要的点(例如,直线可以很容易地表示为起点和终点),你可以使用例如减少点数。 ClipperLib.JS.Lighten() 或 http://mourner.github.io/simplify-js/.

完成这些步骤后,您的位图对象将获得非常轻的多边形表示,通过交集算法可以快速达到 运行。

您可以创建位图,以像素为单位指示对象占用的区域。如果位图之间存在交集,则存在冲突。

您可以使用物理编辑器 https://www.codeandweb.com/physicseditor

它适用于大多数游戏引擎。你必须弄清楚如何让它在 JS 中工作。

这是该网站上使用打字稿的教程 - 与 JS 相关 http://www.gamefromscratch.com/post/2014/11/27/Adventures-in-Phaser-with-TypeScript-Physics-using-P2-Physics-Engine.aspx