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

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

31.05.2021, 09:30. Показов 2697. Ответов 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
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru