Форум программистов, компьютерный форум, киберфорум
Python: Научные вычисления
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 31.05.2021
Сообщений: 1

Соединить все точки выпуклой оболочки. Вычислительная геометрия

31.05.2021, 09:30. Показов 2730. Ответов 0

Студворк — интернет-сервис помощи студентам
Приветствую всех! У меня есть задача, звучащая следующим образом: дано конечное множество точек на плоскости. Необходимо упорядочить точки в таком порядке,чтобы при движении от первой точки к последней все повороты были НАЛЕВО.

Что нужно сделать фактически: с помощью алгоритма Грэхема построить выпуклую оболочку. Однако, когда график возвращается в точку начала, необходимо удалить эту связь (или не рисовать вовсе, не знаю), и от предпоследней точки оболочки соединять все точки внутри выпуклой оболочки, поворачивая только налево. Т.е. должно получить как на рисунке:

У меня уже есть код реализации самого алгоритма Грэхема. Нужно как-то проебразовать его, чтобы он делал то, что нужно.
Привожу код:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from matplotlib import pyplot as plt # библиотека для графиков
from random import randint # для сортировки и создания точек данных
from math import atan2 # для вычисления полярного угла
 
# Возвращаем список (x, y) координат длины 'num_points',
# каждая координата x и y выбирается случайным образом из диапазона
# от 'min' до 'max'. 
def create_points(ct,min=0,max=25):
    return [[randint(min,max),randint(min,max)] \
                    for _ in range(ct)]
 
# Создает диаграмму рассеяния, ввод - это список координат (x, y).
# Второй вход 'convx_hull' - это еще один список координат (x, y),
# состоящий из тех точек в координатах, которые составляют выпуклую оболочку,
# если не None, элементы этого списка будут использоваться для рисования внешнего
# граница (выпуклая оболочка, окружающая точки данных)
def scatter_plot(coords,convex_hull=None):
    xs,ys=zip(*coords) # распаковать в списки координат x и y 
    plt.scatter(xs,ys) # построить точки данных 
 
    if convex_hull!=None:
        # построить границу выпуклой оболочки, дополнительная итерация на
        # конец так, чтобы ограничивающая линия обтекала 
        for i in range(1,len(convex_hull)+1):
            if i==len(convex_hull): i=0 # обертка
            c0=convex_hull[i-1]
            c1=convex_hull[i]
            plt.plot((c0[0],c1[0]),(c0[1],c1[1]),'r')
    plt.show()
scatter_plot(create_points(10))
 
# Возвращает полярный угол (радианы) от p0 до p1.
# Если p1 равен None, по умолчанию он заменяется на
# глобальная переменная anchor, обычно устанавливается в
# функция 'graham_scan'.
def polar_angle(p0,p1=None):
    if p1==None: p1=anchor
    y_span=p0[1]-p1[1]
    x_span=p0[0]-p1[0]
    return atan2(y_span,x_span)
 
# Возвращает евклидово расстояние от p0 до p1,
# квадратный корень не применяется ради скорости.
# Если p1 равен None, по умолчанию он заменяется на
# глобальная переменная anchor, обычно устанавливается в
# функция 'graham_scan'.
def distance(p0,p1=None):
    if p1==None: p1=anchor
    y_span=p0[1]-p1[1]
    x_span=p0[0]-p1[0]
    return y_span**2 + x_span**2
 
# Возвращает определитель матрицы 3x3 ...
# [p1 (x) p1 (y) 1]
# [p2 (x) p2 (y) 1]
# [p3 (x) p3 (y) 1]
# Если> 0, то против часовой стрелки
# Если <0, то по часовой стрелке
# Если = 0, то коллинеарно 
def det(p1,p2,p3):
    return   (p2[0]-p1[0])*(p3[1]-p1[1]) \
            -(p2[1]-p1[1])*(p3[0]-p1[0])
 
# Сортировка по возрастанию полярного угла от точки привязки.
# Предполагается, что переменная 'anchor' является глобальной, устанавливается внутри 'graham_scan'.
# Для любых значений с равными полярными углами применяется вторая сортировка.
# обеспечить увеличение расстояния от точки «якоря». 
def quicksort(a):
    if len(a)<=1: return a
    smaller,equal,larger=[],[],[]
    piv_ang=polar_angle(a[randint(0,len(a)-1)]) # выбрать случайную точку поворота
    for pt in a:
        pt_ang=polar_angle(pt) # вычислить текущий угол точки
        if   pt_ang<piv_ang:  smaller.append(pt)
        elif pt_ang==piv_ang: equal.append(pt)
        else:        larger.append(pt)
    return   quicksort(smaller) \
            +sorted(equal,key=distance) \
            +quicksort(larger)
 
# Возвращает вершины, составляющие границы
# выпуклой оболочки, содержащие все точки входного множества.
# Входные "точки" - это список координат (x, y).
# Если 'show_progress' установлен в True, прогресс в
# Построение корпуса будет строиться на каждой итерации. 
def graham_scan(points,show_progress=True):
    global anchor # устанавливается, (x, y) с наименьшим значением y 
    
# Найдите точку (x, y) с наименьшим значением y,
# вместе с его индексом в списке "точек". Если
# есть несколько точек с одинаковым значением y,
# выбираем тот, у которого наименьший x. 
    min_idx=None
    for i,(x,y) in enumerate(points):
        if min_idx==None or y<points[min_idx][1]:
            min_idx=i
        if y==points[min_idx][1] and x<points[min_idx][0]:
            min_idx=i
# установить глобальную переменную 'anchor', используемую
# функции 'polar_angle' и 'distance' 
    anchor=points[min_idx]
# сортируем точки по полярному углу, затем удаляем
# якорь из отсортированного списка 
    sorted_pts=quicksort(points)
    del sorted_pts[sorted_pts.index(anchor)]
    
    # якорь и точка с наименьшим полярным углом всегда будут на корпусе 
    hull=[anchor,sorted_pts[0]]
    for s in sorted_pts[1:]:
            while det(hull[-2],hull[-1],s)<=0:
                del hull[-1] # возврат 
                #if len (hull) <2: break 
            hull.append(s)
            if show_progress: scatter_plot(points,hull)
    return hull
 
pts = create_points(10)
print ("Points:", pts)
hull = graham_scan(pts, True)
print ("Hull:", hull)
scatter_plot(pts, hull)
Был бы крайне признателен, если бы вы помогли кодом. Заранее благодарю за внимание!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.05.2021, 09:30
Ответы с готовыми решениями:

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

Вычислительная геометрия: определить взаимное расположении точки и прямой
Определить взаимное расположении точки и прямой: лежит выше прямой, на прямой, под прямой.

построение выпуклой оболочки
необходимо построить выпуклую оболочку методом грэхема

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.05.2021, 09:30
Помогаю со студенческими работами здесь

Нахождение выпуклой оболочки
Помогите пожалуйста с решением, Выпуклая оболочка множества точек на плоскости состоит из тех точек множества, через которые можно...

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

Построения выпуклой оболочки
Нужно написать код для алгоритма QuickHull и Грэхема Помогите !

Нахождение выпуклой оболочки (3D)
Здравствуйте, может на этом форуме кто-нибудь сможет помочь. Мне завтра надо сдавать лабораторную, а с ней возникла проблема.... Буду очень...

Алгоритм минимальной выпуклой оболочки
Нужна реализация алгоритма минимальной выпуклой оболочки Желательно самого простого что бы била одно функция помогите с кодом


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru