Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constrain Rectangle within Rectangle

I am using Java's Rectangle class in a program.

I have two Rectangle objects:

Rectangle big = new Rectangle(...);
Rectangle small = new Rectangle(...);

The specific sizes of the rectangles are not important. However, big will always be larger than small (in both width and height).

Usually, small is entirely contained within big. I can use Rectangle#contains to verify this. However, when this is not the case, I would like to move small to be entirely contained within big. The dimensions of neither rectangle should change.

For example:

Rectangles Example

I know could use four conditionals with Math.max and Math.min, but is there a more elegant way of doing this?

like image 846
baum Avatar asked Jan 02 '15 00:01

baum


2 Answers

You could do it with only Math.max and Math.min. Try something like this:

small.setLocation(
    Math.max(Math.min(small.getX(),big.getX() - small.getWidth()),big.getX()),
    Math.max(Math.min(small.getY(),big.getY() - small.getHeight()),big.getY())
);

You'd have to consider readability though.

like image 72
Ghostkeeper Avatar answered Oct 23 '22 10:10

Ghostkeeper


You need a stronger design. If you extend upon the Rectangle class, you can add the exact functionality you're looking for. Apparently the "big rectangle" should act as a container, containing the smaller rectangle:

class BigRectangle extends Rectangle {
    //reference to or list of rectangle(s) here

    private boolean isAlignedWith(Rectangle rect) {
        return /* bounds logic */;
    }

    private void align(Rectangle rect) {
        //move rectangle to proper position
    }

    public void add(Rectangle rect) {
        if(!isAlignedWith(rect)) {
            align(rect);
        }

        //store in reference or add to list
    }
}

Now, you can simply add the smaller rectangle to the bigger one:

Rectangle smallRectangle = new Rectangle();
BigRectangle bigRectangle = new BigRectangle();
bigRectangle.add(smallRectangle); //automatically aligns if needed

You are now hiding the (needed) logic, keeping your central unit of code clean. This is my opinion of the most elegant way to handle this. (I would also probably create an interface RectangleContainer or ShapeContainer, having BigRectangle implement that. The interface would contain a method add(Rectangle) or add(SmallShape))

like image 39
Vince Avatar answered Oct 23 '22 12:10

Vince