Collision detection with Rectangles

A

Abs

Hi!

I have two draggable Rectangle shapes in a JPanel and I'd like
to perform collision detection between them. Right now I'm using
the following algorithm to detect their intersection:


public boolean intersects(RectangleShape r) {
int tw = this._w;
int th = this._h;
int rw = r._w;
int rh = r._h;
if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
return false;
}
int tx = this._x;
int ty = this._y;
int rx = r._x;
int ry = r._y;

rw = rw+rx;
rh = rh+ry;
tw = tw+tx;
th = th+ty;

if ((rw < rx || rw > tx) &&
(rh < ry || rh > ty) &&
(tw < tx || tw > rx) &&
(th < ty || th > ry)) {
return true;
} else {
return false;
}
}


This algorithm detects the intersection but does nothing to avoid
the overlapping between the two shapes. How can I reposition the
moving shape ("this") to prevent it from overlapping the other one ? Can
anyone help me, please ?


Thanks
 
C

Chris Smith

Abs said:
This algorithm detects the intersection but does nothing to avoid
the overlapping between the two shapes. How can I reposition the
moving shape ("this") to prevent it from overlapping the other one ? Can
anyone help me, please ?

That's not a precise enough problem description. There are likely going
to be any number of possible positions that don't overlap the other
rectangle; is any one good enough? Or do you need to stop the moving
rectangle along its path of motion? In the latter case, you you know
its path of motion (meaning direction, if it's moving in a straight
line)?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
A

Abs

Chris said:
That's not a precise enough problem description. There are likely going
to be any number of possible positions that don't overlap the other
rectangle; is any one good enough? Or do you need to stop the moving
rectangle along its path of motion?

I need the four sides of the static rectangle to block the moving one.
Like a rock blocking a moving person by all its sides.
In the latter case, you you know
its path of motion (meaning direction, if it's moving in a straight
line)?

The rectangle is not necessarily moving in a straight line, I can drag
it with the mouse in any direction.
 
C

Chris Smith

Abs said:
The rectangle is not necessarily moving in a straight line, I can drag
it with the mouse in any direction.

I suppose if you know the last good position, you could extrapolate a
straight line from the last position to the current one, and move it
along that. Do you know the last position the rectangle was in before
it moved?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jesper Nordenberg

Abs said:
The rectangle is not necessarily moving in a straight line, I can drag
it with the mouse in any direction.

Subtract the last position of the moving rectangle from the position
you want to move it to (don't move it yet!). Lets call this vector
'v'. Assuming you have one moving rectangle and a number of fixed
rectangles, and the rectangles are not overlapping, you can find the
collision distance using something like this function (I havent tested
it):

/**
* @param mr Moving rectangle
* @param fr Fixed rectangle
* @param v Motion vector for the moving rectangle
* @param maxDist The current first collision found, start with 1
*/
float getCollisionDist(Rectangle mr, Rectangle fr, Point v, float
maxDist) {
if (v.x != 0) {
maxDist = checkDist((float) (v.x > 0 ? fr.x - (mr.x + mr.width) :
fr.x + fr.width - mr.x) / v.x, maxDist);
}

if (v.y != 0) {
maxDist = checkDist((float) (v.y > 0 ? fr.y - (mr.y + mr.height) :
fr.y + fr.height - mr.y) / v.y, maxDist);
}

return maxDist;
}

float checkDist(float dist, float maxDist) {
return dist < 0 ? maxDist : Math.min(dist, maxDist);
}

It will return a float indicating the collision distance, 1 means
there was no collision. If you have multiple fixed rectangles you just
run this method for each one and set the maxDist parameter to the
value returned by the last function call. When all is done, you move
your rectangle v * dist.

/Jesper Nordenberg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,102
Latest member
GregoryGri
Top