Advertisement
trishLEX

Lab5

Apr 21st, 2017
388
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.60 KB | None | 0 0
  1. import glfw
  2. from OpenGL.GL import *
  3. from math import atan
  4. from math import pi
  5.  
  6. class Vertex:
  7.     def __init__(self, point):
  8.         self.coords = point
  9.         #self.isHole = isHole
  10.         self.isIntersectionPoint = False
  11.         self.isEntry = False
  12.  
  13.     def __len__(self):
  14.         return 1
  15.  
  16.  
  17. class Polygon:
  18.     isSbjReady = False
  19.     isHolesReady = False
  20.     listOfEntries = []
  21.     listOfExits = []
  22.     def __init__(self):
  23.         self.points = []
  24.         self.sizes = []
  25.         self.size = 0
  26.     def insert(self, x, i):
  27.         for j in x:
  28.             self.points[i].append(j)
  29.         self.sizes[i] += len(x)
  30.     def append(self, x):
  31.         self.points.append(x)
  32.         self.sizes.append(len(x))
  33.         self.size += 1
  34.     def isEmpty(self):
  35.         if self.size == 0 and self.points == [] and self.sizes == []:
  36.             return True
  37.         else:
  38.             return False
  39.  
  40. class Clip:
  41.     isClipReady = False
  42.     def __init__(self):
  43.         self.points = []
  44.         self.size = 0
  45.     def append(self, x):
  46.         self.points.append(x)
  47.         self.size += 1
  48.  
  49.     def isEmpty(self):
  50.         if self.size:
  51.             return False
  52.         else:
  53.             return True
  54.  
  55. class IntersectionShapes:
  56.     isIntersectionMade = False
  57.     def __init__(self):
  58.         self.points = []
  59.         self.sizes = []
  60.         self.size = 0
  61.     def insert(self, x, i):
  62.         for j in x:
  63.             self.points[i].append(j)
  64.         self.sizes[i] += len(x)
  65.     def append(self, x):
  66.         self.points.append(x)
  67.         self.sizes.append(len(x))
  68.         self.size += 1
  69.     def isEmpty(self):
  70.         if self.size == 0 and self.points == [] and self.sizes == []:
  71.             return True
  72.         else:
  73.             return False
  74.  
  75.  
  76.  
  77. global startPoint
  78. startPoint = False
  79. def mouseCallback(window, button, action, mods):
  80.     global startPoint
  81.     if button == glfw.MOUSE_BUTTON_1 and action:
  82.         mouse = glfw.get_cursor_pos(window)
  83.         mouse = [int(mouse[0]), 480 - int(mouse[1])]
  84.         p = Vertex(mouse)
  85.         if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  86.             if polygon.isEmpty():
  87.                 if not startPoint:
  88.                     startPoint = True
  89.                     polygon.append([p])
  90.             else:
  91.                 polygon.insert([p], 0)
  92.         #print("isSbjReady", polygon.isSbjReady, "isHolesReady", polygon.isHolesReady, "isClipReady", clip.isClipReady)
  93.         #print(polygon.size)
  94.         if polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  95.             if not startPoint:
  96.                 startPoint = True
  97.                 polygon.append([p])
  98.             else:
  99.                 polygon.insert([p], polygon.size - 1)
  100.         if polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
  101.             clip.append(p)
  102.         #print(polygon.size)
  103.         #print(polygon.sizes)
  104.         # for i in range(polygon.size):
  105.         #     for j in range(polygon.sizes[i]):
  106.         #         print(polygon.points[i][j].coords)
  107.  
  108.  
  109. def keyCallback(window, key, scancode, action, mods):
  110.     #global isCurrentHoleReady
  111.     global startPoint
  112.     if key == glfw.KEY_SPACE and action:
  113.         if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  114.             startPoint = False
  115.             polygon.isSbjReady = True
  116.             print("PRESS SPACE TO SKIP DRAWING HOLES")
  117.         elif polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  118.             #isCurrentHoleReady = True
  119.             startPoint = False
  120.             polygon.isHolesReady = True
  121.         elif polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
  122.             #startPoint = False
  123.             clip.isClipReady = True
  124.     if key == glfw.KEY_H and action:
  125.         polygon.isHolesReady = False
  126.     if key == glfw.KEY_ENTER and action:
  127.         makeIntersection()
  128.  
  129.  
  130. def makeIntersection():
  131.     searchForIntersections()
  132.  
  133.  
  134. def searchForIntersections():
  135.     newSbjPoints = []
  136.     newClipPoints = []
  137.  
  138.     newSbjSizes = []
  139.     newSbjSize = 0
  140.     newClipSize = 0
  141.  
  142.     for i in range(polygon.size):
  143.         points = []
  144.         size = 0
  145.         for k in range(polygon.sizes[i]):
  146.             points.append(polygon.points[i][k])
  147.             size += 1
  148.             intersectionPoints = []
  149.             intersectionPointsCount = 0
  150.             for j in range(clip.size):
  151.                 if clip.points[j] not in newClipPoints:
  152.                     newClipPoints.append(clip.points[j])
  153.                     newClipSize += 1
  154.                 I = intersectionFound([polygon.points[i][k].coords, polygon.points[i][(k + 1) % polygon.sizes[i]].coords], [clip.points[j].coords, clip.points[(j + 1) % clip.size].coords])
  155.                 if I:
  156.                     intersectionPointsCount += 1
  157.                     p = Vertex(I)
  158.                     p.isIntersectionPoint = True
  159.                     intersectionPoints.append(p)
  160.                     intersectionPointsCount += 1
  161.                     newClipPoints.append(p)
  162.                     newClipSize += 1
  163.             intersectionPoints = makeOrder(intersectionPoints, polygon.points[i][k], polygon.points[i][(k + 1) % polygon.sizes[i]])
  164.             if intersectionPoints != []:
  165.                 for l in intersectionPoints:
  166.                     points.append(l)
  167.                     size += 1
  168.         newSbjPoints.append(points)
  169.         newSbjSize += 1
  170.         newSbjSizes.append(size)
  171.  
  172.     polygon.points = newSbjPoints
  173.     polygon.sizes = newSbjSizes
  174.     polygon.size = newSbjSize
  175.  
  176.     #print(polygon.sizes)
  177.  
  178.     global center
  179.     center = findCenterOfMass(newClipPoints)
  180.     newClipPoints.sort(key=sort, reverse=True)
  181.  
  182.     clip.points = newClipPoints
  183.     clip.size = newClipSize
  184.  
  185.     #for i in polygon.points[0]:
  186.     #    print(i.coords)
  187.  
  188. def findCenterOfMass(points):
  189.     m = n = 0
  190.     count = 0
  191.     for i in points:
  192.         m += i.coords[0]
  193.         n += i.coords[1]
  194.         count += 1
  195.     return [m / count, n / count]
  196.  
  197. def sort(p):
  198.     point = [p.coords[0] - center[0], p.coords[1] - center[1]]
  199.     phi = atan(point[1] / point[0])
  200.     if point[0] < 0 and point[1] > 0 or point[0] < 0 and point[1] < 0:
  201.         phi += pi
  202.     if point[0] > 0 and point[1] < 0:
  203.         phi += 2 * pi
  204.     return phi
  205.  
  206.  
  207. def intersectionFound(edge1, edge2):
  208.     if checkForBelonging(edge1[0], edge2) or checkForBelonging(edge1[1], edge2) or checkForBelonging(edge2[0], edge1) or checkForBelonging(edge2[1], edge1):
  209.         #print("I'm here")
  210.         return False
  211.     #print("edge1 =", edge1, "edge2 =", edge2)
  212.     A = edge1[0]
  213.     C = edge2[0]
  214.     #print("A =", A, "C =", C)
  215.     c = [C[0] - A[0], C[1] - A[1]]
  216.     #print("c =", c)
  217.     b = [edge1[1][0] - edge1[0][0], edge1[1][1] - edge1[0][1]]
  218.     d = [edge2[1][0] - edge2[0][0], edge2[1][1] - edge2[0][1]]
  219.     #print("b =", b, "d =", d)
  220.     dVert = [-d[1], d[0]]
  221.     bVert = [-b[1], b[0]]
  222.     #print("dVert =", dVert)
  223.     m = dVert[0] * c[0] + dVert[1] * c[1]
  224.     n = dVert[0] * b[0] + dVert[1] * b[1]
  225.     #print("числитель:", m, "знаменатель:", n)
  226.     if n == 0:
  227.         return False
  228.     t = m / n
  229.     #print("t =", t)
  230.     q = bVert[0] * c[0] + bVert[1] * c[1]
  231.     u = q / n
  232.     #print("u =", u)
  233.     if t < 0 or t > 1 or u < 0 or u > 1:
  234.         return False
  235.     pr = [b[0] * t, b[1] * t]
  236.     #print("t * b =", pr)
  237.     I = [A[0] + pr[0], A[1] + pr[1]]
  238.     #print("I =", I)
  239.     return I
  240.  
  241.  
  242. def checkForBelonging(point, edge): ###edge = [[x1, y1], [x2, y2]]
  243.     # print("point =", point, "edge =", edge)
  244.     maxX = max(edge[0][0], edge[1][0])
  245.     minX = min(edge[0][0], edge[1][0])
  246.     maxY = max(edge[0][1], edge[1][1])
  247.     minY = min(edge[0][1], edge[1][1])
  248.  
  249.     if point[0] <= maxX and point[0] >= minX and point[1] <= maxY and point[1] >= minY:
  250.         if not ((point[0] - edge[0][0]) * (edge[1][1] - edge[0][1]) - (point[1] - edge[0][1]) * (
  251.             edge[1][0] - edge[0][0])):
  252.             return True
  253.         else:
  254.             return False
  255.     else:
  256.         return False
  257.  
  258.  
  259. def sign(a, b):
  260.     if a < b:
  261.         return 1
  262.     elif a == b:
  263.         return 0
  264.     else:
  265.         return -1
  266.  
  267.  
  268. def makeOrder(points, point1, point2):
  269.     intersectionPoints = points
  270.     sx = sign(point1.coords[0], point2.coords[0])
  271.     sy = sign(point1.coords[1], point2.coords[1])
  272.     if sx > 0:
  273.         intersectionPoints.sort(key=lambda x: x.coords[0])
  274.     elif sx < 0:
  275.         intersectionPoints.sort(key=lambda x: -x.coords[0])
  276.     else:
  277.         if sy > 0:
  278.             intersectionPoints.sort(key=lambda x: x.coords[1])
  279.         else:
  280.             intersectionPoints.sort(key=lambda x: -x.coords[1])
  281.     return intersectionPoints
  282.  
  283.  
  284. def background():
  285.     glClearColor(1.0, 1.0, 1.0, 1.0)
  286.     glClear(GL_COLOR_BUFFER_BIT)
  287.  
  288.  
  289. def chngCoordf(point):
  290.     width = 640
  291.     height = 480
  292.  
  293.     x = point[0] * 2 / width - 1
  294.     y = point[1] * 2 / height - 1
  295.  
  296.     return x, y
  297.  
  298.  
  299. def drawShape(points, pointsCount, color):
  300.     glBegin(GL_POLYGON)
  301.  
  302.     glColor3f(color[0], color[1], color[2])
  303.  
  304.     for i in range(pointsCount):
  305.         x, y = chngCoordf(points[i].coords)
  306.         glVertex(x, y)
  307.  
  308.     glEnd()
  309.  
  310.  
  311. def drawLines(points, count, color):
  312.     glBegin(GL_LINE_STRIP)
  313.     glColor3f(color[0], color[1], color[2])
  314.     for i in range(count):
  315.         x, y = chngCoordf(points[i].coords)
  316.         glVertex2f(x, y)
  317.     glEnd()
  318.  
  319. def drawLine(point1, point2, color):
  320.     x1, y1 = chngCoordf(point1.coords)
  321.     x2, y2 = chngCoordf(point2.coords)
  322.     glBegin(GL_LINES)
  323.  
  324.     glColor3f(color[0], color[1], color[2])
  325.     glVertex2f(x1, y1)
  326.     glVertex2f(x2, y2)
  327.  
  328.     glEnd()
  329.  
  330. def draw():
  331.     if not polygon.isEmpty():
  332.         if polygon.size == 1:
  333.             if polygon.isSbjReady:
  334.                 drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  335.             else:
  336.                 drawLines(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  337.         else:
  338.             drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  339.             if polygon.isHolesReady:
  340.                 for i in range(1, polygon.size):
  341.                     drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  342.             else:
  343.                 for i in range(1, polygon.size - 1):
  344.                     drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  345.                 for i in range(polygon.size - 1, polygon.size):
  346.                     drawLines(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  347.     if not clip.isEmpty():
  348.         if clip.isClipReady:
  349.             for i in range(clip.size):
  350.                 drawLine(clip.points[i], clip.points[(i + 1) % clip.size], [1.0, 0, 0])
  351.         else:
  352.             for i in range(clip.size):
  353.                 drawLines(clip.points, clip.size, [1.0, 0.0, 0.0])
  354.  
  355.  
  356. class Drawer:
  357.     window = False
  358.  
  359.     def __init__(self):
  360.         if not glfw.init():
  361.             return
  362.  
  363.         self.window = glfw.create_window(640, 480, "Lab5", None, None)
  364.         if not self.window:
  365.             glfw.terminate()
  366.             return
  367.  
  368.         glfw.make_context_current(self.window)
  369.  
  370.         glfw.set_mouse_button_callback(self.window, mouseCallback)
  371.         glfw.set_key_callback(self.window, keyCallback)
  372.         #glfw.set_window_size_callback(self.window, sizeCallback)
  373.  
  374.  
  375.     def startLoop(self):
  376.         while not glfw.window_should_close(self.window):
  377.             background()
  378.             draw()
  379.  
  380.             glfw.swap_buffers(self.window)
  381.             glfw.poll_events()
  382.  
  383.         glfw.terminate()
  384.  
  385. polygon = Polygon()
  386. clip = Clip()
  387. intersectionShapes = IntersectionShapes()
  388. drawer = Drawer()
  389. drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement