IAmYourFaja
IAmYourFaja

Reputation: 56934

What's wrong with my "contains" algorithm?

Modeling closely to Java AWT's Rectangle2D class, I have my Rectangle POJO:

public class Rectangle {
    // The Coordinate of the upper-left corner of the Rectangle.
    private Coordinate upperLeft;   // upperLeft.getXVal() and upperLeft.getYVal()

    // The width of the Rectangle.
    private BigDecimal width;

    // The height of the Rectangle.
    private BigDecimal height;

    // Determine if we wholly contains otherRectangle. (no touching sides).
    @Override
    public boolean contains(Rectangle otherRectangle) {
        BigDecimal x = otherRectangle.getUpperLeft().getXVal();
        BigDecimal y = otherRectangle.getUpperLeft().getYVal();
        BigDecimal w = otherRectangle.getWidth();
        BigDecimal h = otherRectangle.getHeight();
        BigDecimal x0 = getUpperLeft().getXVal();
        BigDecimal y0 = getUpperLeft().getYVal();

        if(isSingularity() || w.doubleValue() <= 0.0 || h.doubleValue() <= 0.0)
            return false;

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

When I execute the following code:

// r1 has upperLeft corner at (0,4), width = 6, height = 4
// r2 has upperLeft corner at (1,2), width = 1, height = 1
Rectangle r1 = new Rectangle(new Coordinate(0,4), 6, 4);
Rectangle r2 = new Rectangle(new Coordinate(1,2), 1, 1);

boolean result = r1.contains(r2);

The answer is false!

Note, I wrote this with the following assumption:

Now then, I believe there's something awry about my return value:

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

But I can't figure out where I'm going wrong. Any ideas?

Upvotes: 1

Views: 92

Answers (2)

bcorso
bcorso

Reputation: 47148

You have your y inequalities mixed up. Because you use top-left as the starting point you need to check for containment in the negative direction.

enter image description here

The above image plots r1 (green) and r2 (pink). To fix your code make the following adjustments

// y must be less than y0
y.doubleValue() <= y0.doubleValue()

// y - h must be greater than y0 - h0
(y.doubleValue() - h.doubleValue()) >= (y0.doubleValue() - getHeight().doubleValue())

Upvotes: 2

NPE
NPE

Reputation: 500703

You seem to be confusing two different coordinate systems. Your code uses the coordinate system where the Y axis points from top to bottom (this is often used in computer graphics). At the same time your comments refer to the standard mathematical coordinate system where the Y axis points from bottom to top.

This is why your code doesn't work the way you expect it to.

You need to decide which coordinate system to use, and then either fix the code or change the way you compute coordinates in your head.

Upvotes: 1

Related Questions