JavaScript中基于空间划分的对象冲突检测
我试图创建一个由许多对象组成的系统,当它们相互碰撞时,这些对象会执行一个动作,我使用的是P5.min.js库 我已经为网格设置了一个数组,为对象设置了一个数组,但我无法找到正确的方法来遍历每个网格单元,并在移动到下一个单元之前只检查该单元中的对象 这是我到目前为止得到的JavaScript中基于空间划分的对象冲突检测,javascript,p5.js,Javascript,P5.js,我试图创建一个由许多对象组成的系统,当它们相互碰撞时,这些对象会执行一个动作,我使用的是P5.min.js库 我已经为网格设置了一个数组,为对象设置了一个数组,但我无法找到正确的方法来遍历每个网格单元,并在移动到下一个单元之前只检查该单元中的对象 这是我到目前为止得到的 let molecules = []; const numOfMolecules = 100; let collisions = 0; let check = 0; let maxR = 10; //max molecule r
let molecules = [];
const numOfMolecules = 100;
let collisions = 0;
let check = 0;
let maxR = 10; //max molecule radius
let minR = 2; //min molecule radius
let numOfCol = 5;
let numOfRow = 5;
let CellW = 600/numOfCol; //gridWidth
let CellH = 600/numOfRow; //gridHeight
let remain = numOfMolecules;
let gridArray = [];
function setup() {
createCanvas(600, 600);
background(127);
for (let i = 0; i < numOfMolecules; i++) {
molecules.push(new Molecule());
}
}
function draw() {
background(127);
molecules.forEach(molecule => {
molecule.render();
molecule.checkEdges();
molecule.step();
});
drawGrid();
splitIntoGrid();
collision();
displayFR();
}
function drawGrid() {
for (i = 0; i < numOfRow+1; i++){
for (j = 0; j < numOfCol+1; j++){
noFill();
stroke(0);
rect(CellW*(j-1), CellH*(i-1), CellW, CellH);
}
}
}
function splitIntoGrid(){
for (let i = 0; i < numOfRow; i++){
for (let j = 0; j < numOfCol; j++){
tempArray = [];
molecules.forEach(molecule => {
if (molecule.position.x > (CellW*j) &&
molecule.position.x < (CellW*(j+1)) &&
molecule.position.y > (CellH*i) &&
molecule.position.y < (CellH*(i+1))) {
tempArray.push(molecule.id);
}
});
}
}
}
let分子=[];
常数NUMOF=100;
设碰撞=0;
让check=0;
设maxR=10//最大分子半径
设minR=2//最小分子半径
设numocol=5;
设numorrow=5;
设CellW=600/numOfCol//网格宽度
设CellH=600/numorrow//网格高度
让剩余=多个分子;
让gridArray=[];
函数设置(){
createCanvas(600600);
背景(127);
for(设i=0;i{
render()分子;
checkEdges()分子;
分子。步骤();
});
drawGrid();
拆分为网格();
碰撞();
displayFR();
}
函数drawGrid(){
对于(i=0;i{
if(molecular.position.x>(CellW*j)&&
分子位置x<(单元w*(j+1))&&
分子位置y>(单元格H*i)&&
分子位置y<(细胞*(i+1))){
tempArray.push(molecular.id);
}
});
}
}
}
如何检查所有对象之间的碰撞:
function collision() {
for (let i=0; i < molecules.length; i++){
for (let j=0; j < molecules.length; j++){
let diff = p5.Vector.sub(molecules[j].position, molecules[i].position);
check++;
if (i != j && diff.mag() <= molecules[j].radius + molecules[i].radius){
collisions++;
molecules[j].changeColor();
}
}
}
}
函数冲突(){
for(设i=0;i 如果(i!=j&&diff.mag()网格单元由数组gridArray
表示。您需要为每个网格单元收集一组分子。我的建议是使用s而不是an,因为顺序不相关。其思想是能够访问给定网格单元(i,j)上的一组分子
使用以下语法:
gridArray[i][j]
以下代码将创建numorrow
数组的数组:
const numorrow=5;
常量gridArray=(新数组(numorrow)).fill([]);
gridArray
的外观如下:
[ [], [], [], [], [] ]
在splitIntoGrid
中,您正在检查哪些分子位于哪些网格单元中。这很好。但是,对于每个网格单元,您正在覆盖全局变量tempArray
。因此,在函数执行结束时,tempArray
将只保存最后一个网格单元的分子,这不是您想要的需要。对于给定的网格单元,我们将向与该网格单元关联的集合添加正确的分子
集合
数据结构有一种方法,可将新元素附加到集合中:
函数splitIntoGrid(){
for(设i=0;i{
if(molecular.position.x>(CellW*j)
&&分子位置x<(单元w*(j+1))
&&分子位置y>(单元格H*i)
&&分子位置y<(细胞*(i+1))){
gridArray[i][j].添加(分子);
}
});
}
}
}
现在,您已经准备好检查每个网格单元上的碰撞。我们将在每个网格单元内总共有四个环。两个环用于导航网格,两个环用于比较每个网格单元内包含的分子:
函数冲突(){
for(设i=0;i{
gridArray[i][j].forEach(moleculeB=>{
常数差=p5矢量sub(分子位置,分子位置);
如果(moleculeA!=moleculeB&&diff.mag(),谢谢Ivan,我对集合不太熟悉。我已经更改了您所讨论的内容,并且所有函数都能完美地工作,除了碰撞,我是否需要在某个地方声明和更新moleculeA和moleculeB?当我使用碰撞运行时,我得到以下错误:@Marcus,您能添加console.log(I,j)吗
就在const diff
行之前,告诉我控制台中有什么日志?这将有助于了解gridArray
是否是这里的问题。打印moleculeA.position
和moleculeB.position
也会有帮助。注意:这两个都是可用的,因为您正在通过gridArray
(这是一个2D数组)。问题就发生在第一个网格单元上gridArray[0][0]
。你能注释掉这两个gridArray[i][j]
forEach
循环并添加gridArray[i][j]。forEach(console.log)
?像这样:函数冲突(){for(让i=0;i
。此外,您可能需要检查您的分子是否具有位置
属性。(@Marcus)很抱歉延迟了响应,它似乎通过阵列时没有问题,并且每个分子的位置都被保存了。当girdArray[I][j]forEach循环没有被注释掉时,我仍然有问题
[ [], [], [], [], [] ]