HICONT

Jarvis and Graham

Oct 24th, 2023 (edited)
726
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.97 KB | None | 0 0
  1. from functools import cmp_to_key
  2.  
  3. def read_file(file_path):
  4.     points = []
  5.     with open(file_path, 'r') as file:
  6.         for line in file:
  7.             coordinates = line.split(' ')
  8.             x = int(coordinates[0])
  9.             y = int(coordinates[1])
  10.             points.append(Point(x, y))
  11.     return points
  12.  
  13. class Point:
  14.     def __init__(self, x, y):
  15.         self.x = x
  16.         self.y = y
  17.  
  18.  
  19. p0 = Point(0, 0)
  20.  
  21.  
  22. # A utility function to find next to top in a stack
  23. # Возвращает значение после вершины стека
  24. def nextToTop(S):
  25.     return S[-2]
  26.  
  27.  
  28. # A utility function to return square of distance
  29. # between p1 and p2
  30. # Функция, возврящающая квадрат расстояния между p1 и p2
  31. def distSq(p1, p2):
  32.     return ((p1.x - p2.x) * (p1.x - p2.x) +
  33.             (p1.y - p2.y) * (p1.y - p2.y))
  34.  
  35. # Функция, использующаяся функцией cmp_to_key, чтобы сортировать
  36. # массив точек, относительно первой точки
  37. def compare(p1, p2):
  38.     o = orientation(p0, p1, p2)
  39.     if o == 0:
  40.         if distSq(p0, p2) >= distSq(p0, p1):
  41.             return -1
  42.         else:
  43.             return 1
  44.     else:
  45.         if o == 2:
  46.             return -1
  47.         else:
  48.             return 1
  49.  
  50. def left_index(points):
  51.     minn = 0
  52.     for i in range(1, len(points)):
  53.         if points[i].x < points[minn].x:
  54.             minn = i
  55.         elif points[i].x == points[minn].x:
  56.             if points[i].y < points[minn].y:
  57.                 minn = i
  58.     return minn
  59.  
  60. def orientation(p, q, r):
  61.     val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y)
  62.  
  63.     if val == 0:
  64.         return 0
  65.     elif val > 0:
  66.         return 1
  67.     else:
  68.         return 2
  69.  
  70. def convexHullJarvis(points, file_path):
  71.     l = left_index(points)
  72.     hull = []
  73.     prev_p = l
  74.     q = 0
  75.     n = len(points)
  76.     while (True):
  77.         hull.append(prev_p)
  78.         # Ищем точку q, такую чтобы угловой коэф между
  79.         # (prev_p, i, q) был отрицательным и наименьшим
  80.         q = (prev_p + 1) % n
  81.         for i in range(n):
  82.             if (orientation(points[prev_p],
  83.                             points[i], points[q]) == 2):
  84.                 q = i
  85.         prev_p = q
  86.         if (prev_p == l):
  87.             break
  88.     with open(file_path, 'w') as file:
  89.         for each in hull:
  90.             file.write(str(points[each].x) + ' ' + str(points[each].y) + '\n')
  91.  
  92. def convexHullGraham(points, n, file_path):
  93.     # Находим самую нижнюю точку
  94.     ymin = points[0].y
  95.     min = 0
  96.     for i in range(1, n):
  97.         y = points[i].y
  98.  
  99.         # Выбираем самую нижнюю точку либо
  100.         # самую левую, если есть несколько самых нижних точек
  101.         if ((y < ymin) or
  102.                 (ymin == y and points[i].x < points[min].x)):
  103.             ymin = points[i].y
  104.             min = i
  105.  
  106.     # Размещаем самую нижнюю точку на первую позицию
  107.     points[0], points[min] = points[min], points[0]
  108.  
  109.     # Сортируем n - 1 точек, относительно первой точки
  110.     # Точка p1 будет перед p2 если p2 имеет больший полярный угол
  111.     # (в направлении против часовой стрелки), чем p1
  112.     p0 = points[0]
  113.     points = sorted(points, key=cmp_to_key(compare))
  114.  
  115.     # Если несколько точек имеют одинаковый угол с p0,
  116.     # то удаляем все, кроме самой дальней от p0
  117.     m = 1
  118.     for i in range(1, n):
  119.  
  120.         # Продолжаем удалять i пока угол i и i + 1 такой же относительно p0
  121.         while ((i < n - 1) and
  122.                (orientation(p0, points[i], points[i + 1]) == 0)):
  123.             i += 1
  124.  
  125.         points[m] = points[i]
  126.         m += 1
  127.  
  128.     if m < 3:
  129.         return
  130.  
  131.     # Создаем пустой стек и пушим в него первые три точки
  132.     S = []
  133.     S.append(points[0])
  134.     S.append(points[1])
  135.     S.append(points[2])
  136.  
  137.     for i in range(3, m):
  138.  
  139.         # Убираем вершину стека пока угол образованный nextToTop, top и points[i]
  140.         # Совершает не левый поворот
  141.         while ((len(S) > 1) and
  142.                (orientation(nextToTop(S), S[-1], points[i]) != 2)):
  143.             S.pop()
  144.         S.append(points[i])
  145.  
  146.     with open(file_path, 'w') as file:
  147.         while S:
  148.             p = S[-1]
  149.             file.write("(" + str(p.x) + ", " + str(p.y) + ")" + '\n')
  150.             S.pop()
  151.  
  152. points_n = read_file('ConvexHullTask.txt')
  153.  
  154. #convexHullJarvis(points_n, 'ConvexHullRes.txt')
  155.  
  156. points = read_file('ConvexHullTask.txt')
  157. n = len(points)
  158. convexHullGraham(points, n, 'ConvexHullRes.txt')
Advertisement
Add Comment
Please, Sign In to add comment