Russian Qt Forum
Ноябрь 22, 2024, 20:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Найти дырки  (Прочитано 10056 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Август 21, 2012, 20:42 »

Добрый день

Есть массив/контейнер точек образующий сложный замкнутый контур (аттач). Некоторые отрезки могут совпадать.
Задача: удалить совпадающие отрезки и разбить исходный контур на N новых

- первый новый = внешний (вмещающий)
- остальные = "дырки"

Результат выдать в виде массивов индексов. Напр дырок нет, значит на выходе один std::vector <int> со значениями 0..N-1 (где N -число точек). Есть дырка - значит какие-то индексы перенесены во второй вектор и.т.д

Мысли?

Спасибо
« Последнее редактирование: Август 22, 2012, 09:50 от Igors » Записан
V1KT0P
Гость
« Ответ #1 : Август 21, 2012, 21:32 »

Если я правильно понял то по точкам строится контур, где линии могут пересекаться?
Тогда самый банальный, это разбить контур на линии, там где линии налаживаются или пересекаются разбивать эти линии на новый. Получится избыток линий в которых простым сравнением начала и конца координат можно отсеять дублирующие. Затем найти точки из которых идут только два луча под углом в 180 градусов, в результате будет убран избыток линий. Что-то типа такого?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Август 22, 2012, 09:58 »

Привет, Витя, давно Вас не было видно

Уточним. Каждый отрезок получается при соединении последующей точки с предыдущей. Гарантируется что контур замкнут - последняя соединена с первой. Поэтому

1) Рассматривается только случай совпадения 2 отрезков - ну это тоже можно считать пересечением. Никакого "физического" удаления нет, если контур дырки выделен, такие отрезки сами и отпадут.

2) Никаких удалений/прореживаний не требуется, сумма индексов во всех выходных массивах должны быть равна N (исходное число точек) 
Записан
_OLEGator_
Гость
« Ответ #3 : Август 22, 2012, 10:23 »

Внешний контур найти достаточно просто.
В общем случае даже можно начинать с любой точки, последовательно перебирая. В местах соединения нескольких ломанных, следующую точку брать в той ломанной, в которой она больше всех удалена от центра и соответственно продолжать перебор точек в этой ломанной.
Все это до тех пор, пока следующая точка уже будет в пути, в общем случае придется выкинуть все лишние точки до пересечения.

UPD
Не, такой алгоритм не катит.
« Последнее редактирование: Август 22, 2012, 10:30 от _OLEGator_ » Записан
V1KT0P
Гость
« Ответ #4 : Август 22, 2012, 20:50 »

Привет, Витя, давно Вас не было видно
Да пока был безработным ездил по Украине =).

Ты лучше уточни что тебе надо. Дай хотя-бы два маленьких примера как было до и как должно быть после. А то я тебя наверно неправильно понял.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Август 22, 2012, 21:45 »

Внешний контур найти достаточно просто.
Ну непросто но можно. Начать с внешней точки (придется ее найти) ну и обходить, если есть выбор куда идти то выбираем "внешний" отрезок по углу. Все это довольно длинно и муторно, ну и дальше-то что? (комнаты как искать)

Ты лучше уточни что тебе надо. Дай хотя-бы два маленьких примера как было до и как должно быть после. А то я тебя наверно неправильно понял.
А что неясно-то? Что один массив (индексов) надо разбить на несколько? Что такое совпадающие отрезки? Ну вот в аттаче "что нужно получить" - каждый массив нарисован своим цветом
Записан
V1KT0P
Гость
« Ответ #6 : Август 22, 2012, 22:02 »

Внешний контур найти достаточно просто.
Ну непросто но можно. Начать с внешней точки (придется ее найти) ну и обходить, если есть выбор куда идти то выбираем "внешний" отрезок по углу. Все это довольно длинно и муторно, ну и дальше-то что? (комнаты как искать)

Ты лучше уточни что тебе надо. Дай хотя-бы два маленьких примера как было до и как должно быть после. А то я тебя наверно неправильно понял.
А что неясно-то? Что один массив (индексов) надо разбить на несколько? Что такое совпадающие отрезки? Ну вот в аттаче "что нужно получить" - каждый массив нарисован своим цветом
Вот теперь наконец-то стало ясно =).
1) Находим внешний контур и переносим эти точки в новый массив.
2) Берем самую левую верхнюю точку и если взять направление вправо то постоянно выбирать направление вправо. Как только достигнута точка с которой начали, то все эти точки переносим в новый массив.
3) Проверяем есть ли еще точки, если есть то п.2.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Август 23, 2012, 02:21 »

Вот теперь наконец-то стало ясно =).
1) Находим внешний контур и переносим эти точки в новый массив.
2) Берем самую левую верхнюю точку и если взять направление вправо то постоянно выбирать направление вправо. Как только достигнута точка с которой начали, то все эти точки переносим в новый массив.
3) Проверяем есть ли еще точки, если есть то п.2.
Как уже сказано выше найти внешний контур - геморрой порядочный. А главное 2. 3 работать не будут т.к. предложены "глядя на разноцветные контуры" - но ведь это уже результат. А посмотрите на исходную картинку - там есть "перепонка" соединяющая "синюю" и "черную" комнаты. Она останется после выделения внешнего контура.

К слову: одна точка самая левая, другая самая верхняя - какая же из них "самую левая верхняя"?  Улыбающийся
Записан
Fat-Zer
Гость
« Ответ #8 : Август 23, 2012, 03:57 »

на входе массив точек или отрезков? если первое, то задача некорректна, по данным нельзя однозначно построить контура... если второе, то не вижу проблем... самая внешняя-левая точка принадлежит внешнему контуру... потом по отрезкам обойти его... при проходе отрезки из списка можно удалять...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Август 23, 2012, 04:19 »

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

Почему "самая внешняя-левая"? Мне кажется что и "самая правая (нижняя, верхняя)" также принадлежат внешнему контуру  Улыбающийся

Ну и хотелось бы что-то поконкретнее вместо многочисленных многоточий...  Улыбающийся 
Записан
Fat-Zer
Гость
« Ответ #10 : Август 23, 2012, 05:34 »

Установлено правило/соглашение - каждая точка соединена с последующей и предыдущей (как они следуют в массиве), последняя соединена с первой. Поэтому точки задают и отрезки.
понял... рисунок нарисован «не отрывая пера»

Почему "самая внешняя-левая"? Мне кажется что и "самая правая (нижняя, верхняя)" также принадлежат внешнему контуру  Улыбающийся
нуда... я к тому, что выбрать первую точку не проблема...
Ну и хотелось бы что-то поконкретнее вместо многочисленных многоточий...  Улыбающийся 
у меня уже половина седьмого на часах и внятно записать свои мысли уже не получается...
в общем тоже самое, что писал V1KT0P...
внешний контур находится точно также, пунктами 2-3: представь что из угла идёшь по линии (по часовой стрелке для определённости)... встретил развилку и выбрал поворот налево... так ты гарантированно пройдёшь по контуру, а не по перемычкам, автоматом обоходя их...
самая левая-верхняя или верхняя-левая - не важно... главное, чтобы она была на краю [и может быть чтобы это был угол]
Записан
V1KT0P
Гость
« Ответ #11 : Август 23, 2012, 07:53 »

Вот теперь наконец-то стало ясно =).
1) Находим внешний контур и переносим эти точки в новый массив.
2) Берем самую левую верхнюю точку и если взять направление вправо то постоянно выбирать направление вправо. Как только достигнута точка с которой начали, то все эти точки переносим в новый массив.
3) Проверяем есть ли еще точки, если есть то п.2.
Как уже сказано выше найти внешний контур - геморрой порядочный. А главное 2. 3 работать не будут т.к. предложены "глядя на разноцветные контуры" - но ведь это уже результат. А посмотрите на исходную картинку - там есть "перепонка" соединяющая "синюю" и "черную" комнаты. Она останется после выделения внешнего контура.

К слову: одна точка самая левая, другая самая верхняя - какая же из них "самую левая верхняя"?  Улыбающийся
Обход как внешнего так и внутренних контуров делается по одному и тому-же алгоритму, с той ли разницей что направление для контура выбирается влево, а для комнат вправо. Это если берем самую верхнюю левую точку.
Вот по подробней:
1) Сперва находим самые левые верхнии точки, далее выбираем самую левую из них. Теперь если строго вправо 0 градусов и градусы по часовой.
2) Эта первоначальная точка имеет вектор 0, теперь из нее смотрим какие есть направления к другим точкам. Для каждого считаем вектор, поворачиваем векторы так чтоб для текущей точки он был 180 и градус между текучим вектором и возможными путями. Для контура нас интересует наименьший градус.
3) Повторяем п.2 пока не дойдем до первоначальной точки. После этого все точки что мы обошли изымаем из общего массива. В итоге те перепонки что соединяли комнаты с контуром исчезнут ибо этих точек в общем массиве нету. Остались только перепонки между комнатами.
4) Снова берем самые верхнии точки, снова самую левую из них. И для каждого действия повторяем п.2-3 с той лишь разницей что направление выбираем угол которого между векторами текущим и следующим был самый большой.
5) В итоге начальный массив опустеет, и мы будем иметь кучу новых среди которых отдельно контур и отдельно каждая комната.

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

Если до выходных не сделаешь то я могу реализовать функцию которая берет массив точек и возвращает массив массивов точек.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Август 23, 2012, 15:22 »

внешний контур находится точно также, пунктами 2-3: представь что из угла идёшь по линии (по часовой стрелке для определённости)... встретил развилку и выбрал поворот налево... так ты гарантированно пройдёшь по контуру, а не по перемычкам, автоматом обоходя их...
Во-первых технически сложно - надо помнить все развилки, каким образом? Во-вторых не вижу что обход по/против часовой работает. Первая точка находится внизу, на внешней стороне контура (ну просто здесь такие данные, вообще может быть где угодно). Первая перемычка самая левая (соединяет синюю комнату с красным внешним контуром). Да, так я могу выделить внешний контур. Но действуя таким же образом для синей комнаты (напр начав с синей верхней точки) я попаду в черную комнату.

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

А что если один раз найти все "перемычки" и запомнить их в контейнере? Как дальше раскрутить? И как найти? (надеюсь я в приличном обществе, и линейный перебор предлагаться не будет  Улыбающийся)
Записан
V1KT0P
Гость
« Ответ #13 : Август 23, 2012, 19:48 »

внешний контур находится точно также, пунктами 2-3: представь что из угла идёшь по линии (по часовой стрелке для определённости)... встретил развилку и выбрал поворот налево... так ты гарантированно пройдёшь по контуру, а не по перемычкам, автоматом обоходя их...
Во-первых технически сложно - надо помнить все развилки, каким образом? Во-вторых не вижу что обход по/против часовой работает. Первая точка находится внизу, на внешней стороне контура (ну просто здесь такие данные, вообще может быть где угодно). Первая перемычка самая левая (соединяет синюю комнату с красным внешним контуром). Да, так я могу выделить внешний контур. Но действуя таким же образом для синей комнаты (напр начав с синей верхней точки) я попаду в черную комнату.

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

А что если один раз найти все "перемычки" и запомнить их в контейнере? Как дальше раскрутить? И как найти? (надеюсь я в приличном обществе, и линейный перебор предлагаться не будет  Улыбающийся)

Да все там не так уж и сложно. В реале я бы тебе быстро на бумаге объяснил. Если тебе надо попроще то вот три варианта, но уже с ограничениями к входным данным:
1) Убираем перепонки между комнатами и контуром. В итоге в массиве будут раздельно связанные точки. Для этого надо чтоб перепонка гарантированно была не больше N, а стороны комнаты или контура гарантированно больше N. Проходим все линии и там где длина меньше N удаляем.
2) Так как глядя на картинку видно что п.1 не подходит, то чуть усложняем. Теперь сторона комнаты может быть больше N. Также проходим и все линии меньше N удаляем, при условии что обе точки имеют три связи.
3) Как по мне так самый простой, правда что-то не сразу пришел в голову =). Перебираем по очереди все линии, если у линии обе точки имеют три связи то удаляем ее. В итоге и контур и комнаты не будут связанны.

На сколько я могу судить 3-й вариант идеально подходит, до предела прост в реализации, очень эффективный и самый быстрый. Только попробуй сказать что он не подходит Смеющийся.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Август 23, 2012, 20:23 »

На сколько я могу судить 3-й вариант идеально подходит, до предела прост в реализации, очень эффективный и самый быстрый. Только попробуй сказать что он не подходит Смеющийся.
Видать на новой работе особо лазить в инете не разрешают, поэтому у Вити активность к вечеру  Улыбающийся

Ну а что такое "удалить линии"? Формально никаких линий/отрезков нет, на входе есть точки. "Перепонка" выглядит так

точка 10 (например) совпадает с  точкой 20
точка 11 совпадает с  точкой 19

Ну эти совпадения еще надо найти. И что мы собрались удалять?

Просьба: цитированием не злоупотребляйте, и так понятно о чем речь
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.06 секунд. Запросов: 22.