Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import glfw
- from OpenGL.GL import *
- from math import atan
- from math import pi
- class Vertex:
- def __init__(self, point):
- self.coords = point
- #self.isHole = isHole
- self.isIntersectionPoint = False
- self.isEntry = False
- def __len__(self):
- return 1
- class Polygon:
- isSbjReady = False
- isHolesReady = False
- listOfEntries = []
- listOfExits = []
- def __init__(self):
- self.points = []
- self.sizes = []
- self.size = 0
- def insert(self, x, i):
- for j in x:
- self.points[i].append(j)
- self.sizes[i] += len(x)
- def append(self, x):
- self.points.append(x)
- self.sizes.append(len(x))
- self.size += 1
- def isEmpty(self):
- if self.size == 0 and self.points == [] and self.sizes == []:
- return True
- else:
- return False
- class Clip:
- isClipReady = False
- def __init__(self):
- self.points = []
- self.size = 0
- def append(self, x):
- self.points.append(x)
- self.size += 1
- def isEmpty(self):
- if self.size:
- return False
- else:
- return True
- class IntersectionShapes:
- isIntersectionMade = False
- def __init__(self):
- self.points = []
- self.sizes = []
- self.size = 0
- def insert(self, x, i):
- for j in x:
- self.points[i].append(j)
- self.sizes[i] += len(x)
- def append(self, x):
- self.points.append(x)
- self.sizes.append(len(x))
- self.size += 1
- def isEmpty(self):
- if self.size == 0 and self.points == [] and self.sizes == []:
- return True
- else:
- return False
- global startPoint
- startPoint = False
- def mouseCallback(window, button, action, mods):
- global startPoint
- if button == glfw.MOUSE_BUTTON_1 and action:
- mouse = glfw.get_cursor_pos(window)
- mouse = [int(mouse[0]), 480 - int(mouse[1])]
- p = Vertex(mouse)
- if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
- if polygon.isEmpty():
- if not startPoint:
- startPoint = True
- polygon.append([p])
- else:
- polygon.insert([p], 0)
- #print("isSbjReady", polygon.isSbjReady, "isHolesReady", polygon.isHolesReady, "isClipReady", clip.isClipReady)
- #print(polygon.size)
- if polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
- if not startPoint:
- startPoint = True
- polygon.append([p])
- else:
- polygon.insert([p], polygon.size - 1)
- if polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
- clip.append(p)
- #print(polygon.size)
- #print(polygon.sizes)
- # for i in range(polygon.size):
- # for j in range(polygon.sizes[i]):
- # print(polygon.points[i][j].coords)
- def keyCallback(window, key, scancode, action, mods):
- #global isCurrentHoleReady
- global startPoint
- if key == glfw.KEY_SPACE and action:
- if not polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
- startPoint = False
- polygon.isSbjReady = True
- print("PRESS SPACE TO SKIP DRAWING HOLES")
- elif polygon.isSbjReady and not polygon.isHolesReady and not clip.isClipReady:
- #isCurrentHoleReady = True
- startPoint = False
- polygon.isHolesReady = True
- elif polygon.isSbjReady and polygon.isHolesReady and not clip.isClipReady:
- #startPoint = False
- clip.isClipReady = True
- if key == glfw.KEY_H and action:
- polygon.isHolesReady = False
- if key == glfw.KEY_ENTER and action:
- makeIntersection()
- def makeIntersection():
- searchForIntersections()
- def searchForIntersections():
- newSbjPoints = []
- newClipPoints = []
- newSbjSizes = []
- newSbjSize = 0
- newClipSize = 0
- for i in range(polygon.size):
- points = []
- size = 0
- for k in range(polygon.sizes[i]):
- points.append(polygon.points[i][k])
- size += 1
- intersectionPoints = []
- intersectionPointsCount = 0
- for j in range(clip.size):
- if clip.points[j] not in newClipPoints:
- newClipPoints.append(clip.points[j])
- newClipSize += 1
- 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])
- if I:
- intersectionPointsCount += 1
- p = Vertex(I)
- p.isIntersectionPoint = True
- intersectionPoints.append(p)
- intersectionPointsCount += 1
- newClipPoints.append(p)
- newClipSize += 1
- intersectionPoints = makeOrder(intersectionPoints, polygon.points[i][k], polygon.points[i][(k + 1) % polygon.sizes[i]])
- if intersectionPoints != []:
- for l in intersectionPoints:
- points.append(l)
- size += 1
- newSbjPoints.append(points)
- newSbjSize += 1
- newSbjSizes.append(size)
- polygon.points = newSbjPoints
- polygon.sizes = newSbjSizes
- polygon.size = newSbjSize
- #print(polygon.sizes)
- global center
- center = findCenterOfMass(newClipPoints)
- newClipPoints.sort(key=sort, reverse=True)
- clip.points = newClipPoints
- clip.size = newClipSize
- #for i in polygon.points[0]:
- # print(i.coords)
- def findCenterOfMass(points):
- m = n = 0
- count = 0
- for i in points:
- m += i.coords[0]
- n += i.coords[1]
- count += 1
- return [m / count, n / count]
- def sort(p):
- point = [p.coords[0] - center[0], p.coords[1] - center[1]]
- phi = atan(point[1] / point[0])
- if point[0] < 0 and point[1] > 0 or point[0] < 0 and point[1] < 0:
- phi += pi
- if point[0] > 0 and point[1] < 0:
- phi += 2 * pi
- return phi
- def intersectionFound(edge1, edge2):
- if checkForBelonging(edge1[0], edge2) or checkForBelonging(edge1[1], edge2) or checkForBelonging(edge2[0], edge1) or checkForBelonging(edge2[1], edge1):
- #print("I'm here")
- return False
- #print("edge1 =", edge1, "edge2 =", edge2)
- A = edge1[0]
- C = edge2[0]
- #print("A =", A, "C =", C)
- c = [C[0] - A[0], C[1] - A[1]]
- #print("c =", c)
- b = [edge1[1][0] - edge1[0][0], edge1[1][1] - edge1[0][1]]
- d = [edge2[1][0] - edge2[0][0], edge2[1][1] - edge2[0][1]]
- #print("b =", b, "d =", d)
- dVert = [-d[1], d[0]]
- bVert = [-b[1], b[0]]
- #print("dVert =", dVert)
- m = dVert[0] * c[0] + dVert[1] * c[1]
- n = dVert[0] * b[0] + dVert[1] * b[1]
- #print("числитель:", m, "знаменатель:", n)
- if n == 0:
- return False
- t = m / n
- #print("t =", t)
- q = bVert[0] * c[0] + bVert[1] * c[1]
- u = q / n
- #print("u =", u)
- if t < 0 or t > 1 or u < 0 or u > 1:
- return False
- pr = [b[0] * t, b[1] * t]
- #print("t * b =", pr)
- I = [A[0] + pr[0], A[1] + pr[1]]
- #print("I =", I)
- return I
- def checkForBelonging(point, edge): ###edge = [[x1, y1], [x2, y2]]
- # print("point =", point, "edge =", edge)
- maxX = max(edge[0][0], edge[1][0])
- minX = min(edge[0][0], edge[1][0])
- maxY = max(edge[0][1], edge[1][1])
- minY = min(edge[0][1], edge[1][1])
- if point[0] <= maxX and point[0] >= minX and point[1] <= maxY and point[1] >= minY:
- if not ((point[0] - edge[0][0]) * (edge[1][1] - edge[0][1]) - (point[1] - edge[0][1]) * (
- edge[1][0] - edge[0][0])):
- return True
- else:
- return False
- else:
- return False
- def sign(a, b):
- if a < b:
- return 1
- elif a == b:
- return 0
- else:
- return -1
- def makeOrder(points, point1, point2):
- intersectionPoints = points
- sx = sign(point1.coords[0], point2.coords[0])
- sy = sign(point1.coords[1], point2.coords[1])
- if sx > 0:
- intersectionPoints.sort(key=lambda x: x.coords[0])
- elif sx < 0:
- intersectionPoints.sort(key=lambda x: -x.coords[0])
- else:
- if sy > 0:
- intersectionPoints.sort(key=lambda x: x.coords[1])
- else:
- intersectionPoints.sort(key=lambda x: -x.coords[1])
- return intersectionPoints
- def background():
- glClearColor(1.0, 1.0, 1.0, 1.0)
- glClear(GL_COLOR_BUFFER_BIT)
- def chngCoordf(point):
- width = 640
- height = 480
- x = point[0] * 2 / width - 1
- y = point[1] * 2 / height - 1
- return x, y
- def drawShape(points, pointsCount, color):
- glBegin(GL_POLYGON)
- glColor3f(color[0], color[1], color[2])
- for i in range(pointsCount):
- x, y = chngCoordf(points[i].coords)
- glVertex(x, y)
- glEnd()
- def drawLines(points, count, color):
- glBegin(GL_LINE_STRIP)
- glColor3f(color[0], color[1], color[2])
- for i in range(count):
- x, y = chngCoordf(points[i].coords)
- glVertex2f(x, y)
- glEnd()
- def drawLine(point1, point2, color):
- x1, y1 = chngCoordf(point1.coords)
- x2, y2 = chngCoordf(point2.coords)
- glBegin(GL_LINES)
- glColor3f(color[0], color[1], color[2])
- glVertex2f(x1, y1)
- glVertex2f(x2, y2)
- glEnd()
- def draw():
- if not polygon.isEmpty():
- if polygon.size == 1:
- if polygon.isSbjReady:
- drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
- else:
- drawLines(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
- else:
- drawShape(polygon.points[0], polygon.sizes[0], [0.0, 0.0, 0.0])
- if polygon.isHolesReady:
- for i in range(1, polygon.size):
- drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
- else:
- for i in range(1, polygon.size - 1):
- drawShape(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
- for i in range(polygon.size - 1, polygon.size):
- drawLines(polygon.points[i], polygon.sizes[i], [1.0, 1.0, 1.0])
- if not clip.isEmpty():
- if clip.isClipReady:
- for i in range(clip.size):
- drawLine(clip.points[i], clip.points[(i + 1) % clip.size], [1.0, 0, 0])
- else:
- for i in range(clip.size):
- drawLines(clip.points, clip.size, [1.0, 0.0, 0.0])
- class Drawer:
- window = False
- def __init__(self):
- if not glfw.init():
- return
- self.window = glfw.create_window(640, 480, "Lab5", None, None)
- if not self.window:
- glfw.terminate()
- return
- glfw.make_context_current(self.window)
- glfw.set_mouse_button_callback(self.window, mouseCallback)
- glfw.set_key_callback(self.window, keyCallback)
- #glfw.set_window_size_callback(self.window, sizeCallback)
- def startLoop(self):
- while not glfw.window_should_close(self.window):
- background()
- draw()
- glfw.swap_buffers(self.window)
- glfw.poll_events()
- glfw.terminate()
- polygon = Polygon()
- clip = Clip()
- intersectionShapes = IntersectionShapes()
- drawer = Drawer()
- drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement