Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Самопересикающиеся полигон, оптимизация 
:(
    Опции темы
FataList
Дата 18.7.2006, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



 День добрый!

Это самопересикающийся полигон.

************************
*                                            *
*                         *****         *  
*                         *      *         *
*                         *      **** **  
*    *******       *      *         *
*    *          *       *      *         *
*    *          *       *      *         *
*    *          *************** 
*    *          *       *      *         * 
*    *          *       *      *         * 
*    *******       *      *         *
*                         *****         *
*                                            *
************************

Как найти красную точку с минимум затрат?
Есть вариант, когда все ребра (от вершины 1 до вершмны 2  и т.д.) сравнивать друг с другом и тем самым находить эту точку, но получается 
0(n*n).  А это плохо! Нужно быстрее. Какие будут мысли?
 
PM MAIL   Вверх
Earnest
Дата 19.7.2006, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Используй метод сканирующей линии. Он дает (кажется) O(n*log n). Быстрее, по-моему, не получится.
Метод сканирующей линии вкратце: все ребра сортируем, скажем по x, слева направо. Начальные и конечные х-координаты ребер составляют список точек-событий. Вертикальная сканирующая линия переходит от одного события к другому, слева направо. В каждый момент времени рассматриваются только те ребра, которые пересекают сканирующую линию. Причем эти ребра (называемые активными) сортируются по y-координате пересечения сканирующей линии. Так что нужно проверять пересечения только соседних в списке ребер. Хорошее и подробное описание этого алгоритма можно найти в книге Ласло "Вычислительная геометрия и компьютерная графика на С++". 
Но следует иметь в виду, что реализация алгоритма значительно сложнее, чем квадратичная проверка пересечений всех ребер, а за счет сортировок и подготовительной работы выгрыш будет только при большом числе ребер. Я думаю, от сотни. Если ребер 2 десятка, проще попарно сравнить.

Добавлено @ 09:54 
Если полигон именно такой, как на рисунке, т.е. состоит только из вертикальных и горизонтальных линий, думаю процесс можно существенно упростить и ускорить. 


--------------------
...
PM   Вверх
FataList
Дата 21.7.2006, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо!
Просто нужно определить эту точку, которая принадлежит обоим  отрезкам (сторонам). На первый взгляд это легко, но когда копнешь глубже...
           
            A'
             *
             *
             *
             *
 A************B
             *
             * 
             *
             *
           B'

Получется куча условий и они работают по отдельности.

Код

           if ( ( ( ((x1 <= x0) && (x0 <= x2)) || ((x1 >= x0) && (x0 >= x2)) ) &&
                    ((y1 < y0) && (y0 < y2)) &&                             
                    ((x3 > x0) && (x0 > x4)) &&
                  ( ((y3 >= y0) && (y0 >= y4)) || ((y3 <= y0) && (y0 <= y4)) ) ) ||
                ( ( ((x1 <= x0) && (x0 <= x2)) || ((x1 >= x0) && (x0 >= x2)) ) &&
                    ((y1 < y0) && (y0 < y2)) &&                              
                    ((x3 < x0) && (x0 < x4)) &&
                  ( ((y3 >= y0) && (y0 >= y4)) || ((y3 <= y0) && (y0 <= y4)) ) ) )
             Decomposition_Segment++;
                        
           if ( ( ( ((x1 <= x0) && (x0 <= x2)) || ((x1 >= x0) && (x0 >= x2)) ) &&
                    ((y1 > y0) && (y0 > y2)) &&                             
                    ((x3 > x0) && (x0 > x4)) &&
                  ( ((y3 >= y0) && (y0 >= y4)) || ((y3 <= y0) && (y0 <= y4)) ) ) ||
                ( ( ((x1 <= x0) && (x0 <= x2)) || ((x1 >= x0) && (x0 >= x2)) ) &&
                    ((y1 > y0) && (y0 > y2)) &&                              
                    ((x3 < x0) && (x0 < x4)) &&
                  ( ((y3 >= y0) && (y0 >= y4)) || ((y3 <= y0) && (y0 <= y4)) ) ) )
             Decomposition_Segment++;
 


Это 1 / 4 от всех условий. 
Первое, это когда рассматривается отрезок (сторона) A'B' и (AB или BA)
А второе -  B'A' и (AB или BA). 
И так с каджой стороны (учитываются и то, что под любым углом пересекаются прямые).

Видимо надо от этого отказаться, или нацти альтернативу. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

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


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

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


 




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


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

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