Question

I am testing collision between numerous moving squares in a quadtree.

When two square collides, I invert their velocity, like this:

    for (auto pair : collisionPairs)
    {
        auto& square1 = static_cast<Square&>(*(pair.first));
        auto& square2 = static_cast<Square&>(*(pair.second));

        square1.setVelocity(-square1.getVelocity());

        square2.setVelocity(-square2.getVelocity());

    }

The problem is, collision detection is not always during one frame.

Sometimes, they are collision between same squares more than one frame, because the squares have been intersecting to deep.

So squares overlap and they keep reversing their velocity infinitely, which results a 0 velocity ( -velocity + velocity = 0 )

How could I fix this ?

EDIT : I've discovered that the deep intersection issue was caused by my quadtree, I forgot to check collision with the objects of children trees.

Now it STILL happens but very rarely, like 1 in 100 collisions, before it was ~20 from 100 collisions

Was it helpful?

Solution

In addition to the pure collision detection I'd also check, whether the centers of the squares move towards each other or not and only revert their velocity in the first case. For me to provide an example you'd have to provide information about your implementation of the Square class.

Edit: Essentially the logic would look something like this:

if (collision detected) {
    if ( (square2.posx-square1.posx)* (square2.vx-square1.vx) < 0) {            
        // EDIT: exchange velocities of square1 and square2 in x direction
    }
    if ( (square2.posy-square1.posy)* (square2.vy-square1.vy) < 0) {             
        // EDIT: exchange velocities of square1 and square2 in y direction
    }
}

This is of course far from a realistic collision simulation, but if you just want to see whether your collision detection works correctly it should suffice. Btw. I'm assuming, that the rectangle edges are all oriented along the x and y axis.

OTHER TIPS

You could give your Square class an additional inCollision() state or so, and check this additionally:

if(!square1.inCollision()) {
    square1.setVelocity(-square1.getVelocity());
    square1.setInCollision(true);
}

// Analogous code for square2

// Set inCollision state to false, when you build the collisionPairs
// Simplyfied pseudo code:
if(intersect(square1,square2) {
     // make_pair blah blah
}
else {
     square1.setInCollision(false);
     square2.setInCollision(false);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top