Patrioticcow
Patrioticcow

Reputation: 27048

How do I implement collision detection between a set of Div elements?

I have this example in jsfiddle

I have a var as being the collision element:

var $div = $('.container');

and then the collision:

function test (){
    $('.drag')
        .drag("start",function( ev, dd ){
            dd.limit = $div.offset();
            dd.limit.bottom = dd.limit.top + $div.outerHeight()
                - $( this ).outerHeight();
            dd.limit.right = dd.limit.left + $div.outerWidth()
                - $( this ).outerWidth();
        })
        .drag(function( ev, dd ){
            $( this ).css({
                top: Math.min( dd.limit.bottom, Math.max( dd.limit.top, dd.offsetY ) ),
                left: Math.min( dd.limit.right, Math.max( dd.limit.left, dd.offsetX ) )
            });   
        });
}

for:

<div class="container"></div>
<div class="drag xxx" style="left:40px;"></div>
<div class="drag xxx" style="left:120px;"></div>
<div class="drag xxx" style="left:200px;"></div>

This code implements collision detection of the child divs against the container div. How would I implement collision detection to make those 3 divs collide with each other?

I'm thinking to set up another div : var $divs = $('.xxx'); but im not sure how to use it within this example.

Upvotes: 6

Views: 10900

Answers (1)

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59111

Full collision detection and correct collision response isn't a trivial problem to solve, except in special cases.

The code you have now is fairly easy to write because you only have two objects to compare (the dragged object and the container), and because your collision response was simply to restrict the div's position to be inside the container.

For full collision against all the divs, you'll have to check the dragged div against the container and all other divs. Your collision response will have to calculate a movement vector, and handle complex "sliding" logic to make sure you can move around other objects, but ensure that your final position will still be inside the container.

I'd suggest you first reexamine your need for full collision detection, as it can be perf-heavy and complicated. Maybe you just need overlap detection, ala jQuery UI's droppable? Or maybe you need something like jQuery UI's draggable snapping, or jQuery UI's sortable?

If you determine you actually need full collision detection, I suggest you grab a library that already handles collision detection since it is hard to implement. See answers on this question for a few library options:

If you really want to implement it yourself, you should look up the Separating Axis Theorem:

I'd then read the articles on implementing collision detection and response as seen in the N game:

If you need to search for more info, you can consider divs to be Axis-Aligned Bounding Boxes (AABBs). This can give you huge perf increases and huge complexity reductions. The math for checking AABB-to-AABB collision is about as easy as it gets for overlap and collision detection (though collision response is still as hard as with any other type of collision).

Upvotes: 9

Related Questions