Advertisement
fevzi02

Тимур 4лаба

Jan 17th, 2022
4,138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.57 KB | None | 0 0
  1. import pygame, sys, math
  2. import numpy as np
  3. import random
  4.  
  5. class Main:
  6.     def __init__(self, fps=60):
  7.         self.fps = fps
  8.         pygame.init()
  9.         self.screen = pygame.display.set_mode((1080,720))
  10.         self.clock = pygame.time.Clock()
  11.         self.display_width, self.display_height = pygame.display.Info().current_w, pygame.display.Info().current_h
  12.         while True:
  13.  
  14.             self.set_points()
  15.  
  16.     def set_points(self):
  17.         self.coordinates = []
  18.         self.coordinatesNEW = []
  19.         self.pos = (-5,-5)
  20.  
  21.         self.bool_start = 0
  22.         self.bool_pos = 0
  23.  
  24.         while True:
  25.             self.screen.fill("white")
  26.             if len(self.coordinates) > 1:
  27.                 for i in range(len(self.coordinates)):
  28.                     pygame.draw.aalines(self.screen, "black", True, self.coordinates)
  29.             else:
  30.                 self.screen.fill("black", (self.pos, (3, 3)))
  31.  
  32.             for event in pygame.event.get():
  33.                 if event.type == pygame.QUIT:
  34.                     pygame.quit()
  35.                     sys.exit()
  36.                 if event.type == pygame.KEYDOWN :
  37.                     if event.key == pygame.K_ESCAPE:
  38.                         pygame.quit()
  39.                         sys.exit()
  40.                     elif event.key == pygame.K_q:
  41.                         if len(self.coordinates) > 2:
  42.                             self.bool_start = 1
  43.                             self.start()
  44.                             pygame.display.set_caption("Задание точек завершено")
  45.                         else:
  46.                             pygame.display.set_caption("Нужно задать как минимум 3 точки!")
  47.                     elif event.key == pygame.K_w:
  48.                         self.bool_start = 0
  49.                         self.coordinates = []
  50.                         self.coordinatesNEW = []
  51.                         self.pos = (-5, -5)
  52.                         pygame.display.set_caption("Точки сброшены!")
  53.                 if event.type == pygame.MOUSEBUTTONDOWN :
  54.                     self.pos = event.pos
  55.                     self.bool_pos = 1
  56.                     if not self.bool_start:
  57.                         self.coordinates.append(self.pos)
  58.                         pygame.display.set_caption(str(self.pos) + ".  Для начала триангуляции нажмите на - q")
  59.             if self.bool_start == 1:
  60.                 break
  61.  
  62.             pygame.display.flip()
  63.             self.clock.tick(self.fps)
  64.  
  65.     def start(self):
  66.         self.pos = (0, 0)
  67.         self.bool_pos = 0
  68.  
  69.         self.screen.fill("white")
  70.         self.print_polygon(self.coordinates)
  71.  
  72.         if len(self.coordinates) > 0:
  73.             for coords in self.coordinates:
  74.                 self.coordinatesNEW.append(coords)
  75.         while True:
  76.             self.triangles = []
  77.             if not self.is_clockwise():
  78.                 self.coordinates.reverse()
  79.             if_done = self.triangulate()
  80.             if if_done:
  81.                 pygame.display.set_caption("Триангуляция прошла успешно.    Сброс точек - w")
  82.                 self.coordinates = []
  83.                 if len(self.coordinatesNEW) > 0:
  84.                     for coords in self.coordinatesNEW:
  85.                         self.coordinates.append(coords)
  86.  
  87.                 hasPointOfPolygonMouse = self.hasPointOfPolygonMouse()
  88.                 if hasPointOfPolygonMouse[0] and self.bool_pos:
  89.                     pygame.draw.polygon(self.screen, (random.randint(0, 256)%256,random.randint(0, 256)%256, random.randint(0, 256)%256), hasPointOfPolygonMouse[1])
  90.                 self.bool_pos = 0
  91.             else:
  92.                 self.bool_start = 0
  93.                 self.coordinates = []
  94.                 self.coordinatesNEW = []
  95.                 self.pos = (-5, -5)
  96.                 pygame.display.set_caption("Произошла ошибка точки сброшены")
  97.                 self.set_points()
  98.             #обработчик событий
  99.             for event in pygame.event.get():
  100.                 if event.type == pygame.QUIT:
  101.                     for tr in self.triangles:
  102.                         print(tr)
  103.                     pygame.quit()
  104.                     sys.exit()
  105.                 if event.type == pygame.KEYDOWN :
  106.                     if event.key == pygame.K_ESCAPE:
  107.                         for tr in self.triangles:
  108.                             print(tr)
  109.                         pygame.quit()
  110.                         sys.exit()
  111.                     elif event.key == pygame.K_w:
  112.                         self.bool_start = 0
  113.                         self.coordinates = []
  114.                         self.coordinatesNEW = []
  115.                         self.pos = (-5, -5)
  116.                         pygame.display.set_caption("Точки сброшены!")
  117.                         self.set_points()
  118.  
  119.                 if event.type == pygame.MOUSEBUTTONDOWN :
  120.                     self.pos = event.pos
  121.                     self.bool_pos = 1
  122.             pygame.display.flip()
  123.             self.clock.tick(self.fps)
  124.  
  125.     def is_clockwise(self):
  126.         assert len(self.coordinates) > 0
  127.         s = 0.0
  128.         for p1, p2 in zip(self.coordinates, self.coordinates[1:] + [self.coordinates[0]]):
  129.             s += (p2[0] - p1[0]) * (p2[1] + p1[1])
  130.         return s > 0.0
  131.  
  132.     def print_polygon(self, coordinates):
  133.         pygame.draw.aalines(self.screen, "black", True, coordinates)
  134.  
  135.     # 2 Левая тройка векторов?
  136.     def isLeft(self, i):
  137.         A = self.coordinates[i%len(self.coordinates)]
  138.         B = self.coordinates[(i+1)%len(self.coordinates)]
  139.         C = self.coordinates[(i+2)%len(self.coordinates)]
  140.  
  141.         AB = {"x": B[0] - A[0], "y": B[1] - A[1]}
  142.         AC = {"x": C[0] - A[0], "y": C[1] - A[1]}
  143.  
  144.         return AB["x"] * AC["y"] - AC["x"] * AB["y"] < 0
  145.  
  146.     def hasPointOfPolygonMouse(self):
  147.         for triangle in self.triangles:
  148.             A = triangle[0]
  149.             B = triangle[1]
  150.             C = triangle[2]
  151.             for j in range(0, len(self.coordinates)):
  152.                 VP0  = self.cross(A, B, self.pos)
  153.                 VP1  = self.cross(B, C, self.pos)
  154.                 VP2  = self.cross(C, A, self.pos)
  155.                 s_l = np.sign([VP0, VP1, VP2])
  156.  
  157.                 if s_l[0] == s_l[1] and s_l[1] == s_l[2] and s_l[0] == s_l[2]:
  158.                      return (True, triangle)
  159.  
  160.                 for h in range(len(s_l)):
  161.                     if s_l[h] == 0:
  162.                         if s_l[(h+1)%len(s_l)] == s_l[(h+2)%len(s_l)]:
  163.                             return (True, triangle)
  164.         return (False, (None, None))
  165.  
  166.     def cross(self, P1, P2, P): #ABxAP, BCxBP and CAxCP.
  167.         vector_P1_P2 = (P2[0]-P1[0], P2[1]-P1[1])
  168.         vector_P1_P = (P[0]-P1[0], P[1]-P1[1])
  169.  
  170.         return np.cross(vector_P1_P2, vector_P1_P)
  171.  
  172.     # 3 Есть ли другие точки внутри рассматриваемого треугольника?
  173.     def hasPointOfPolygon(self, i):
  174.         A = self.coordinates[i%len(self.coordinates)]
  175.         B = self.coordinates[(i+1)%len(self.coordinates)]
  176.         C = self.coordinates[(i+2)%len(self.coordinates)]
  177.  
  178.         for j in range((i+3)%len(self.coordinates), len(self.coordinates)+i%len(self.coordinates)):
  179.             VP0  = self.cross(A, B, self.coordinates[j%len(self.coordinates)])
  180.             VP1  = self.cross(B, C, self.coordinates[j%len(self.coordinates)])
  181.             VP2  = self.cross(C, A, self.coordinates[j%len(self.coordinates)])
  182.             s_l = np.sign([VP0, VP1, VP2])
  183.  
  184.             if s_l[0] == s_l[1] and s_l[1] == s_l[2] and s_l[0] == s_l[2]:
  185.                  return False
  186.  
  187.             for h in range(len(s_l)):
  188.                 if s_l[h] == 0:
  189.                     if s_l[(h+1)%len(s_l)] == s_l[(h+2)%len(s_l)]:
  190.                         return False
  191.         return True
  192.  
  193.     #Триангуляция
  194.     def triangulate(self):
  195.         i = 0
  196.         crt = 0
  197.         while len(self.coordinates) >= 3:
  198.             crt += 1
  199.             if self.isLeft(i) and self.hasPointOfPolygon(i):
  200.                 self.triangles.append([self.coordinates[(i)%len(self.coordinates)], self.coordinates[(i+1)%len(self.coordinates)], self.coordinates[(i+2)%len(self.coordinates)]])
  201.                 if len(self.coordinates) == 3:
  202.                     break
  203.                 del self.coordinates[(i+1)%len(self.coordinates)]
  204.             else:
  205.                 i += 1
  206.                 i = i%len(self.coordinates)
  207.             if crt == len(self.coordinates) ** 2:
  208.                 return 0
  209.         return 1
  210.  
  211. Main(24)
  212.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement