quadtree-ts

2.2.2

Many-to-many Example

This example shows how Quadtrees can be used for many-to-many checks. All objects can collide with each other.

Two loops are neccessary to first insert all objects into the tree [2] and then check each object for collisions [3].

• If Use Quadtree is enabled, every objects is only checked against objects from the same node(s).
• If Use Quadtree is disabled, every object is checked against ever other object.

The following code is reduced to the most important parts. View the full script.js of this example on GitHub.

HTML

<canvas id="canvas" width="640" height="480"></canvas>

JS

// Create a new Quadtree
const tree = new Quadtree({
	width: 640,
	height: 480,
});

// Store all objects in an array
const myObjects = [];

// Create some objects
for(let i=0;i<200;i++) {
    const rectangle = new Quadtree.Rectangle({
        x: Math.random() * 640,
        y: Math.random() * 480,
        width: 4 + Math.random() * 28,
        height: 4 + Math.random() * 28,

        // Custom data: velocity for x and y, 
        // and a check boolean to flag colliding objects
        data: {
            vx: -0.5 + Math.random(),
            vy: -0.5 + Math.random(),
            check: false,
        },
    });

    myObjects.push(rectangle);
}

// Enable/disable Quadtree
let useQuadtree = true;
document.querySelector('#toggle-quadtree').addEventListener('click', () => useQuadtree = !useQuadtree);

// Main loop
function loop() {
    
    // [1] Clear the tree
    if(useQuadtree) {
        tree.clear();
    }
    
    // [2] Update myObjects and insert them into the tree again
    myObjects.forEach(obj => {

        // Update the position
        obj.x += obj.data.vx;
        obj.y += obj.data.vy;

        // Reset retrieve flag
        obj.data.check = false;
        
        if(useQuadtree) {
            tree.insert(obj);
        }
    });

    // [3] now that the tree is filled, we have to check each object for collisions
    for(let i=0;i<myObjects.length;i++) {

        const myObject = myObjects[i];

        // [4] first, get all candidates that share nodes with myObject
        // (or all objects, if useQuadtree is false)
        const candidates = useQuadtree ? tree.retrieve(myObject) : myObjects;

        // [5] let's check them for actual collision
        for(let k=0;k<candidates.length;k++) {

            const myCandidate = candidates[k];

            // [6] since all objects are inside the tree, 
            // we will also retrieve the current object itself.
            // That's a collision case we want to skip.
            if(myObject === myCandidate) continue;

            // [7] check for actual intersection
            const intersect = getIntersection(myObject, myCandidate);
            
            //[8] if they actually intersect, we can take further 
            //actions. In this script, colliding objects will turn 
            //green and change velocity 
            if(intersect) {
                // … take actions
            }
        }
    }

    // Draw scene
    draw();
    
    window.requestAnimationFrame(loop);
};

loop();

To see the full example code please check the page source or visit this page on github.