Esempio n. 1
0
 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
Esempio n. 3
0
    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
Esempio n. 5
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()
Esempio n. 7
0
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)
Esempio n. 9
0
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)
Esempio n. 12
0
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))