def __calculateIntersection(self): if self.__line1 is not None and self.__line2 is not None: check = LineSegment.checkSegmentIntersection( self.__line1, self.__line2) if check: self.__status_text = 'Line Segments intersect with each other.' self.__intersection_point = LineSegment.lineSegmentsIntersectionPoint( self.__line1, self.__line2) else: self.__status_text = 'Line Segment doesn\'t intersect with each other.' self.__intersection_point = None
def handleEvents(self, events): self.__mouse.updateMouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1]), events) for event in events: if event.type == pg.KEYDOWN: if event.key == pg.K_d: self.__changeDrawStatus() if event.key == pg.K_o: self.__origin = self.__mouse.position self.__calculateRotation() if event.type == pg.USEREVENT: if event.user_type == pg_gui.UI_TEXT_ENTRY_CHANGED and event.ui_element == self.__angle_input: txt = self.__angle_input.text if txt == '' or txt == '-': txt = '0' self.__changeRotation(value=int(txt)) if self.__mouse.leftDownClick and self.__draw_object: if self.__drop_down.selected_option == TransformationView.LINE_TEXT: self.__line = LineSegment(self.__mouse.position, self.__mouse.position) elif self.__drop_down.selected_option == TransformationView.RECTANGLE_TEXT: self.__rectangle = [ self.__mouse.position, self.__mouse.position, self.__mouse.position, self.__mouse.position ] elif self.__drop_down.selected_option == TransformationView.POLYGON_TEXT: if self.__polygon is not None: self.__polygon.append(self.__mouse.position) elif self.__mouse.leftDrag and self.__draw_object: if self.__drop_down.selected_option == TransformationView.LINE_TEXT: if self.__line is not None: start = self.__line.start self.__line = LineSegment(start, self.__mouse.position) self.__calculateRotation() elif self.__drop_down.selected_option == TransformationView.RECTANGLE_TEXT: if self.__rectangle is not None: pos = self.__mouse.position p1 = self.__rectangle[0] p2 = Vector2(pos.x, p1.y) p3 = pos p4 = Vector2(p1.x, pos.y) self.__rectangle = [p1, p2, p3, p4] self.__calculateRotation() elif self.__mouse.scrollUp and self.__angle_input.is_focused: self.__changeRotation(delta_change=1) if self.__mouse.scrollDown and self.__angle_input.is_focused: self.__changeRotation(delta_change=-1)
def render(self, debug=False): if self.__mouse.leftDrag and len(self.__lines) > 0: self.__lines[-1] = LineSegment(self.__lines[-1].start, self.__mouse.position) for i in range(len(self.__lines)): line = self.__lines[i] Renderer.getInstance().renderLine(line.start, line.end) Renderer.getInstance().renderText(f'{line.start.x, line.start.y}', line.start - Vector2(0, 10), font_size=14) Renderer.getInstance().renderText(f'{line.end.x, line.end.y}', line.end - Vector2(0, 10), font_size=14) Renderer.getInstance().renderText( f'{i}', (line.start + line.end) // 2 + Vector2(0, 10), font_size=14) for line in self.__resultant_lines: Renderer.getInstance().renderLine(line.start, line.end, color=(255, 0, 0)) if self.__status_text is not None: pos = Vector2(Renderer.getInstance().surface.get_width() // 2, Renderer.getInstance().surface.get_height() - 15) Renderer.getInstance().renderText(self.__status_text, pos)
def upperClip(polygon, rect): min_x = min(rect[0].x, rect[1].x, rect[2].x, rect[3].x) min_y = min(rect[0].y, rect[1].y, rect[2].y, rect[3].y) max_x = max(rect[0].x, rect[1].x, rect[2].x, rect[3].x) max_y = max(rect[0].y, rect[1].y, rect[2].y, rect[3].y) newPolygon = [Vector2(pt.x, pt.y) for pt in polygon] length = len(newPolygon) points = [] # upper clipping for i in range(length): pt1 = newPolygon[i] pt2 = newPolygon[(i + 1) % length] pt1_inside = False if pt1.y <= max_y: pt1_inside = True pt2_inside = False if pt2.y <= max_y: pt2_inside = True if pt1_inside: if pt2_inside: points.append(pt2) else: line1 = LineSegment(pt1, pt2) line2 = LineSegment(Vector2(-INF, max_y), Vector2(INF, max_y)) if line1.checkIntersection(line2): intersection_pt = line1.intersectionPoint(line2) points.append(intersection_pt) else: if pt2_inside: line1 = LineSegment(pt1, pt2) line2 = LineSegment(Vector2(-INF, max_y), Vector2(INF, max_y)) if line1.checkIntersection(line2): intersection_pt = line1.intersectionPoint(line2) points.append(intersection_pt) points.append(pt2) else: continue return points
def handleEvents(self, events): self.__mouse.updateMouse(Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1]), events) if self.__mouse.leftDownClick: self.__start_pos = self.__mouse.position elif self.__mouse.leftUpClick: self.__end_pos = self.__mouse.position if self.__start_pos.distance_squared_to(self.__end_pos) > 10: if self.__line_id == 0: self.__line1 = LineSegment( self.__start_pos, self.__end_pos) else: self.__line2 = LineSegment( self.__start_pos, self.__end_pos) self.__calculateIntersection() elif self.__mouse.scrollUp: self.__line_id += 1 self.__line_id %= 2 elif self.__mouse.scrollDown: self.__line_id = (2 + self.__line_id - 1) % 2 self.__line_id %= 2
def handleEvents(self, events): self.__mouse.updateMouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1]), events) if self.__mouse.leftDownClick: self.__start_pos = self.__mouse.position elif self.__mouse.leftUpClick: self.__end_pos = self.__mouse.position if self.__start_pos.distance_squared_to(self.__end_pos) > 10: self.__line = LineSegment(self.__start_pos, self.__end_pos) else: self.__point = self.__end_pos self.__calculateOrientation()
def handleEvents(self, events): self.__mouse.updateMouse((Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])), events) for event in events: if event.type == pg.KEYDOWN: if event.key == pg.K_c: pass if self.__mouse.leftDownClick: self.__lines.append( LineSegment(self.__mouse.position, self.__mouse.position)) elif self.__mouse.leftUpClick: if len(self.__lines) > 0: start = self.__lines[-1].start end = self.__lines[-1].end if start.distance_squared_to(end) < 10: self.__lines.pop() self.__calculateSweepLine()
def __calculateScale(self): self.__status_text = f'Transformation: scale by {self.__scale}' if self.__line is not None: start = scaleVector(self.__line.start - self.__origin, self.__scale) end = scaleVector(self.__line.end - self.__origin, self.__scale) self.__resultant_line = LineSegment(self.__origin + start, self.__origin + end) if self.__rectangle is not None: self.__resultant_rectangle = len(self.__rectangle) * [None] for i in range(len(self.__rectangle)): self.__resultant_rectangle[i] = scaleVector( self.__rectangle[i] - self.__origin, self.__scale) + self.__origin if self.__polygon is not None: self.__resultant_polygon = len(self.__polygon) * [None] for i in range(len(self.__polygon)): self.__resultant_polygon[i] = scaleVector( self.__polygon[i] - self.__origin, self.__scale) + self.__origin
def anySegmentsIntersect(lines): S = [] for i in range(len(lines)): if lines[i].start.x > lines[i].end.x or ( lines[i].start.x == lines[i].end.x and lines[i].start.y > lines[i].end.y): end = lines[i].start start = lines[i].end lines[i] = LineSegment(start, end) pt1 = Point(lines[i].start.x, lines[i].start.y, 0) S.append(pt1) pt2 = Point(lines[i].end.x, lines[i].end.y, 1) S.append(pt2) pt1.other_end = pt2 pt2.other_end = pt1 sortedPoints = sorted(S, key=cmp_to_key(compare)) dict = {} for pt in sortedPoints: dict[pt] = Node(pt) T = RedBlackTree() # Step 3 for pt in sortedPoints: nd = dict[pt] # print(T) # print('node : ', nd, '\tp: ', nd.parent.key, '\tl: ', nd.left.key, '\tr: ', nd.right.key) if nd.key.ptype == 0: T.insert(nd) line1 = LineSegment(nd.key, nd.key.other_end) prd = T.predecessor(nd) if prd: line2 = LineSegment(prd.key, prd.key.other_end) if LineSegment.checkSegmentIntersection(line1, line2): return (line1, line2) else: print('pred not found : ', nd) ssc = T.successor(nd) if ssc: line2 = LineSegment(ssc.key, ssc.key.other_end) if LineSegment.checkSegmentIntersection(line1, line2): return (line1, line2) else: print('succ not found : ', nd) if nd.key.ptype == 1: T.delete(dict[nd.key.other_end]) T.insert(nd) prd = T.predecessor(nd) ssc = T.successor(nd) if prd and ssc: line1 = LineSegment(prd.key, prd.key.other_end) line2 = LineSegment(ssc.key, ssc.key.other_end) print(line1, '\t', line2) if LineSegment.checkSegmentIntersection(line1, line2): print('intersect : ', T.size) return (line1, line2) else: print('does not intersect') else: print('prev or succ not found : ', nd) T.delete(nd) return None
def sweepLine(lines): """ Return: lines (LineSegment) Args: lines (LineSegment) find all intersected line pairs """ pq = PriorityQueue() for line in lines: pq.put((line.start.x, line.start.y, 0)) pq.put((line.end.x, line.end.y, 1)) # points = linesToSortedPoints(lines) print(len(points)) for pt in points: print(pt[0], pt[1]) active_lines = AVLTree() intersectedLines = [] for i in range(len(points)): pt = points[i] line1 = pt[2] active_lines.insert((pt[0].y, pt[0].x), line1) if pt[1] == True: if active_lines.count <= 1: continue try: prev = active_lines.prev_key((pt[0].y, pt[0].x)) line2 = active_lines[prev] check = LineSegment.checkSegmentIntersection(line1, line2) print(line1, line2, check) if check: intersectedLines.extend([line1, line2]) except: print(f'{pt[0]} twa da 1!') try: succ = active_lines.succ_key((pt[0].y, pt[0].x)) line2 = active_lines[succ] check = LineSegment.checkSegmentIntersection(line1, line2) print(line1, line2, check) if check: intersectedLines.extend([line1, line2]) except: print(f'{pt[0]} twa da 2!') else: if pt[3]: active_lines.remove((pt[2].end.y, pt[2].end.x)) else: active_lines.remove((pt[2].start.y, pt[2].start.x)) if active_lines.count > 2: try: prev = active_lines.prev_key((pt[0].y, pt[0].x)) line1 = active_lines[prev] try: succ = active_lines.succ_key((pt[0].y, pt[0].x)) line2 = active_lines[succ] check = LineSegment.checkSegmentIntersection( line1, line2) print(line1, line2, check) if check: intersectedLines.extend([line1, line2]) except: print(f'{pt[0]} twa da 3!') except: print(f'{pt[0]} twa da 4!') active_lines.remove((pt[0].y, pt[0].x)) print(f'active lines : {active_lines.count}') active_lines.clear() return intersectedLines