kxcoze

satie_lab8_8_matplotlib

Nov 16th, 2022
690
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.36 KB | None | 0 0
  1. from pprint import pprint
  2.  
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5.  
  6.  
  7. def cast_line(h, r1, r2):
  8.     # Кастим прямую с углом наклона tan(h), которая
  9.     # исходит из точки (r1, r2)
  10.     k = np.round(np.tan(h), K)
  11.     return k, -k*r1+r2
  12.  
  13.  
  14. def intersection(y1, y2):
  15.     k1, b1 = y1
  16.     k2, b2 = y2
  17.     if k1 == k2: return None
  18.  
  19.     x = np.round((b2-b1) / (k1-k2), K)
  20.     y = np.round(k1*x + b1, K)
  21.     return x, y
  22.  
  23.  
  24. def dist(x1, y1, x2, y2):
  25.     return np.round(np.sqrt((x1-x2)**2 + (y1-y2)**2), K)
  26.  
  27.  
  28. def get_all_intersections(all_lines, cur_line):
  29.     intrs = []
  30.     for line in all_lines:
  31.         p = intersection(line, cur_line)
  32.         if p: intrs.append((p, line))
  33.     return intrs
  34.  
  35.  
  36. def get_first_near_intersections(lines, cur_line, initial_point):
  37.     x0, y0 = initial_point
  38.     intrs = get_all_intersections(lines, cur_line)
  39.     min_forward = [1e9, (), ()]
  40.     min_backward = [1e9, (), ()]
  41.     for p, line in intrs:
  42.         x1, y1 = p
  43.         t = [dist(x0, y0, x1, y1), line, p]
  44.         if (x0 == x1 and y0 <= y1) or (x0 <= x1 and y0 == y1) or x0 <= x1:
  45.             min_forward = min(min_forward, t, key=lambda x: x[0])
  46.         else:
  47.             min_backward = min(min_backward, t, key=lambda x: x[0])
  48.     if not all(min_backward) or not all(min_forward):
  49.         print(f'A({x}, {y}) не находится в каком-либо многоугольнике!')
  50.         plot_graphic()
  51.         raise SystemExit(1)
  52.     return min_forward, min_backward
  53.  
  54. def plot_graphic(spec_lines=[]):
  55.     fig = plt.figure()
  56.     ax = fig.add_subplot(1, 1, 1)
  57.     ox = np.linspace(r1, r2, n)
  58.     ax.spines['left'].set_position('center')
  59.     ax.spines['bottom'].set_position('center')
  60.     ax.spines['right'].set_color('none')
  61.     ax.spines['top'].set_color('none')
  62.     ax.xaxis.set_ticks_position('bottom')
  63.     ax.yaxis.set_ticks_position('left')
  64.     plt.xlim(r1, r2)
  65.     plt.ylim(r1, r2)
  66.     plt.plot(x, y, marker='o', markersize=5, markerfacecolor='red', label=f'A({np.round(x, 2)}, {np.round(y, 2)})')
  67.     for line in lines:
  68.         k, b = line
  69.         plt.plot(ox, k*ox + b, '--g')
  70.     for line in spec_lines:
  71.         k, b = line
  72.         plt.plot(ox, k*ox + b, '-b', label=f'y={np.round(k, 2)}x + {np.round(b, 2)}')
  73.     plt.legend(loc='upper left')
  74.     plt.show()
  75.  
  76. n = 20
  77. r1, r2 = -10, 10
  78. k = (r2-r1) * np.random.sample(n) + r1
  79. b = (r2-r1) * np.random.sample(n) + r1
  80. lines = list(zip(k, b))
  81.  
  82. x, y = (r2-r1) * np.random.sample(2) + r1
  83. K = 16
  84. h = 0.01
  85. vertexes = set()
  86. main_lines = set()
  87. for i in np.arange(-np.pi/2+h, np.pi/2-h, h):
  88.     cur_line = cast_line(i, x, y)
  89.     forward_result, backward_result = get_first_near_intersections(lines, cur_line, (x, y))
  90.     for result in (forward_result, backward_result):
  91.         _, line, intr = result
  92.         forward_result2, backward_result2 = get_first_near_intersections(lines, line, intr)
  93.         for second_result in (forward_result2, backward_result2):
  94.             _, _, vertex = second_result
  95.             _x, _y = vertex
  96.             _x = np.round(_x, K//2)
  97.             _y = np.round(_y, K//2)
  98.             vertexes.add((_x, _y))
  99.             main_lines.add(line)
  100.  
  101. print(f'Вершины многоугольника, которому принадлежит начальная точка A({x}, {y})')
  102. pprint(vertexes)
  103. plot_graphic(list(main_lines))
  104.  
Advertisement
Add Comment
Please, Sign In to add comment