如何在不容易多边形分割的物体中检测碰撞
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
假设我们正在 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