Основное разбиение прямоугольника - PullRequest
1 голос
/ 14 октября 2011

Я застрял на каком-то тривиальном вопросе, и, думаю, мне нужна помощь здесь.

enter image description here

У меня есть два прямоугольника, и они гарантированно имеют одну общую точку из своих 4 базовых точек (верхняя часть рисунка). Также гарантируется, что они выровнены по оси.

Я знаю эту общую точку (которая также легко выводится), размеры и координаты этих прямоугольников.


Теперь мне нужно получить координаты прямоугольников с именами 1 и 2, и я ищу простой способ сделать это (нижняя часть рисунка) .

Моя текущая реализация опирается на множество if операторов, и я подозреваю, что я слишком глуп, чтобы найти лучший способ.

Спасибо.

Обновление: моя текущая реализация.

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 then 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);

Это рефакторинг, но методы getCommonPoint и getAdjacent... и getOpposite содержат много операторов if, и я подумал, можно ли это сделать лучше.

Ответы [ 3 ]

1 голос
/ 14 октября 2011

Предполагая, что у вас были RA и RB в качестве входных данных, и какой бы язык вы не использовали, класс Rectangle, вот способ сделать это с 4 if s, Math.Min, Math.Max и 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));
    }  
}  

Этот код был написан в Блокноте, поэтому он может иметь опечатку или две, но логика логична.

1 голос
/ 14 октября 2011

Верхнее и нижнее значения прямоугольника 1 совпадают с большим прямоугольником.Левое и правое значения прямоугольника 2 совпадают с маленьким прямоугольником.Нам нужно только получить левое и правое значения прямоугольника 1, а также верхнее и нижнее значения для прямоугольника 2. Таким образом, у нас есть только 2 простых оператора if:

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)

В приведенном выше примере Rectangle Конструктор принимает в качестве входных данных: слева, сверху, ширина, высота.

1 голос
/ 14 октября 2011

Из того, что я понимаю, кажется, что вам нужно иметь оператор if (или switch) для определения ориентации прямоугольника, и оттуда это будет просто добавить и вычесть:

Если вы знаете координаты внутреннего синего прямоугольника (и размеры прямоугольника в целом), то найти другие не должно быть проблемой. Одна из точек R1 и R2 всегда будет одинаковой: равна смежной синей прямоугольной точке. а остальные просто математика.

Не похоже, что вы можете уйти от первоначального оператора if / switch. Если бы прямоугольник мог быть только вверх или вниз, то вы могли бы просто сделать смещение отрицательным или положительным, но оно также может быть левым или правым ... так что вы можете застрять там. Вы можете сделать смещение - / + для вертикального или горизонтального состояния, но тогда вам придется проверять каждый расчет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...