IAmYourFaja
IAmYourFaja

Reputation: 56944

Detecting rectangle adjacency in Java

I have implemented the following Rectangle POJO with correct intersects(Rectangle) and contains(Rectangle) methods:

public class Rectangle {
    private double x;       // x-value of upper-left corner of rectangle
    private double y;       // y-value of upper-left corner of rectangle
    private double width;   // width of the rectangle
    private double height;  // height of the rectangle

    // Returns true if this Rectangle intersects otherRectangle.
    public boolean intersects(Rectangle otherRectangle) {
        double x = otherRectangle.getX();
        double y = otherRectangle.getY();
        double w = otherRectangle.getWidth();
        double h = otherRectangle.getHeight();
        double x0 = getX();
        double y0 = getY();

        if(isEmpty() || w <= 0 || h <= 0)
            return false;

        return (
            x + w > x0 &&
            y + h > y0 &&
            x < x0 + getWidth() &&
            y < y0 + getHeight()
        );
    }

    // Returns true if this Rectangle contains otherRectangle.
    public boolean contains(Rectangle otherRectangle) {
        double x = otherRectangle.getX();
        double y = otherRectangle.getY();
        double w = otherRectangle.getWidth();
        double h = otherRectangle.getHeight();
        double x0 = getX();
        double y0 = getY();

        return (
            x >= x0 &&
            y >= y0 &&
            x < x0 + getWidth() &&
            y < y0 + getHeight()
        );
    }

    // Returns true if this Rectangle is adjacent to otherRectangle.
    public boolean isAdjacentTo(Rectangle otherRectangle) {
        // ???
    }
}

Now I am trying to implement isAdjacentTo and am choking. I was told by another SOer that, for adjacency, I could:

...just do containment checks on one axis (like the top and bottom sides), and then make sure each corner is NOT contained in the other direction (like horizontally).

But still I'm not visualizing the solution. Any ideas? Optimally I could make use of the intersects and contains methods, but I'll take anything that truly works.

Upvotes: 2

Views: 1518

Answers (1)

jgon
jgon

Reputation: 688

Ok. I'm going to make up some methods leftSide(), rightSide(), topSide() and bottomSide() which are the left, right, top, and bottom of the rectangles respectively (bottom is numerically smaller than top, though if it were displayed on a screen it would be the top).

Then the code:

// Returns true if this Rectangle is adjacent to otherRectangle.
public boolean isAdjacentTo(Rectangle otherRectangle, double tolerance) {
    if(Math.abs(getLeftSide()-otherRectangle.getRightSide())<tolerance||Math.abs(otherRectangle.getLeftSide()-getRightSide())<tolerance)
    {
        return !(getTopSide()<otherRectangle.getBottomSide()||otherRectangle.getTopSide()<getBottomSide());
    }
    if(Math.abs(getTopSide()-otherRectangle.getBottomSide())<tolerance||Math.abs(otherRectangle.getTopSide()-getBottomSide())<tolerance)
    {
        return !(getRightSide()<otherRectangle.getLeftSide()||otherRectangle.getRightSide()<getLeftSide());
    }
    return false;
}

Now here's what it does. Is the top side of one the same as the bottom side of the other? Yes -> return true if there is no space between them. (I'm checking to see if the right side of one is to the left of the left side of the other (for both rectangles)) No -> do the same thing for sharing right/left sides

If they don't share right/left sides return false because they don't share any sides.

tolerance is used because you can't compare doubles for equality.

Upvotes: 2

Related Questions