asteri
asteri

Reputation: 11572

How can I determine which side a collision is on?

I'm implementing some fairly straightforward 2D collision detection in Java, and I'm a little tripped up on how to figure out which surface (or side of the hit-box) the collision has occurred on.

I've looked through the questions on this site and attempted extensive Google-fu elsewhere, and the closest it's gotten me was something like this:

public Side getCollisionSide(Rectangle main, Rectangle incoming) {
    boolean toTheLeft = main.getX() - incoming.getX() < 0;
    boolean toTheTop = main.getY() - incoming.getY() < 0;
    // ...but what can I do from here?
}

The problem is that this doesn't actually give which side was collided with. It can tell me which quadrant the collision occurred in, in a grid with the origin set as main's coordinates. But if an object hits main from the left (and happens to be lower in the field on the Y-axis), I can't know using this method whether the collision has occurred from the left or from the bottom.

Does anyone know a solution for this, or even just a different implementation?

I see how having speed and directional information could be a benefit (or even a solution, if objects can only move through one dimension at a time). However if objects can move diagonally, I don't see how to escape the same issue.

Upvotes: 0

Views: 865

Answers (2)

Moataz Elmasry
Moataz Elmasry

Reputation: 2519

As the other answer points out, you need more parameters to get that piece of information.

You can solve this problem in many ways, I assume that these two triangles are movable (or at least one of them) and they have constant size. In this case you can for example save an a queue the last 5-10 last positions of the triangles and be able to track its movement. You can for simplicity and abstraction even save that queue inside your rectangle class.

Another solution that won't require saving the previous positions is to check more frequently the positions (or set a trigger to inform you when a position change happens) and limit the rectangles to move only in small steps. if your trigger contains trigger like: rectMoved(rectangleId, newPosition) then you can know easily which rectangle hit the other and from which side

Cheers

Upvotes: 0

NickJ
NickJ

Reputation: 9559

You need more arguments than just rectangle, because rectangles only have position and size information. If the rectangles collide, at least one of them must be moving, but you don't pass in any velocity data. Maybe try subclassing Rectange:

public class MovingRectange extends Rectangle {

  int xVelocity;
  int yVelocity;

  //etc
}

Then pass the MovingRectange instances to getCollisionSide...

Upvotes: 1

Related Questions