Basic rectangle splitting
I'm stuck on some trivial question and, well, I guess I need help here.
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 if
s, 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.
精彩评论