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
- #self.numberOfHole = numberOfHole ###numbering holes starts with 1, 0 means simple outline, False means clip point
- #self.isFinalInHole = 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 isCurrentHoleReady
- # isCurrentHoleReady = 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:
- # if not startPoint:
- # startPoint = True
- # clip.append(p)
- # else:
- 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 isClipInside():
- maxXofClip = -1
- for i in range(clip.size):
- if clip.points[i].coords[0] > maxXofClip:
- maxXofClip = clip.points[i].coords[0]
- maxXofSbj = -1
- for i in range(polygon.sizes[0]):
- if polygon.points[0][i].coords[0] > maxXofSbj:
- maxXofSbj = polygon.points[0][i].coords[0]
- if maxXofClip > maxXofSbj:
- return False
- else:
- return True
- def checkForEntry(point, points):
- maxX = max([i.coords[0] for i in points])
- minX = min([i.coords[0] for i in points])
- maxY = max([i.coords[1] for i in points])
- minY = min([i.coords[1] for i in points])
- if point.coords[0] > minX and point.coords[0] < maxX and point.coords[1] > minY and point.coords[1] < maxY:
- return False
- else:
- return True
- def makeIntersection():
- oldSizes = polygon.sizes
- searchForIntersections()
- # if oldSizes == polygon.sizes:
- # if isClipInside():
- # intersectionShapes.points = [clip.points]
- # intersectionShapes.size = 1
- # intersectionShapes.sizes = [clip.size]
- # else:
- # intersectionShapes.points = polygon.points
- # intersectionShapes.sizes = polygon.sizes
- # intersectionShapes.size = polygon.size
- # else:
- entry = checkForEntry(polygon.points[0][0], clip.points)
- for i in range(polygon.size):
- for j in range(polygon.sizes[i]):
- if polygon.points[i][j].isIntersectionPoint:
- k = clip.points.index(polygon.points[i][j])
- polygon.points[i][j].isEntry = entry
- clip.points[k].isEntry = entry
- l = polygon.points[i][j]
- if entry:
- polygon.listOfEntries.append(l)
- else:
- polygon.listOfExits.append(l)
- entry = not entry
- print("list of entries", [i.coords for i in polygon.listOfEntries])
- print("polygon coords", [i.coords for i in polygon.points[0]])
- print("clip coords", [i.coords for i in clip.points])
- makeIntersectionShapes()
- def makeIntersectionShapes():
- points = []
- size = 0
- goToListOfEntries = False
- startPoint = False
- while polygon.listOfEntries != []:
- a = polygon.listOfEntries.pop() ###here may be some problems
- if not startPoint:
- startPoint = a
- # for i in polygon.points:
- # for j in i:
- # if a == j:
- # points.append(a)
- # size += 1
- # for x in range(i.index(j), i.index(j) +len(i)):
- # points.append(i[x % len(i)])
- for i in range(polygon.size):
- if goToListOfEntries:
- break
- for j in range(polygon.sizes[i]):
- if goToListOfEntries:
- break
- if a == polygon.points[i][j]:
- points.append(a)
- print("points1", [r.coords for r in points])
- size += 1
- print("size =", size)
- for x in range(j + 1, j + polygon.sizes[i]):
- if goToListOfEntries:
- break
- p = polygon.points[i][x % polygon.sizes[i]]
- print("p", p.coords, "index =", x % polygon.sizes[i], "x =", x)
- if not p.isIntersectionPoint:
- points.append(p)
- size += 1
- print("points2", [r.coords for r in points])
- print("size =", size)
- else:
- print("GG WP")
- z = clip.points.index(p)
- points.append(p)
- size += 1
- print("points3", [r.coords for r in points])
- print("size =", size)
- print("p index in clip", z)
- for y in range(z + 1, z + clip.size):
- point = clip.points[y]
- #size += 1
- #print(point.coords, "isIntersection?", point.isIntersectionPoint)
- if not point.isIntersectionPoint:
- points.append(point)
- size += 1
- print("points4", [r.coords for r in points])
- print("size =", size)
- else:
- goToListOfEntries = True
- if point == startPoint:
- intersectionShapes.points.append(points)
- intersectionShapes.size += 1
- intersectionShapes.sizes.append(size)
- points = []
- size = 0
- startPoint = False
- break
- if goToListOfEntries:
- goToListOfEntries = False
- 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
- # if point1.coords[0] < point2.coords[0]:
- # sx = 1
- # elif point1.coords[0] == point2.coords[0]:
- # sx = 0
- # else:
- # sx = -1
- # if point1.coords[1] < point2.coords[1]:
- # sy = 1
- # elif point1.coords[1] == point2.coords[1]:
- # sy = 0
- # else:
- # sy = -1
- 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], [0, 0, 1.0])
- else:
- for i in range(clip.size):
- drawLines(clip.points, clip.size, [0.0, 0.0, 1.0])
- if not intersectionShapes.isEmpty():
- for i in range(intersectionShapes.size):
- #print("shapes coords", [j.coords for j in intersectionShapes.points[i]])
- print("shape", [s.coords for s in intersectionShapes.points[i]], "sizes", intersectionShapes.sizes)
- drawShape(intersectionShapes.points[i], intersectionShapes.sizes[i], [1.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