开发者

Basic rectangle splitting

I'm stuck on some trivial question and, well, I guess I need help here.

Basic rectangle splitting

I have two rectangles and it's guaranteed that they have one common point from their 4 base points (upper part of the picture). It's also guaranteed that they are axis-aligned.

I know this common point (which also can be easily deduced), dimensions and the coordinates of these rectangles.


Now, I need to retrieve the coordinates of the rectangles named 1 and 2 and I'm seeking for an easy way to do that (lower part of the picture).

My current implementation relies on many if statements and I suspect I'm too stupid to find a better way.

Thank you.

Update: My current implementation.

Point commonPoint = getCommonPoint(bigRectangle, smallRectangle);

rectangle2 = new Rectangle(smallRectangle.getAdjacentVerticalPoint(commonPoint),
                           bigRectangle.getOppositePoint(commonPoint));

rectangle1 = new Rectangle(smallRectangle.getAdjacentHorizontalPoint(commonPoint)
                           bigRectangle.getOppositePoint(commonPoint));

// Now simply adjust one of these rectangles to remove the overlap,
// it's trivial - we take the 'opposite' points for 'small' and 'big'
// rectangles and th开发者_运维技巧en use their absolute coordinate difference as
// a fix for either width of 'rectangle2' or height of 'rectangle1'
// (in this situation it's going to be width).

adjustRectangle(rectangle2);

This is refactored, but still methods getCommonPoint and getAdjacent... and getOpposite have many if statements and I thought if this can be done better.


The top and bottom values of Rectangle 1 are the same as the big rectangle. The left and right values of rectangle 2 are the same as the small rectangle. We only need to obtain the left and right values of rectangle 1, and the top and bottom values for rectangle 2. So we only have 2 simple if-statements:

if (bigRectangle.Left == smallRectangle.Left) 
    left = smallRectangle.Right
    right = bigRectangle.Right
else
    left = bigRectangle.Left
    right = smallRectangle.Left
rectangle1 = new Rectangle(left, bigRectangle.Top, right - left, bigRectangle.Height)

if (bigRectangle.Top == smallRectangle.Top)
    top = smallRectangle.Bottom
    bottom = bigRectangle.Bottom
else
    top = bigRectangle.Top
    bottom = smallRectangle.Top
rectangle2 = new Rectangle(smallRectangle.Left, top, smallRectangle.Width, bottom - top)

In the above, the Rectangle constructors takes as inputs: left, top, width, height.


From what I understand, seems like you need to have an if (or switch) statement to determine the orientation of the rectangle, and from there it would just be some easy adding and subtracting:

If you know the coords of the inner blue rectangle (and the dimensions of the rect as a whole), then finding the others should be no problem. One of the R1 and R2 points will always be the same: equal to the adjacent blue rect point. and the others is just a lil math.

Doesn't seem like you can get away from the initial if/switch statement. If the rectangle could only be up or down, then you could just make the offset negative or positive, but it can also be left or right..so you might be stuck there. You can make a -/+ offset for a vertical or horizontal state,but then you'd have to do a check on each calculation


Assuming you had RA and RB as your inputs, and whatever language you're using has a Rectangle class, here's a way to do it with 4 ifs, Math.Min, Math.Max, and Math.Abs:

Rectangle r1, r2; // Note - Rectangle constructor: new Rectangle(X, Y, Width, Height)
if (RA.X = RB.X) {  
    r1 = new Rectangle(Math.Min(RA.Right, RB.Right), Math.Min(RA.Y, RB.Y), Math.Abs(RA.Width - RB.Width), Math.Max(RA.Height, RB.Height));  
    if (RA.Y = RB.Y) {
        // Intersects Top Left
        r2 = new Rectangle(RA.X, Math.Min(RA.Bottom, RB.Bottom), Math.Min(RA.Width, RB.Width), Math.Abs(RA.Height - RB.Height));  
    } else {  
        // Intersects Bottom Left
        r2 = new Rectangle(RA.X, Math.Max(RA.Bottom, RB.Bottom), Math.Min(RA.Width, RB.Width), Math.Abs(RA.Height - RB.Height));
    }  
} else {  
    r1 = new Rectangle(Math.Min(RA.X, RB.X), Math.Min(RA.Y, RB.Y), Math.Abs(RA.Width - RB.Width), Math.Max(RA.Height, RB.Height));
    if (RA.Y = RB.Y) {  
        // Intersects Top Right
        r2 = new Rectangle(Math.Max(RA.X, RB.X), Math.Min(RA.Bottom, RB.Bottom), Math.Min(RA.Width, RB.Width), Math.Abs(RA.Height - RB.Height));
    } else {  
        // Intersects Bottom Right
        r2 = new Rectangle(Math.Max(RA.X, RB.X), Math.Min(RA.X, RA.Y), Math.Min(RA.Width, RB.Width), Math.Abs(RA.Height - RB.Height));
    }  
}  

This code was written in Notepad so it might have a typo or two, but the logic is sound.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜