Advertisement
trishLEX

Untitled

Apr 21st, 2017
526
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 17.86 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.         #self.numberOfHole = numberOfHole ###numbering holes starts with 1, 0 means simple outline, False means clip point
  14.         #self.isFinalInHole = False
  15.     def __len__(self):
  16.         return 1
  17.  
  18.  
  19. class Polygon:
  20.     isSbjReady = False
  21.     isHolesReady = False
  22.     listOfEntries = []
  23.     listOfExits = []
  24.     def __init__(self):
  25.         self.points = []
  26.         self.sizes = []
  27.         self.size = 0
  28.     def insert(self, x, i):
  29.         for j in x:
  30.             self.points[i].append(j)
  31.         self.sizes[i] += len(x)
  32.     def append(self, x):
  33.         self.points.append(x)
  34.         self.sizes.append(len(x))
  35.         self.size += 1
  36.     def isEmpty(self):
  37.         if self.size == 0 and self.points == [] and self.sizes == []:
  38.             return True
  39.         else:
  40.             return False
  41.  
  42. class Clip:
  43.     isClipReady = False
  44.     def __init__(self):
  45.         self.points = []
  46.         self.size = 0
  47.     def append(self, x):
  48.         self.points.append(x)
  49.         self.size += 1
  50.  
  51.     def isEmpty(self):
  52.         if self.size:
  53.             return False
  54.         else:
  55.             return True
  56.  
  57. class IntersectionShapes:
  58.     isIntersectionMade = False
  59.     def __init__(self):
  60.         self.points = []
  61.         self.sizes = []
  62.         self.size = 0
  63.     def insert(self, x, i):
  64.         for j in x:
  65.             self.points[i].append(j)
  66.         self.sizes[i] += len(x)
  67.     def append(self, x):
  68.         self.points.append(x)
  69.         self.sizes.append(len(x))
  70.         self.size += 1
  71.     def isEmpty(self):
  72.         if self.size == 0 and self.points == [] and self.sizes == []:
  73.             return True
  74.         else:
  75.             return False
  76.  
  77.  
  78. # global isCurrentHoleReady
  79. # isCurrentHoleReady = False
  80. global startPoint
  81. startPoint = False
  82. def mouseCallback(window, button, action, mods):
  83.     global startPoint
  84.     if button == glfw.MOUSE_BUTTON_1 and action:
  85.         mouse = glfw.get_cursor_pos(window)
  86.         mouse = [int(mouse[0]), 480 - int(mouse[1])]
  87.         p = Vertex(mouse)
  88.         if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  89.             if polygon.isEmpty():
  90.                 if not startPoint:
  91.                     startPoint = True
  92.                     polygon.append([p])
  93.             else:
  94.                 polygon.insert([p], 0)
  95.         #print("isSbjReady", polygon.isSbjReady, "isHolesReady", polygon.isHolesReady, "isClipReady", clip.isClipReady)
  96.         #print(polygon.size)
  97.         if polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  98.             if not startPoint:
  99.                 startPoint = True
  100.                 polygon.append([p])
  101.             else:
  102.                 polygon.insert([p], polygon.size - 1)
  103.         if polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
  104.             # if not startPoint:
  105.             #     startPoint = True
  106.             #     clip.append(p)
  107.             # else:
  108.             clip.append(p)
  109.         #print(polygon.size)
  110.         #print(polygon.sizes)
  111.         # for i in range(polygon.size):
  112.         #     for j in range(polygon.sizes[i]):
  113.         #         print(polygon.points[i][j].coords)
  114.  
  115.  
  116. def keyCallback(window, key, scancode, action, mods):
  117.     #global isCurrentHoleReady
  118.     global startPoint
  119.     if key == glfw.KEY_SPACE and action:
  120.         if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  121.             startPoint = False
  122.             polygon.isSbjReady = True
  123.             print("PRESS SPACE TO SKIP DRAWING HOLES")
  124.         elif polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
  125.             #isCurrentHoleReady = True
  126.             startPoint = False
  127.             polygon.isHolesReady = True
  128.         elif polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
  129.             #startPoint = False
  130.             clip.isClipReady = True
  131.     if key == glfw.KEY_H and action:
  132.         polygon.isHolesReady = False
  133.     if key == glfw.KEY_ENTER and action:
  134.         makeIntersection()
  135.  
  136.  
  137. def isClipInside():
  138.     maxXofClip = -1
  139.     for i in range(clip.size):
  140.         if clip.points[i].coords[0] > maxXofClip:
  141.             maxXofClip = clip.points[i].coords[0]
  142.     maxXofSbj = -1
  143.     for i in range(polygon.sizes[0]):
  144.         if polygon.points[0][i].coords[0] > maxXofSbj:
  145.             maxXofSbj = polygon.points[0][i].coords[0]
  146.  
  147.     if maxXofClip > maxXofSbj:
  148.         return False
  149.     else:
  150.         return True
  151.  
  152.  
  153. def checkForEntry(point, points):
  154.     maxX = max([i.coords[0] for i in points])
  155.     minX = min([i.coords[0] for i in points])
  156.     maxY = max([i.coords[1] for i in points])
  157.     minY = min([i.coords[1] for i in points])
  158.  
  159.     if point.coords[0] > minX and point.coords[0] < maxX and point.coords[1] > minY and point.coords[1] < maxY:
  160.         return False
  161.     else:
  162.         return True
  163.  
  164.  
  165. def makeIntersection():
  166.     oldSizes = polygon.sizes
  167.     searchForIntersections()
  168.  
  169.     # if oldSizes == polygon.sizes:
  170.     #     if isClipInside():
  171.     #         intersectionShapes.points = [clip.points]
  172.     #         intersectionShapes.size = 1
  173.     #         intersectionShapes.sizes = [clip.size]
  174.     #     else:
  175.     #         intersectionShapes.points = polygon.points
  176.     #         intersectionShapes.sizes = polygon.sizes
  177.     #         intersectionShapes.size = polygon.size
  178.     # else:
  179.     entry = checkForEntry(polygon.points[0][0], clip.points)
  180.  
  181.     for i in range(polygon.size):
  182.         for j in range(polygon.sizes[i]):
  183.             if polygon.points[i][j].isIntersectionPoint:
  184.                 k = clip.points.index(polygon.points[i][j])
  185.                 polygon.points[i][j].isEntry = entry
  186.                 clip.points[k].isEntry = entry
  187.                 l = polygon.points[i][j]
  188.                 if entry:
  189.                     polygon.listOfEntries.append(l)
  190.                 else:
  191.                     polygon.listOfExits.append(l)
  192.                 entry = not entry
  193.  
  194.     print("list of entries", [i.coords for i in polygon.listOfEntries])
  195.     print("polygon coords", [i.coords for i in polygon.points[0]])
  196.     print("clip coords", [i.coords for i in clip.points])
  197.  
  198.     makeIntersectionShapes()
  199.  
  200.  
  201. def makeIntersectionShapes():
  202.     points = []
  203.     size = 0
  204.     goToListOfEntries = False
  205.     startPoint = False
  206.     while polygon.listOfEntries != []:
  207.         a = polygon.listOfEntries.pop() ###here may be some problems
  208.         if not startPoint:
  209.             startPoint = a
  210.         # for i in polygon.points:
  211.         #     for j in i:
  212.         #         if a == j:
  213.         #             points.append(a)
  214.         #             size += 1
  215.         #             for x in range(i.index(j), i.index(j) +len(i)):
  216.         #                 points.append(i[x % len(i)])
  217.         for i in range(polygon.size):
  218.             if goToListOfEntries:
  219.                 break
  220.             for j in range(polygon.sizes[i]):
  221.                 if goToListOfEntries:
  222.                     break
  223.                 if a == polygon.points[i][j]:
  224.                     points.append(a)
  225.                     print("points1", [r.coords for r in points])
  226.                     size += 1
  227.                     print("size =", size)
  228.                     for x in range(j + 1, j + polygon.sizes[i]):
  229.                         if goToListOfEntries:
  230.                             break
  231.                         p = polygon.points[i][x % polygon.sizes[i]]
  232.                         print("p", p.coords, "index =", x % polygon.sizes[i], "x =", x)
  233.                         if not p.isIntersectionPoint:
  234.                             points.append(p)
  235.                             size += 1
  236.                             print("points2", [r.coords for r in points])
  237.                             print("size =", size)
  238.                         else:
  239.                             print("GG WP")
  240.                             z = clip.points.index(p)
  241.                             points.append(p)
  242.                             size += 1
  243.                             print("points3", [r.coords for r in points])
  244.                             print("size =", size)
  245.                             print("p index in clip", z)
  246.                             for y in range(z + 1, z + clip.size):
  247.                                 point = clip.points[y]
  248.                                 #size += 1
  249.                                 #print(point.coords, "isIntersection?", point.isIntersectionPoint)
  250.                                 if not point.isIntersectionPoint:
  251.                                     points.append(point)
  252.                                     size += 1
  253.                                     print("points4", [r.coords for r in points])
  254.                                     print("size =", size)
  255.                                 else:
  256.                                     goToListOfEntries = True
  257.                                     if point == startPoint:
  258.                                         intersectionShapes.points.append(points)
  259.                                         intersectionShapes.size += 1
  260.                                         intersectionShapes.sizes.append(size)
  261.                                         points = []
  262.                                         size = 0
  263.                                         startPoint = False
  264.                                     break
  265.         if goToListOfEntries:
  266.             goToListOfEntries = False
  267.  
  268.  
  269.  
  270.  
  271. def searchForIntersections():
  272.     newSbjPoints = []
  273.     newClipPoints = []
  274.  
  275.     newSbjSizes = []
  276.     newSbjSize = 0
  277.     newClipSize = 0
  278.  
  279.     for i in range(polygon.size):
  280.         points = []
  281.         size = 0
  282.         for k in range(polygon.sizes[i]):
  283.             points.append(polygon.points[i][k])
  284.             size += 1
  285.             intersectionPoints = []
  286.             intersectionPointsCount = 0
  287.             for j in range(clip.size):
  288.                 if clip.points[j] not in newClipPoints:
  289.                     newClipPoints.append(clip.points[j])
  290.                     newClipSize += 1
  291.                 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])
  292.                 if I:
  293.                     intersectionPointsCount += 1
  294.                     p = Vertex(I)
  295.                     p.isIntersectionPoint = True
  296.                     intersectionPoints.append(p)
  297.                     intersectionPointsCount += 1
  298.                     newClipPoints.append(p)
  299.                     newClipSize += 1
  300.             intersectionPoints = makeOrder(intersectionPoints, polygon.points[i][k], polygon.points[i][(k + 1) % polygon.sizes[i]])
  301.             if intersectionPoints != []:
  302.                 for l in intersectionPoints:
  303.                     points.append(l)
  304.                     size += 1
  305.         newSbjPoints.append(points)
  306.         newSbjSize += 1
  307.         newSbjSizes.append(size)
  308.  
  309.     polygon.points = newSbjPoints
  310.     polygon.sizes = newSbjSizes
  311.     polygon.size = newSbjSize
  312.  
  313.     #print(polygon.sizes)
  314.  
  315.     global center
  316.     center = findCenterOfMass(newClipPoints)
  317.     newClipPoints.sort(key=sort, reverse=True)
  318.  
  319.     clip.points = newClipPoints
  320.     clip.size = newClipSize
  321.  
  322.     #for i in polygon.points[0]:
  323.     #    print(i.coords)
  324.  
  325. def findCenterOfMass(points):
  326.     m = n = 0
  327.     count = 0
  328.     for i in points:
  329.         m += i.coords[0]
  330.         n += i.coords[1]
  331.         count += 1
  332.     return [m / count, n / count]
  333.  
  334. def sort(p):
  335.     point = [p.coords[0] - center[0], p.coords[1] - center[1]]
  336.     phi = atan(point[1] / point[0])
  337.     if point[0] < 0 and point[1] > 0 or point[0] < 0 and point[1] < 0:
  338.         phi += pi
  339.     if point[0] > 0 and point[1] < 0:
  340.         phi += 2 * pi
  341.     return phi
  342.  
  343.  
  344. def intersectionFound(edge1, edge2):
  345.     if checkForBelonging(edge1[0], edge2) or checkForBelonging(edge1[1], edge2) or checkForBelonging(edge2[0], edge1) or checkForBelonging(edge2[1], edge1):
  346.         #print("I'm here")
  347.         return False
  348.     #print("edge1 =", edge1, "edge2 =", edge2)
  349.     A = edge1[0]
  350.     C = edge2[0]
  351.     #print("A =", A, "C =", C)
  352.     c = [C[0] - A[0], C[1] - A[1]]
  353.     #print("c =", c)
  354.     b = [edge1[1][0] - edge1[0][0], edge1[1][1] - edge1[0][1]]
  355.     d = [edge2[1][0] - edge2[0][0], edge2[1][1] - edge2[0][1]]
  356.     #print("b =", b, "d =", d)
  357.     dVert = [-d[1], d[0]]
  358.     bVert = [-b[1], b[0]]
  359.     #print("dVert =", dVert)
  360.     m = dVert[0] * c[0] + dVert[1] * c[1]
  361.     n = dVert[0] * b[0] + dVert[1] * b[1]
  362.     #print("числитель:", m, "знаменатель:", n)
  363.     if n == 0:
  364.         return False
  365.     t = m / n
  366.     #print("t =", t)
  367.     q = bVert[0] * c[0] + bVert[1] * c[1]
  368.     u = q / n
  369.     #print("u =", u)
  370.     if t < 0 or t > 1 or u < 0 or u > 1:
  371.         return False
  372.     pr = [b[0] * t, b[1] * t]
  373.     #print("t * b =", pr)
  374.     I = [A[0] + pr[0], A[1] + pr[1]]
  375.     #print("I =", I)
  376.     return I
  377.  
  378.  
  379. def checkForBelonging(point, edge): ###edge = [[x1, y1], [x2, y2]]
  380.     # print("point =", point, "edge =", edge)
  381.     maxX = max(edge[0][0], edge[1][0])
  382.     minX = min(edge[0][0], edge[1][0])
  383.     maxY = max(edge[0][1], edge[1][1])
  384.     minY = min(edge[0][1], edge[1][1])
  385.  
  386.     if point[0] <= maxX and point[0] >= minX and point[1] <= maxY and point[1] >= minY:
  387.         if not ((point[0] - edge[0][0]) * (edge[1][1] - edge[0][1]) - (point[1] - edge[0][1]) * (
  388.             edge[1][0] - edge[0][0])):
  389.             return True
  390.         else:
  391.             return False
  392.     else:
  393.         return False
  394.  
  395.  
  396. def sign(a, b):
  397.     if a < b:
  398.         return 1
  399.     elif a == b:
  400.         return 0
  401.     else:
  402.         return -1
  403.  
  404.  
  405. def makeOrder(points, point1, point2):
  406.     intersectionPoints = points
  407.     # if point1.coords[0] < point2.coords[0]:
  408.     #     sx = 1
  409.     # elif point1.coords[0] == point2.coords[0]:
  410.     #     sx = 0
  411.     # else:
  412.     #     sx = -1
  413.     # if point1.coords[1] < point2.coords[1]:
  414.     #     sy = 1
  415.     # elif point1.coords[1] == point2.coords[1]:
  416.     #     sy = 0
  417.     # else:
  418.     #     sy = -1
  419.     sx = sign(point1.coords[0], point2.coords[0])
  420.     sy = sign(point1.coords[1], point2.coords[1])
  421.     if sx > 0:
  422.         intersectionPoints.sort(key=lambda x: x.coords[0])
  423.     elif sx < 0:
  424.         intersectionPoints.sort(key=lambda x: -x.coords[0])
  425.     else:
  426.         if sy > 0:
  427.             intersectionPoints.sort(key=lambda x: x.coords[1])
  428.         else:
  429.             intersectionPoints.sort(key=lambda x: -x.coords[1])
  430.     return intersectionPoints
  431.  
  432.  
  433. def background():
  434.     glClearColor(1.0, 1.0, 1.0, 1.0)
  435.     glClear(GL_COLOR_BUFFER_BIT)
  436.  
  437.  
  438. def chngCoordf(point):
  439.     width = 640
  440.     height = 480
  441.  
  442.     x = point[0] * 2 / width - 1
  443.     y = point[1] * 2 / height - 1
  444.  
  445.     return x, y
  446.  
  447.  
  448. def drawShape(points, pointsCount, color):
  449.     glBegin(GL_POLYGON)
  450.  
  451.     glColor3f(color[0], color[1], color[2])
  452.  
  453.     for i in range(pointsCount):
  454.         x, y = chngCoordf(points[i].coords)
  455.         glVertex(x, y)
  456.  
  457.     glEnd()
  458.  
  459.  
  460. def drawLines(points, count, color):
  461.     glBegin(GL_LINE_STRIP)
  462.     glColor3f(color[0], color[1], color[2])
  463.     for i in range(count):
  464.         x, y = chngCoordf(points[i].coords)
  465.         glVertex2f(x, y)
  466.     glEnd()
  467.  
  468. def drawLine(point1, point2, color):
  469.     x1, y1 = chngCoordf(point1.coords)
  470.     x2, y2 = chngCoordf(point2.coords)
  471.     glBegin(GL_LINES)
  472.  
  473.     glColor3f(color[0], color[1], color[2])
  474.     glVertex2f(x1, y1)
  475.     glVertex2f(x2, y2)
  476.  
  477.     glEnd()
  478.  
  479. def draw():
  480.     if not polygon.isEmpty():
  481.         if polygon.size == 1:
  482.             if polygon.isSbjReady:
  483.                 drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  484.             else:
  485.                 drawLines(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  486.         else:
  487.             drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
  488.             if polygon.isHolesReady:
  489.                 for i in range(1, polygon.size):
  490.                     drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  491.             else:
  492.                 for i in range(1, polygon.size - 1):
  493.                     drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  494.                 for i in range(polygon.size - 1, polygon.size):
  495.                     drawLines(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
  496.     if not clip.isEmpty():
  497.         if clip.isClipReady:
  498.             for i in range(clip.size):
  499.                 drawLine(clip.points[i], clip.points[(i + 1) % clip.size], [0, 0, 1.0])
  500.         else:
  501.             for i in range(clip.size):
  502.                 drawLines(clip.points, clip.size, [0.0, 0.0, 1.0])
  503.     if not intersectionShapes.isEmpty():
  504.         for i in range(intersectionShapes.size):
  505.             #print("shapes coords", [j.coords for j in intersectionShapes.points[i]])
  506.             print("shape", [s.coords for s in intersectionShapes.points[i]], "sizes", intersectionShapes.sizes)
  507.             drawShape(intersectionShapes.points[i], intersectionShapes.sizes[i], [1.0, 0, 0])
  508.  
  509.  
  510. class Drawer:
  511.     window = False
  512.  
  513.     def __init__(self):
  514.         if not glfw.init():
  515.             return
  516.  
  517.         self.window = glfw.create_window(640, 480, "Lab5", None, None)
  518.         if not self.window:
  519.             glfw.terminate()
  520.             return
  521.  
  522.         glfw.make_context_current(self.window)
  523.  
  524.         glfw.set_mouse_button_callback(self.window, mouseCallback)
  525.         glfw.set_key_callback(self.window, keyCallback)
  526.         #glfw.set_window_size_callback(self.window, sizeCallback)
  527.  
  528.  
  529.     def startLoop(self):
  530.         while not glfw.window_should_close(self.window):
  531.             background()
  532.             draw()
  533.  
  534.             glfw.swap_buffers(self.window)
  535.             glfw.poll_events()
  536.  
  537.         glfw.terminate()
  538.  
  539. polygon = Polygon()
  540. clip = Clip()
  541. intersectionShapes = IntersectionShapes()
  542. drawer = Drawer()
  543. drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement