
p5.collide2D实战二如何在画布上随机放置上百个不重叠的对象【免费下载链接】p5.collide2DA collision detection library for 2D geometry in p5.js项目地址: https://gitcode.com/gh_mirrors/p5/p5.collide2D这篇文章带你用p5.collide2D——p5.js 的 2D 碰撞检测库——在画布上随机放置上百个互不重叠的圆形、矩形和多边形对象。无需手写距离公式只需几行碰撞检测代码就能生成像泡泡画、气泡墙、随机贴纸排版这类视觉效果。为什么随机放置的对象总会重叠最直觉的做法是给每个对象生成一个随机坐标然后画出来。但结果一定是乱成一锅粥——因为随机坐标之间没有任何约束对象之间会大量重叠。要解决这个问题需要给每个新生对象一次资格检查它落在随机位置后先和所有已放置的对象做一轮碰撞检测一旦碰到任何一个就作废重来。这正是 p5.collide2D 的用武之地。核心思路随机试探 碰撞检测的试错法整个算法只有 3 步非常好记随机生成一个候选位置循环检测它与所有已放置对象是否碰撞库函数返回true表示碰撞、false表示安全安全则保留碰撞则重试直到放够目标数量。 这种生成—检测—重试的试错法rejection sampling简单可靠适合画布上几十到上千个对象。p5.collide2D 的所有碰撞函数都遵循统一约定返回true表示发生碰撞false表示没有碰撞。常用函数速查如下场景函数关键点圆 vs 圆collideCircleCircle()尺寸参数传直径矩形 vs 矩形collideRectRect()默认rectMode(CORNER)矩形 vs 圆collideRectCircle()混合形状必备圆 vs 多边形collideCirclePoly()多边形用p5.Vector顶点数组表示多边形 vs 多边形collidePolyPoly()支持自相交的多边形这些函数的实现都在 p5.collide2d.js 中例如圆对圆的collideCircleCircle定义在第 66 行附近源码非常精简读一遍就能理解其原理。p5.collide2D 快速上手一条命令安装如果你习惯本地开发克隆仓库即可git clone https://gitcode.com/gh_mirrors/p5/p5.collide2D把项目里的p5.collide2d.js开发用或p5.collide2d.min.js压缩版上线推荐引入你的 p5.js 页面放在 p5.js 核心库之后加载即可。库没有任何外部依赖引入即用。完整示例随机生成 200 个互不重叠的圆下面是完整可运行的 sketch注意看placeAll函数里的三层结构——它就是本文的核心const objects []; const R 16; // 半径 function setup() { createCanvas(800, 600); placeAll(200, R); } function placeAll(count, r) { while (objects.length count) { const x random(r, width - r); // 留出边距防止贴边被截断 const y random(r, height - r); let safe true; for (const o of objects) { // 碰撞检测参数是圆心 直径 if (collideCircleCircle(x, y, r * 2, o.x, o.y, o.r * 2)) { safe false; break; // 碰到一个就放弃省掉剩余检测 } } if (safe) objects.push({ x, y, r }); } } function draw() { background(240); noStroke(); fill(70, 130, 180, 220); for (const o of objects) circle(o.x, o.y, o.r * 2); }两个新手最常踩的坑提前避开传直径不是半径collideCircleCircle的第三个参数是直径所以代码里写r * 2碰撞就break只要和一个对象碰撞即可判定失败不必检测完所有对象。性能优化从 200 个到 1000 个对象默认写法是 O(n²)——第 n 个对象要和前 n−1 个对象逐一碰撞检测。放 200 个对象瞬间完成若要放 1000 个可以加两招第一招廉价包围盒预检在调用真正的碰撞检测前先用最便宜的坐标差排除明显不碰的对象function quickCollide(x, y, r, o) { const d r o.r; if (Math.abs(x - o.x) d || Math.abs(y - o.y) d) return false; return collideCircleCircle(x, y, r * 2, o.x, o.y, o.r * 2); }大部分对象对会在if这一行被直接排除根本走不到碰撞检测整体速度提升数倍。第二招加放弃上限防止死循环对象越放越密时随机命中空位的概率会急剧下降while循环可能越转越久。给它加一个最大尝试次数function placeWithLimit(count, r, maxTries 50) { let tries 0; while (objects.length count tries count * maxTries) { tries; // ……与上文相同的生成 检测逻辑 } }放不满了就接受放多少算多少画面依然自然。第三招控制密度如果希望对象之间留缝隙更像泡泡效果把碰撞检测的直径调大一点点即可比如用r * 2.4参与检测——相当于给每个圆加了一圈缓冲区无需额外逻辑。进阶玩法矩形与多边形混排换成矩形只需替换碰撞函数collideRectRect使用左上角坐标 宽高if (collideRectRect(x, y, w, h, o.x, o.y, o.w, o.h)) safe false;圆和矩形混排时用collideRectCircle不规则多边形则用顶点数组配合collideCirclePoly/collidePolyPoly顶点用createVector存放。调试时还可以在setup()里调用collideDebug(true)让库在碰撞点画一个标记圆方便肉眼核对检测是否准确。常见问题 FAQQ循环卡住不放了怎么办密度过高随机命中空位的概率趋近于零。减少对象数量、缩小对象尺寸或使用上文放弃上限。Q碰撞检测算的是接触还是重叠两者都算。只要边界相切或重叠就会返回true所以默认放置出来的对象是贴着但不穿帮的。Q能用于 3D 吗不能p5.collide2D 专注 2D 几何。3D 需要其他方案。Q许可协议是什么本项目采用 CC BY-NC-SA 4.0 协议与 Jeffrey Thompson 的碰撞检测教程一致商用前请自行确认条款。小结步骤要点① 安装引入p5.collide2d.js置于 p5.js 之后② 试错法随机生成 → 逐一碰撞检测 → 碰撞则重试③ 细节圆传直径、碰撞即break、留边距④ 提速包围盒预检 尝试上限 控制密度随机试错法配上 p5.collide2D 的碰撞检测函数几十行代码就能让上百个对象各占一方、互不打架。下一站可以试试给这些对象加上随时间移动和反弹碰撞检测在动态场景里同样好使。【免费下载链接】p5.collide2DA collision detection library for 2D geometry in p5.js项目地址: https://gitcode.com/gh_mirrors/p5/p5.collide2D创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考