Home > front end >  How to check if two rectangles collide over the axis
How to check if two rectangles collide over the axis

Time:12-07

I think I've got some kind of duplicate question, but I just can't figure it out.

So I got a Region class. This class contains four attributes. aX, aY and bX, bY. Now I want to produce a method doesCollide(Region other). I've tried many things, but can't get it to work. I think it is, because the regions refer to a region on a minecraft world, where the to points a and b can be negative. Can someone help me out?

For better understanding I did a little drawing of a scenario:

What I've tried:

Due to a hint of a user I tried it using the java.awt.Rectangle class:

        Rectangle thisRectangle = new Rectangle((int) aX, (int) aY, Math.abs((int) bX) - Math.abs((int) aX), Math.abs((int) bY) - Math.abs((int) aY));
        Rectangle otherRectangle = new Rectangle((int) other.aX, (int) other.aY, Math.abs((int) other.bX) - Math.abs((int) other.aX), Math.abs((int) other.bY) - Math.abs((int) other.aY));
        return thisRectangle.intersects(otherRectangle);

(I absolutely don't know if I've done it right)

I tried something that I would say is the "standard" thing used here:

return aX < other.bX && bX > other.aX & aY < other.bY && bY > other.aY

Well, didn't work either.

CodePudding user response:

Okay, some things to point out. First, if you have double values you can use Rectangle2D.Double. Second, it handles negative numbers fine.

I would suggest creating a method to convert a region to a Rectangle2D.

public Rectangle2D getBounds(Region r){
    double x, w;
    if(r.aX < r.bX ){
      x = r.aX;
      w = r.bX - r.aX;
    } else{
      x = r.bX;
      w = r.aX - r.bX;
    }
    double y, h;
    if(r.aY < r.bY){
      y = r.aY;
      h = r.bY - r.aY;
    } else{
      y = r.bY;
      h = r.aY - r.bY;
    } 
    return new Rectangle2D.Double(x, y, w, h);
}

What this is doing, checking to make sure aX, aY and bX, bY are in the correct order, so that x,y is the top left corner of the rectangle and the width and height are positive (or zero) values. I've written it as a method on a region, but you can make it as a method of Region. Such that:

public boolean intersects(Region other){
    return getBounds().intersects(other.getBounds());
}

CodePudding user response:

Here is one way to approach it. I am using records which are simply immutable classes. The same approach would be used for the Rectangle2D class in the Java API. Note that this presumes that the first coordinate in the constructor is the upper left, and the other is the lower right. You might consider specifying your region as a bounded area with the upper left coordinates specified along with the width and height. It will then be trival to return the other coordinates as required.

import java.awt.Rectangle;
public class RectangleIntersections {
    
    record Region(int aX, int aY, int bX, int bY) {
        public int getWidth() {
            return bX-aX;
        }
        public int getHeight() {
            return bY-aY;
        }
        public boolean intersects(Region other) {
            return new Rectangle(aX, aY, getWidth(), getHeight()).intersects(
                    new Rectangle(other.aX, other.aY, other.getWidth(), other.getHeight()));
        }
    }
    public static void main(String[] args) {
        new RectangleIntersections().start();
        
    }
    public void start() {
        Region r1 = new Region(0,0, 100,100);
        Region r2 = new Region(50,50, 150,150);
        System.out.println(r1.intersects(r2));
        Region r3 = new Region(101, 101, 110,120);
        System.out.println(r1.intersects(r3));
    }
    
}

prints

true
false
  • Related