Sean Patrick Sutton
Sean Patrick Sutton

Reputation: 185

collision detection. 2 rectangles intersect: place source rectangle outside area

I am writing a collision detection system in as3. It is intended to be simple: I have some moving rectangles and some static ones. When a moving rectangle collides with another rectangle, I would like to move the source (colliding) rectangle just outside of the collision area, but still as close as possible (based on the source's trajectory).

On every frame I update the positions of my moving rectangles and check for contact amongst all rectangles.

The below image represents the following:

a: Box #1 is moving at an angle of 45 degrees towards a static rectangle (#2).

b: After several 'ticks' we see Rectangle #1 move into the space of Rectangle #2 (the static one). This is the point at which impact is detected for the first time.

c: Now - what I would really like to do! - is move the source Rectangle #1 to the outskirts of Rectangle #2's collision area.

... So given the angle of movement of Rectangle #1 and, knowing the overall areas and positions of Rectangles #1 and #2, Is there a formula that provides the closest possible x and y co-ordinates for Rectangle #1 to be moved to (so that we are no longer in full collision, as we see in stage 'b').

Obviously I would like a solution that will work at any angle of movement and all sorts of rectangle shapes.

3 steps

Thanks in advance for your time on this :)

Upvotes: 1

Views: 957

Answers (2)

golyo
golyo

Reputation: 518

Lets say your green square is colliding with the red one, with a velocity smaller than its width.enter image description here

The importance of this speed limit is, that this way you only need to check the collision points a,b,d, as long as you are moving "top right". This speed limit avoids collision points "moving past" their target, and missing collisions. Lets say "a" will move to point "p".

ie:

//check if p is inside the red box
if (p.x > f.x && p.x < g.x && p.y > i.y && p.y < f.y)
{
    //calculate the intersection of |if| with |aP|
    var x:Number = f.x;
    var y:Number = a.y + ((f.x - a.x) / (p.x - a.x)) * (p.y - a.y);
}

Upvotes: 2

Marty
Marty

Reputation: 39466

Assuming your rectangles are never rotated, you can check for the actual collision using an inbuilt method, Rectangle.intersects():

var rectangleA:Rectangle = objectA.getRect(objectA.parent);
var rectangleB:Rectangle = objectB.getRect(objectB.parent);

if(rectangleA.insersects(rectangleB))
{
    // Collision.
}

As for moving the rectangle back to the outside of the one it collided with, you can add 180 degrees to its trajectory and back up until the rectangles no longer intersect.

If you want more realistic collisions and rotated rectangles, use a physics engine like Box2D.

Upvotes: 0

Related Questions