Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Построение контура облака точек 
:(
    Опции темы
Dementor
Дата 30.7.2013, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Всем доброго времени суток!

Столкнулся с необходимостью получить контур облака точек. 

Сначала обратился в сторону выпуклых оболочек. Информации по ним много, но лично я использовал вот этот вариант http://e-maxx.ru/algo/convex_hull_graham. В общем то вопросов по этому варианту нет никаких, но я понял, что он мне не подходит.

Дело в том, что мне необходимо зафиксировать "неровности" контура, а выпуклая оболочка как раз их и скрывает.

Таким образом мне необходимо построить контур с заданной точностью, т.е. если между двумя внешними точками расстояние больше заданного, то в качестве очередной вершины будет добавлена точка облака, которая находится между внешними. Тупо наверно объяснил, поэтому приведу на рисунках:
user posted imageuser posted image

Прошу наставить на путь истинный и подсказать в какую сторону капать. Я думаю, что немного усложнив имеющийся алгоритм можно достичь желаемого, но как это сделать я никак не могу придумать.
PM MAIL   Вверх
Pavia
Дата 31.7.2013, 05:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: 11
Всего: 12



Добавь ограничение по длине. Если точка дальше порога, то она не участвует в сортировке.
PM MAIL   Вверх
Earnest
Дата 31.7.2013, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 7
Всего: 183



Да, сначала строишь выпуклую оболочку, затем проверяешь длину ребер, берешь самое длинное (если оно больше порога), начинаешь заворачивать его вовнутрь пока не нарвешься на точку. И т.д.
Еще один способ - построить триангуляцию, удалить внешние треугольники со слишком длинным ребром, затем построить внешний контур.


--------------------
...
PM   Вверх
_Y_
Дата 31.7.2013, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Если точек не смертелъно много, можно (ИМХО):
Соединит' всe точки со всеми.
Убрат' соединения длиннее, чем заданное ограничение по длине. 
Получится требуемая форма, но у неe могут быт' неприятности вроде таких
user posted image
После исключения серой линии, появляются 2 варианта решения - красные линии (внутренние соединения не показаны).
Надо ввести критерий выбора из такого рода вариантов. Например, наимен'шая площад' "впуклости" или наименшая суммарная длина или еще что.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Dementor
Дата 31.7.2013, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Цитата(_Y_ @  31.7.2013,  12:57 Найти цитируемый пост)
Если точек не смертелъно много, можно (ИМХО):Соединит' всe точки со всеми.Убрат' соединения длиннее, чем заданное ограничение по длине. 

Над таким вариантом я думал, и еще пару лет назад он был бы приемлем, но не сейчас. Количество точек может быть и в пределах пары сотен и в пределах десятков и сотен тысяч, а в крайних случаях и миллионы.

Я пытаюсь сделать ограничение по длине ребра, как предлагалось выше, но никак не могу понять в какую часть кода эту проверку внедрять - как ни пытался не получается ничего.
PM MAIL   Вверх
_Y_
Дата 31.7.2013, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



[Б]Дементор[/Б], тогда тоже можно соединят' каждую точку с каждой, но, при этом в массив добавлят' тол'ко те, которые мен'ше выбранного ограничения длины. Если точки не очен' плотно расположены, то их бол'шое число не будет критично.

Можно еще так- некий оптимизированный вариант алгоритма:
Нарисоват' описывающий контур.
Убрат' слишком длинные соединения.
Соединит' не все-со-всеми, а тол'ко точки контура, у которых были убраны слишком длинные соединения, со всеми, лежащими в пределах ограничения.
Если замкнутого контура не найдено - растит' деревя от следующих точек, пока нe получится замкнутый контур.
Получится то, о чем а писал выше, но ненужных внутренних соединений будет гораздо мен'ше.

Понятно я написал или мысли выражены путано-туманно? smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
mrgloom
Дата 31.7.2013, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



http://en.wikipedia.org/wiki/Ramer%E2%80%9...ucker_algorithm

можно построить контур минимальный по площади вокруг облака точек, а потом по алгоритму упростить(если надо)
PM MAIL   Вверх
_Y_
Дата 31.7.2013, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



mrgloom, что-то я не понял. Ramer–Douglas–Peucker algorithm умен'шает испол'зуемое количество точек, а задача, наоборот, добавит'.  Может стоит обяснит' идею для недогадливых? smile 

Это сообщение отредактировал(а) _Y_ - 31.7.2013, 15:09


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Dementor
Дата 31.7.2013, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Я если не ошибаюсь, но алгоритм Дугласа-Пекера используется для сглаживания... хотя могу и ошибаться, но его применение я встречал только для сглаживания контуров.
PM MAIL   Вверх
mrgloom
Дата 31.7.2013, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



сначала строим максимально приближенный к форме контур который прилегает в "облипку" и имеет много точек, а потом его и начинаем упрощать, можно еще потребовать, чтобы оболочка была выпуклой. 


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

Это сообщение отредактировал(а) mrgloom - 31.7.2013, 15:30
PM MAIL   Вверх
Dementor
Дата 31.7.2013, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Цитата(mrgloom @  31.7.2013,  15:27 Найти цитируемый пост)
сначала строим максимально приближенный к форме контур который прилегает в "облипку"

Фактически мне и надо построить именно такой контур, чтобы он облеплял облако точек. А упрощать его как раз и можно будет алгоритмом Дугласа-Пекера.

PM MAIL   Вверх
_Y_
Дата 31.7.2013, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Dementor, eсли вернут'ся к моему рисунку. Каков будет критерий выбора из двух внутренних точек, если любая из них удовлетворяет условию о непревышении длины соединений?


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Dementor
Дата 31.7.2013, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Цитата(_Y_ @ 31.7.2013,  16:54)
Dementor, eсли вернут'ся к моему рисунку. Каков будет критерий выбора из двух внутренних точек, если любая из них удовлетворяет условию о непревышении длины соединений?

На самом деле для моей задачи без разницы.
Могу пояснить саму суть: предположим есть два облака точек, которые покрывают одну и ту же область. Надо выбрать лишь одно облако, которое покрывает заданную область наиболее хорошо, при этом стоит учитывать, что количество точек в облаке не имеет прямого влияния на качество покрытия, т.к. ясно, что 100 точек из одного облака могут покрыть область лучше 1000 точек из другого. При этом заведомо известно, что форма области, которую покрывают облака стремится либо к прямоугольнику, либо к трапеции. Таким образом, если получившийся контур облака имеет вогнутые внутрь участки, то условие покрытия не выполняется.
PM MAIL   Вверх
_Y_
Дата 31.7.2013, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Цитата(Dementor @  31.7.2013,  17:04 Найти цитируемый пост)
При этом заведомо известно, что форма области, которую покрывают облака стремится либо к прямоугольнику, либо к трапеции. Таким образом, если получившийся контур облака имеет вогнутые внутрь участки, то условие покрытия не выполняется.

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


Это сообщение отредактировал(а) _Y_ - 31.7.2013, 19:25


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Dementor
Дата 31.7.2013, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 9.7.2007

Репутация: нет
Всего: нет



Цитата(_Y_ @  31.7.2013,  19:24 Найти цитируемый пост)
Так мы, наверное, отвечаем не на тот вопрос. Тогда надо просто строить описывающий точки прямоугольник, после чего выбирать какие его две строны будут соответствовать параллельным сторонам трапеции и постепенно менять наклон двух дугих сторон с тем, чтобы оптимизировать-уменьшить размер получающейся трапеции.


Вообще я методом тыка пришел может к неправильному, но пока вполне работающему варианту: я поменял условия сортировки при построении выпуклой оболочки (оригинал был в первом посте в виде ссылки):
Код

      for (int i=1; i!=FL.Count(); i++)
      {
        if (i==FL.Ns()-1 || !cw (p1, FL[i], p2))
        {
          while (up.size()>=2 && cw (up[up.size()-2], up[up.size()-1], FL[i])) up.pop_back();
          up.push_back (FL[i]);
        }

        if (i==FL.Ns()-1 || !ccw (p1, FL[i], p2))
        {
          while (down.size()>=2 && ccw (down[down.size()-2], down[down.size()-1], FL[i])) down.pop_back();
          down.push_back (FL[i]);
        }
      }

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

Но над вашим вариантом решения я буду еще думать - посмотрю что получится.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0708 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.