JavaScript中基于空间划分的对象冲突检测

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

我试图创建一个由许多对象组成的系统,当它们相互碰撞时,这些对象会执行一个动作,我使用的是P5.min.js库

我已经为网格设置了一个数组,为对象设置了一个数组,但我无法找到正确的方法来遍历每个网格单元,并在移动到下一个单元之前只检查该单元中的对象

这是我到目前为止得到的

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循环没有被注释掉时,我仍然有问题
[ [], [], [], [], [] ]