обрамляющий прямоугольник
От: Аноним  
Дата: 16.12.13 05:46
Оценка:
Здравствуйте, коллеги
Столкнулся с такой задачей в некую функцию добавляют/ удаляют прямоугольники заданный двумя точками X1Y1 (верхний, левый) и X2Y2 (нижний правый).

void Add(X1, Y1, X2, Y2);
void Remove(X1, Y1, X2, Y2);

И собственно задача постоянно поддерживать максимальный обрамляющий прямоугольник, над всеми добавленными, ну при одном добавлении в этом нет ник каких проблем, просто расширяем экстент и все, сложности начинаются когда прямоугольники удаляют.
Re: обрамляющий прямоугольник
От: watchmaker  
Дата: 16.12.13 08:52
Оценка: 5 (1)
Здравствуйте, Аноним, Вы писали:

А>Столкнулся с такой задачей в некую функцию добавляют/ удаляют прямоугольники заданный двумя точками X1Y1 (верхний, левый) и X2Y2 (нижний правый).


А>void Add(X1, Y1, X2, Y2);

А>void Remove(X1, Y1, X2, Y2);


Удаляются только те прямоугольники, которые уже были добавлены? Если это так, то просто заведи пару сбалансированных деревьев поиска, например. При добавлении прямоугольника добавляешь в одно дерево ключи x1 и x2, а в другое дерево ключи y1 и y2. При удалении просто исключаешь из деревьев соответствующие ключи. Обрамляющий прямоугольник находится из наименьшего и наибольшего значения ключей из обоих деревьев. Дублирующиеся ключи в деревьях можно хранить либо многократно, либо в комбинации "уникальный ключ" + счётчик.
Если удаляться могут не только добавленные прямоугольники, и нужно определять такую ситуацию (например, сообщая об невозможности удаления), то можно несложно изменить структуру данных и для такого случая — в дереве сделать ключи уникальными, а в данных, связанных с ключом, хранить множество уникальных идентификаторов для добавленных прямоугольников. Тогда при вызове удаления можно будет определить, добавлялся ранее такой прямоугольник или нет.
Re[2]: обрамляющий прямоугольник
От: Кодт Россия  
Дата: 16.12.13 09:51
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Если удаляться могут не только добавленные прямоугольники, и нужно определять такую ситуацию (например, сообщая об невозможности удаления), то можно несложно изменить структуру данных и для такого случая — в дереве сделать ключи уникальными, а в данных, связанных с ключом, хранить множество уникальных идентификаторов для добавленных прямоугольников. Тогда при вызове удаления можно будет определить, добавлялся ранее такой прямоугольник или нет.


Проще говоря, сделать (хеш)-таблицу с ключами — 4-элементными векторами.
Добавляем прямоугольник — добавляем в его таблицу (кстати, проверяем, не был ли он добавлен ранее; что делать с дубликатами?) и добавляем его габариты в мультимножества.
Удаляем — соответственно, проверяем наличие в таблице, удаляем оттуда, и вычёркиваем по одному вхождению из мультимножеств.


А если удаляться могут произвольные прямоугольники (вырезаться из существующего покрытия), то придётся сделать quad-tree.
Перекуём баги на фичи!
Re: обрамляющий прямоугольник
От: __kot2  
Дата: 16.12.13 19:30
Оценка:
Здравствуйте, Аноним, Вы писали:
А>И собственно задача постоянно поддерживать максимальный обрамляющий прямоугольник, над всеми добавленными, ну при одном добавлении в этом нет ник каких проблем, просто расширяем экстент и все, сложности начинаются когда прямоугольники удаляют.
простенькое решение — завести 4 кучи (heap). в C++ кстати ф-ии есть в стандартной библиотеке для работы с ними.
каждая куча — координата соотв-но x, y левого верхнего угла и x, y правого нижнего

добавляем-удаляем элементы кучи, а на вершине их всегда лежит наш обрамляющий прямоугольник
Re[2]: обрамляющий прямоугольник
От: watchmaker  
Дата: 16.12.13 19:45
Оценка:
Здравствуйте, __kot2, Вы писали:

__>простенькое решение — завести 4 кучи (heap). в C++ кстати ф-ии есть в стандартной библиотеке для работы с ними.

__>каждая куча — координата соотв-но x, y левого верхнего угла и x, y правого нижнего
Куча плоха тем, что из неё удалить элемент по значению можно только почти полным просмотром. Уж если ограничивать себя стандартной библиотекой C++, то std::map или std::multiset куда лучше себя ведут по мере увеличения числа прямоугольников.
Re[3]: обрамляющий прямоугольник
От: __kot2  
Дата: 16.12.13 19:50
Оценка:
Здравствуйте, watchmaker, Вы писали:
W>Здравствуйте, __kot2, Вы писали:
__>>простенькое решение — завести 4 кучи (heap). в C++ кстати ф-ии есть в стандартной библиотеке для работы с ними.
__>>каждая куча — координата соотв-но x, y левого верхнего угла и x, y правого нижнего
W>Куча плоха тем, что из неё удалить элемент по значению можно только почти полным просмотром. Уж если ограничивать себя стандартной библиотекой C++, то std::map или std::multiset куда лучше себя ведут по мере увеличения числа прямоугольников.
че-то не подумал. в общем, да, 4 дерева получается лучше. правда нужные элементы не на вершине будут лежать, а будут самыми левыми или правыми листьями, но тоже ничего страшного
Re: обрамляющий прямоугольник
От: pik Италия  
Дата: 16.12.13 19:53
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>И собственно задача постоянно поддерживать максимальный обрамляющий прямоугольник


коллеги, я чтото непонял? неужели для этой задачи недостаточно после каждого Add/Remove банально мин и мах координаты определять?
Re[4]: обрамляющий прямоугольник
От: watchmaker  
Дата: 16.12.13 20:00
Оценка:
Здравствуйте, __kot2, Вы писали:

__> 4 дерева получается лучше. правда нужные элементы не на вершине будут лежать, а будут самыми левыми или правыми листьями, но тоже ничего страшного

Зачем четыре-то? :)
Сам же сказал, что элементы будут левыми или правыми листьями.
Re[2]: обрамляющий прямоугольник
От: watchmaker  
Дата: 16.12.13 20:08
Оценка:
Здравствуйте, pik, Вы писали:

pik>Здравствуйте, Аноним, Вы писали:


А>>И собственно задача постоянно поддерживать максимальный обрамляющий прямоугольник


pik>коллеги, я чтото непонял? неужели для этой задачи недостаточно после каждого Add/Remove банально мин и мах координаты определять?


Достаточно. Просто это может быть сложнее или проще сделать. Как именно устроена задача из формулировки непонятно. Если там под удалением прямоугольника подразумевается csg, то даже с самой подзадачей определения минимальной координаты возникнут некоторые сложности (хотя, конечно, на плоскости да с прямыми параллельными осям всё проще). К сожалению из исходного сообщения не ясно, нужно ли csg рассматривать или требуется что-то другое.
Re[3]: обрамляющий прямоугольник
От: pik Италия  
Дата: 16.12.13 20:19
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Достаточно. Просто это может быть сложнее или проще сделать. Как именно устроена задача из формулировки непонятно. Если там под удалением прямоугольника подразумевается csg, то даже с самой подзадачей определения минимальной координаты возникнут некоторые сложности (хотя, конечно, на плоскости да с прямыми параллельными осям всё проще). К сожалению из исходного сообщения не ясно, нужно ли csg рассматривать или требуется что-то другое.


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


в некую функцию добавляют/ удаляют прямоугольники заданный двумя точками X1Y1 (верхний, левый) и X2Y2 (нижний правый).

Re[5]: обрамляющий прямоугольник
От: __kot2  
Дата: 16.12.13 20:44
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, __kot2, Вы писали:


__>> 4 дерева получается лучше. правда нужные элементы не на вершине будут лежать, а будут самыми левыми или правыми листьями, но тоже ничего страшного

W>Зачем четыре-то?
W>Сам же сказал, что элементы будут левыми или правыми листьями.
да, с деревом можно двумя обойтись — отдельно для x и для y
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.