def __init__(self, gui_manager): super().__init__(gui_manager) self.__lines = [] self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__resultant_lines = [] self.__status_text = 'Sweep Line: '
def __init__(self, gui_manager): super().__init__(gui_manager) self.__polygon = [] self.__clip_window = [] self.__cliping_points = [] self.__draw_clip_window = False self.__drawing_polygon = False self.__status_text = 'Polygon Clipping: ' self.__mouse = Mouse( Vector2(pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__show_only_cliping_polygon = False
def __init__(self, gui_manager): super().__init__(gui_manager) self.__line1 = None self.__line2 = None self.__status_text = 'Line Intersection : ' self.__intersection_point = None self.__line_id = 0 self.__start_pos = Vector2(0, 0) self.__end_pos = Vector2(0, 0) self.__mouse = Mouse( Vector2(pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1]))
def __init__(self, gui_manager): super().__init__(gui_manager) self.__grid_size = Vector2(20, 20) width = Renderer.getInstance().surface.get_width() height = Renderer.getInstance().surface.get_height() self.__origin = Vector2(width // 2, height // 2) self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__mat = [1, 0, 0, 1] self.__idx = 0
def __initialize(self): self.__polygon1 = [] self.__polygon2 = [] self.__status_text = 'Minkowski Sum :' self.__minkowski_polygon = [] self.__first_polygon = True self.__draw_polygon1 = False self.__draw_polygon2 = False self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1]))
def __init__(self, gui_manager): super().__init__(gui_manager) self.__object_types = [ TransformationView.LINE_TEXT, TransformationView.RECTANGLE_TEXT, TransformationView.POLYGON_TEXT ] self.__origin = Vector2(0, 0) self.__rotation = 0 self.__draw_object = False self.__line = None self.__rectangle = None self.__polygon = None self.__resultant_line = None self.__resultant_rectangle = None self.__resultant_polygon = None self.__status_text = 'Transformation: ' self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) screen_width = Renderer.getInstance().surface.get_width() self.__drop_down = pg_gui.elements.UIDropDownMenu( self.__object_types, TransformationView.LINE_TEXT, Rect(screen_width - 160, 10, 150, 40), self._gui_manager) self.__angle_input = pg_gui.elements.UITextEntryLine( Rect(screen_width - 50, 60, 60, 30), self._gui_manager) allow_chars = pg_gui.elements.UITextEntryLine._number_character_set allow_chars.append('-') self.__angle_input.set_allowed_characters(allow_chars) self.hideUI()
class LineIntersectionView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__line1 = None self.__line2 = None self.__status_text = 'Line Intersection : ' self.__intersection_point = None self.__line_id = 0 self.__start_pos = Vector2(0, 0) self.__end_pos = Vector2(0, 0) self.__mouse = Mouse( Vector2(pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) 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) 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 render(self, debug=False): if self.__mouse.leftDrag: Renderer.getInstance().renderLine(self.__start_pos, self.__mouse.position) if self.__line1 is not None: Renderer.getInstance().renderLine(self.__line1.start, self.__line1.end) Renderer.getInstance().renderText('A', self.__line1.start - Vector2(0, 10)) Renderer.getInstance().renderText('B', self.__line1.end - Vector2(0, 10)) if self.__line2 is not None: Renderer.getInstance().renderLine(self.__line2.start, self.__line2.end) Renderer.getInstance().renderText('C', self.__line2.start - Vector2(0, 10)) Renderer.getInstance().renderText('D', self.__line2.end - Vector2(0, 10)) if self.__intersection_point is not None: Renderer.getInstance().renderCircle( self.__intersection_point, 3, color=(128, 128, 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) if self.__line_id == 0: Renderer.getInstance().renderText('Draw AB line. Scroll to change line drawing.', Vector2( Renderer.getInstance().surface.get_width()//2, 15), font_size=18) elif self.__line_id == 1: Renderer.getInstance().renderText('Draw CD line. Scroll to change line drawing.', Vector2( Renderer.getInstance().surface.get_width()//2, 15), font_size=18)
class SutherlandHodgmanView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__polygon = [] self.__clip_window = [] self.__cliping_points = [] self.__draw_clip_window = False self.__drawing_polygon = False self.__status_text = 'Polygon Clipping: ' self.__mouse = Mouse( Vector2(pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__show_only_cliping_polygon = False def __calculateCliping(self): if len(self.__polygon) < 3: return if len(self.__clip_window) < 3: return self.__cliping_points = sutherlandHodgman( self.__polygon, self.__clip_window) 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_s: self.__show_only_cliping_polygon = not self.__show_only_cliping_polygon if event.key == pg.K_d and not self.__draw_clip_window: self.__drawing_polygon = not self.__drawing_polygon if self.__drawing_polygon: self.__clip_window = [] self.__cliping_points = [] self.__polygon = [ self.__mouse.position, self.__mouse.position] else: if len(self.__polygon) > 0: self.__polygon.pop() if self.__mouse.leftDownClick: if self.__drawing_polygon: self.__polygon[-1] = self.__mouse.position self.__polygon.append(self.__mouse.position) if self.__draw_clip_window: self.__clip_window = [ self.__mouse.position, self.__mouse.position, self.__mouse.position, self.__mouse.position] elif self.__mouse.leftUpClick: self.__calculateCliping() elif self.__mouse.scrollUp or self.__mouse.scrollDown: self.__draw_clip_window = not self.__draw_clip_window self.__drawing_polygon = False def render(self, debug=False): if self.__drawing_polygon and not self.__draw_clip_window: self.__polygon[-1] = self.__mouse.position if self.__draw_clip_window: if len(self.__clip_window) > 0 and self.__mouse.leftDrag: p1 = self.__clip_window[0] p2 = Vector2(self.__mouse.position.x, self.__clip_window[0].y) p3 = self.__mouse.position p4 = Vector2(self.__clip_window[0].x, self.__mouse.position.y) self.__clip_window = [p1, p2, p3, p4] if not self.__show_only_cliping_polygon: if len(self.__polygon) > 2: Renderer.getInstance().renderPolygon(self.__polygon) elif len(self.__polygon) == 2: Renderer.getInstance().renderLine( self.__polygon[0], self.__polygon[1]) elif len(self.__polygon) == 1: Renderer.getInstance().renderCircle(self.__polygon[0], 3) if len(self.__clip_window) > 0: Renderer.getInstance().renderPolygon( self.__clip_window, color=(0, 0, 255), alpha=50) if len(self.__cliping_points) > 2: Renderer.getInstance().renderPolygon( self.__cliping_points, color=(255, 0, 0), alpha=128) 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) if self.__draw_clip_window: Renderer.getInstance().renderText('Draw cliping window. Scroll to draw polygon.', Vector2( Renderer.getInstance().surface.get_width()//2, 15), font_size=18) else: Renderer.getInstance().renderText('Draw polygon. Scroll to draw cliping window.', Vector2( Renderer.getInstance().surface.get_width()//2, 15), font_size=18)
class MinkowskiSumView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__initialize() def __initialize(self): self.__polygon1 = [] self.__polygon2 = [] self.__status_text = 'Minkowski Sum :' self.__minkowski_polygon = [] self.__first_polygon = True self.__draw_polygon1 = False self.__draw_polygon2 = False self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) def __calculateMinkowski(self): if len(self.__polygon1) < 3: self.__status_text = 'Minkowski Sum : length of points in polygon1 is less than 3' return if len(self.__polygon2) < 3: self.__status_text = 'Minkowski Sum : length of points in polygon2 is less than 3' return self.__minkowski_polygon = minkowskiSum(self.__polygon1, self.__polygon2) self.__status_text = f'Minkowski Sum : length of polygon {len(self.__minkowski_polygon)}' 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: if self.__first_polygon: self.__draw_polygon2 = False self.__draw_polygon1 = not self.__draw_polygon1 if self.__draw_polygon1: self.__polygon1 = [ self.__mouse.position, self.__mouse.position ] else: if len(self.__polygon1) > 0: self.__polygon1.pop() else: self.__draw_polygon1 = False self.__draw_polygon2 = not self.__draw_polygon2 if self.__draw_polygon2: self.__polygon2 = [ self.__mouse.position, self.__mouse.position ] else: if len(self.__polygon2) > 0: self.__polygon2.pop() self.__calculateMinkowski() if self.__mouse.leftDownClick: if self.__draw_polygon1: self.__polygon1[-1] = self.__mouse.position self.__polygon1.append(self.__mouse.position) elif self.__draw_polygon2: self.__polygon2[-1] = self.__mouse.position self.__polygon2.append(self.__mouse.position) if self.__mouse.scrollUp or self.__mouse.scrollDown: self.__first_polygon = not self.__first_polygon self.__draw_polygon1 = False self.__draw_polygon2 = False def render(self, debug=False): if self.__draw_polygon1: self.__polygon1[-1] = self.__mouse.position if self.__draw_polygon2: self.__polygon2[-1] = self.__mouse.position if len(self.__polygon1) > 2: Renderer.getInstance().renderPolygon(self.__polygon1) elif len(self.__polygon1) == 2: Renderer.getInstance().renderLine(self.__polygon1[0], self.__polygon1[1]) elif len(self.__polygon1) == 1: Renderer.getInstance().renderCircle(self.__polygon1[0], 3) if len(self.__polygon2) > 2: Renderer.getInstance().renderPolygon(self.__polygon2) elif len(self.__polygon2) == 2: Renderer.getInstance().renderLine(self.__polygon2[0], self.__polygon2[1]) elif len(self.__polygon2) == 1: Renderer.getInstance().renderCircle(self.__polygon2[0], 3) if len(self.__minkowski_polygon) > 2: Renderer.getInstance().renderPolygon(self.__minkowski_polygon) 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) if self.__first_polygon: Renderer.getInstance().renderText( 'Draw polygom 1. Scroll to draw next polygon.', Vector2(Renderer.getInstance().surface.get_width() // 2, 15), font_size=18) else: Renderer.getInstance().renderText( 'Draw polygon 2. Scroll to draw next polygon.', Vector2(Renderer.getInstance().surface.get_width() // 2, 15), font_size=18)
class TransformationView(Window): LINE_TEXT = 'Line' RECTANGLE_TEXT = 'Rectangle' POLYGON_TEXT = 'Polygon' def __init__(self, gui_manager): super().__init__(gui_manager) self.__object_types = [ TransformationView.LINE_TEXT, TransformationView.RECTANGLE_TEXT, TransformationView.POLYGON_TEXT ] self.__origin = Vector2(0, 0) self.__rotation = 0 self.__draw_object = False self.__line = None self.__rectangle = None self.__polygon = None self.__resultant_line = None self.__resultant_rectangle = None self.__resultant_polygon = None self.__status_text = 'Transformation: ' self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) screen_width = Renderer.getInstance().surface.get_width() self.__drop_down = pg_gui.elements.UIDropDownMenu( self.__object_types, TransformationView.LINE_TEXT, Rect(screen_width - 160, 10, 150, 40), self._gui_manager) self.__angle_input = pg_gui.elements.UITextEntryLine( Rect(screen_width - 50, 60, 60, 30), self._gui_manager) allow_chars = pg_gui.elements.UITextEntryLine._number_character_set allow_chars.append('-') self.__angle_input.set_allowed_characters(allow_chars) self.hideUI() def __changeDrawStatus(self): self.__draw_object = not self.__draw_object if self.__drop_down.selected_option == TransformationView.POLYGON_TEXT: if self.__draw_object: self.__polygon = [self.__mouse.position, self.__mouse.position] else: if self.__polygon is not None and len(self.__polygon) > 2: self.__polygon.pop() else: self.__polygon = None if self.__draw_object: self.__angle_input.disable() else: self.__angle_input.enable() self.__calculateRotation() def __changeRotation(self, delta_change=None, value=None): if value is None and delta_change is None: return if value is None: self.__rotation += delta_change elif delta_change is None: self.__rotation = value self.__calculateRotation() if self.__angle_input.text != str(self.__rotation): self.__angle_input.set_text(str(self.__rotation)) 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 __calculateRotation(self): self.__status_text = f'Transformation: rotation by {self.__rotation}' if self.__line is not None: start = rotateVector(self.__line.start - self.__origin, self.__rotation) end = rotateVector(self.__line.end - self.__origin, self.__rotation) 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] = rotateVector( self.__rectangle[i] - self.__origin, self.__rotation) + 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] = rotateVector( self.__polygon[i] - self.__origin, self.__rotation) + self.__origin 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.__drop_down.selected_option == TransformationView.POLYGON_TEXT: if self.__draw_object and self.__polygon is not None: self.__polygon[-1] = self.__mouse.position if self.__line is not None: Renderer.getInstance().renderLine(self.__line.start, self.__line.end) if self.__rectangle is not None: Renderer.getInstance().renderPolygon(self.__rectangle, color=(0, 0, 255), alpha=128) if self.__polygon is not None: if len(self.__polygon) > 2: Renderer.getInstance().renderPolygon(self.__polygon, color=(0, 255, 0), alpha=128) elif len(self.__polygon) == 2: Renderer.getInstance().renderLine(self.__polygon[0], self.__polygon[1], color=(0, 255, 0)) elif len(self.__polygon) == 1: Renderer.getInstance().renderCircle(self.__polygon[0], 3, color=(0, 255, 0)) if self.__resultant_line is not None: Renderer.getInstance().renderLine(self.__resultant_line.start, self.__resultant_line.end) if self.__resultant_rectangle is not None: Renderer.getInstance().renderPolygon(self.__resultant_rectangle, color=(0, 0, 255), alpha=128) if self.__resultant_polygon is not None: if len(self.__resultant_polygon) > 2: Renderer.getInstance().renderPolygon(self.__resultant_polygon, color=(0, 255, 0), alpha=128) elif len(self.__resultant_polygon) == 2: Renderer.getInstance().renderLine(self.__resultant_polygon[0], self.__resultant_polygon[1], color=(0, 255, 0)) elif len(self.__resultant_polygon) == 1: Renderer.getInstance().renderCircle( self.__resultant_polygon[0], 3, color=(0, 255, 0)) Renderer.getInstance().renderCircle(self.__origin, 5, color=(255, 255, 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) text = '' if self.__draw_object: if self.__drop_down.selected_option == TransformationView.LINE_TEXT: text = 'Draw Line.' elif self.__drop_down.selected_option == TransformationView.RECTANGLE_TEXT: text = 'Draw Rectangle.' elif self.__drop_down.selected_option == TransformationView.POLYGON_TEXT: text = 'Draw Polygon.' else: text = 'Press \'d\' to draw.' Renderer.getInstance().renderText( text, Vector2(Renderer.getInstance().surface.get_width() // 2, 15), font_size=18) def showUI(self): self.__drop_down.show() self.__angle_input.show() def hideUI(self): self.__drop_down.hide() self.__angle_input.hide() def clear(self): self.__drop_down.kill() self.__angle_input.kill()
class OrientationView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__line = None self.__point = None self.__status_text = 'Orientation : ' self.__start_pos = Vector2(0, 0) self.__end_pos = Vector2(0, 0) self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) def __calculateOrientation(self): if self.__line is not None and self.__point is not None: orient = orientation2d(self.__line.start, self.__line.end, self.__point) if orient == 1: self.__status_text = 'Orientation : point is in anti-clockwise direction.' elif orient == -1: self.__status_text = 'Orientation : point is in clockwise direction.' else: self.__status_text = 'Orientation : point is colinear with line.' else: self.__status_text = 'Orientation : ' 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 render(self, debug=False): if self.__mouse.leftDrag: Renderer.getInstance().renderLine(self.__start_pos, self.__mouse.position) if self.__line is not None: Renderer.getInstance().renderLine(self.__line.start, self.__line.end) Renderer.getInstance().renderCircle(self.__line.start, 3, color=(255, 0, 0)) Renderer.getInstance().renderCircle(self.__line.end, 3, color=(0, 255, 0)) Renderer.getInstance().renderText( 'A', self.__line.start - Vector2(0, 10)) Renderer.getInstance().renderText('B', self.__line.end - Vector2(0, 10)) if self.__point is not None: Renderer.getInstance().renderCircle(self.__point, 3, color=(0, 255, 0)) Renderer.getInstance().renderText('C', self.__point - Vector2(0, 10)) 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)
class SweepLineView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__lines = [] self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__resultant_lines = [] self.__status_text = 'Sweep Line: ' def __calculateSweepLine(self): if platform.system() == 'Linux': os.system('clear') elif platform.system() == 'Windows': os.system('cls') self.__resultant_lines = [] if len(self.__lines) > 1: # res = pairOfIntersectedLineSegment(self.__lines) res = anySegmentsIntersect(self.__lines) if res is not None: self.__resultant_lines = [res[0], res[1]] 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 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)
class LinearTransformationView(Window): def __init__(self, gui_manager): super().__init__(gui_manager) self.__grid_size = Vector2(20, 20) width = Renderer.getInstance().surface.get_width() height = Renderer.getInstance().surface.get_height() self.__origin = Vector2(width // 2, height // 2) self.__mouse = Mouse( Vector2( pg.mouse.get_pos()[0], Renderer.getInstance().surface.get_height() - pg.mouse.get_pos()[1])) self.__mat = [1, 0, 0, 1] self.__idx = 0 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_0: self.__idx = 0 elif event.key == pg.K_1: self.__idx = 1 elif event.key == pg.K_2: self.__idx = 2 if event.key == pg.K_3: self.__idx = 3 if self.__mouse.scrollUp: self.__mat[self.__idx] += 1 elif self.__mouse.scrollDown: self.__mat[self.__idx] -= 1 def __draw_grid(self): width = Renderer.getInstance().surface.get_width() height = Renderer.getInstance().surface.get_height() grid_surface = pg.Surface((width, height)) grid_surface.set_colorkey((0, 0, 0)) grid_surface.set_alpha(75) color = (255, 255, 255) weight = 1 # left vertical lines x = self.__origin.x while True: x -= self.__grid_size.x start = Vector2(x, -10) end = Vector2(x, 2 * self.__origin.y + 10) pg.draw.line(grid_surface, color, start, end, weight) if x < 0: break # origin vertical line start = Vector2(self.__origin.x, -10) end = Vector2(self.__origin.x, 2 * self.__origin.y + 10) pg.draw.line(grid_surface, color, start, end, 2) # right vertical lines x = self.__origin.x while True: x += self.__grid_size.x start = Vector2(x, -10) end = Vector2(x, 2 * self.__origin.y + 10) pg.draw.line(grid_surface, color, start, end, weight) if x > 2 * self.__origin.x: break # bottom horizontal lines y = self.__origin.y while True: y -= self.__grid_size.y start = Vector2(-10, y) end = Vector2(2 * self.__origin.x + 10, y) pg.draw.line(grid_surface, color, start, end, weight) if y < 0: break # origin horizontal line start = Vector2(-10, self.__origin.y) end = Vector2(2 * self.__origin.x + 10, self.__origin.y) pg.draw.line(grid_surface, color, start, end, 2) # upper horizontal lines y = self.__origin.y while True: y += self.__grid_size.y start = Vector2(-10, y) end = Vector2(2 * self.__origin.x + 10, y) pg.draw.line(grid_surface, color, start, end, weight) if y > 2 * self.__origin.y: break Renderer.getInstance().surface.blit(grid_surface, (0, 0)) def __draw_transform_grid(self, i_hat, j_hat): width = Renderer.getInstance().surface.get_width() height = Renderer.getInstance().surface.get_height() grid_surface = pg.Surface((width, height)) grid_surface.set_colorkey((0, 0, 0)) grid_surface.set_alpha(128) diag_distance = math.sqrt(width * width + height * height) half_diag_distance = diag_distance // 2 + 5 screen_i_hat = self.__convertPointToScreenPos(i_hat) screen_j_hat = self.__convertPointToScreenPos(j_hat) weight = 1 # parallel j_hat lines color = (0, 0, 255) # origin j_hat line start = self.__origin - j_hat * half_diag_distance end = self.__origin + j_hat * half_diag_distance screen_pos_start = Vector2(start.x, height - start.y) screen_pos_end = Vector2(end.x, height - end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, 2) sqrt = math.sqrt(screen_i_hat.x * screen_i_hat.x + screen_i_hat.y * screen_i_hat.y) if sqrt != 0: cnt = math.ceil(half_diag_distance / sqrt) up_start = Vector2(start.x, start.y) up_end = Vector2(end.x, end.y) down_start = Vector2(start.x, start.y) down_end = Vector2(end.x, end.y) for i in range(1, cnt + 1): up_start += screen_i_hat up_end += screen_i_hat screen_pos_start = Vector2(up_start.x, height - up_start.y) screen_pos_end = Vector2(up_end.x, height - up_end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, weight) down_start -= screen_i_hat down_end -= screen_i_hat screen_pos_start = Vector2(down_start.x, height - down_start.y) screen_pos_end = Vector2(down_end.x, height - down_end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, weight) # parrallel i_hat lines color = (0, 255, 0) # origin i_hat line start = self.__origin - i_hat * half_diag_distance end = self.__origin + i_hat * half_diag_distance screen_pos_start = Vector2(start.x, height - start.y) screen_pos_end = Vector2(end.x, height - end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, 2) sqrt = math.sqrt(screen_j_hat.x * screen_j_hat.x + screen_j_hat.y * screen_j_hat.y) if sqrt != 0: cnt = math.ceil(half_diag_distance / sqrt) up_start = Vector2(start.x, start.y) up_end = Vector2(end.x, end.y) down_start = Vector2(start.x, start.y) down_end = Vector2(end.x, end.y) for i in range(0, cnt): up_start += screen_j_hat up_end += screen_j_hat screen_pos_start = Vector2(up_start.x, height - up_start.y) screen_pos_end = Vector2(up_end.x, height - up_end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, weight) down_start -= screen_j_hat down_end -= screen_j_hat screen_pos_start = Vector2(down_start.x, height - down_start.y) screen_pos_end = Vector2(down_end.x, height - down_end.y) pg.draw.line(grid_surface, color, screen_pos_start, screen_pos_end, weight) Renderer.getInstance().surface.blit(grid_surface, (0, 0)) def __convertPointToScreenPos(self, position): return Vector2(position.x * self.__grid_size.x, position.y * self.__grid_size.y) def __screenPosToPoint(self, position): return Vector2(position.x // self.__grid_size.x, position.y // self.__grid_size.y) def render(self, debug=False): self.__draw_grid() pt = Vector2(1, 5) screen_pos = self.__convertPointToScreenPos(pt) Renderer.getInstance().renderCircle(self.__origin + screen_pos, 3) i_hat = Vector2(self.__mat[0], self.__mat[1]) j_hat = Vector2(self.__mat[2], self.__mat[3]) self.__draw_transform_grid(i_hat, j_hat) screen_pos = self.__convertPointToScreenPos( Vector2(pt.x * i_hat.x + pt.y * j_hat.x, pt.x * i_hat.y + pt.y * j_hat.y)) Renderer.getInstance().renderCircle(self.__origin + screen_pos, 3, color=(0, 0, 255)) Renderer.getInstance().renderText(f'i hat: ({i_hat.x},{i_hat.y})', Vector2(150, 20)) Renderer.getInstance().renderText(f'j hat: ({j_hat.x},{j_hat.y})', Vector2(500, 20))