Advertisement
trishLEX

Untitled

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