Ответ от Реми Лебо имеет незначительную проблему. Если oColl
пусто, calcUnionColl
вернет значение по умолчанию a
. Таким образом, если значение по умолчанию a
равно x1:0, x2:0, y1:0, y2:0
, то, если calcUnionColl
возвращает это значение, невозможно узнать, является ли это действительным объединением значений в oColl
, или если
oColl
было пусто.
Обычный прием при поиске максимального значения, кратного int
с, - инициализация рабочего максимума с помощью INT_MIN
. И таким же образом, при поиске минимального значения, мы запускаем рабочий минимум с помощью INT_MAX
.
Найти объединение прямоугольников - это не что иное, как найти минимальное / максимальное значение координат углов прямоугольников, поэтому мы можем использовать описанный выше прием.
Например, если a = {x1:INT_MAX, x2:INT_MIN, y1:INT_MAX, y2:INT_MIN}
, то при вычислении объединения a
и любого прямоугольника b
мы будем иметь:
b.x1 <= a.x1 // a.x1 == INT_MAX
b.y1 <= a.y1 // a.y1 == INT_MAX
b.x2 >= a.x1 // a.x1 == INT_MIN
b.y2 >= a.y2 // a.y2 == INT_MIN
Таким образом, объединение a
и b
в этом случае будет b
Использование этого в calcUnionColl()
:
// I assume the data-type for your rectangle coordinates is `int`.
// If you use another datatype, change this accoringly.
Rectangle RectangleCollection::calcUnionColl() const {
int i_min = std::numeric_limit<int>::min(); // c++ way of getting INT_MIN
int i_max = std::numeric_limit<int>::max(); // c++ way of getting INT_MAX
set<Rectangle>::iterator it;
Rectangle a(i_max, i_min, i_max, i_min);
for (it = oColl.begin(); it != oColl.end(); ++it) {
a = a.unionRect(*it);
}
return a;
}
Теперь, если oColl
пусто, calcUnionColl()
вернет x1:INT_MAX, x2:INT_MIN, y1:INT_MAX, y2:INT_MIN
. Это должно быть недопустимым значением для прямоугольника, начиная с x1>x2
и y1>y2
, и его должно быть легко проверить.
Иногда вам даже не нужно проверять его, поскольку оно часто является недопустимым значением, «которое имеет смысл» для дальнейших вычислений.