def test_create_point_from_point(self):
     '''Test Point constructor when cloning another point'''
     oldpnt = Point(2, 3)
     newpnt = Point(oldpnt)
     self.assertFalse(oldpnt is newpnt)
     self.assertEqual(oldpnt.x, newpnt.x)
     self.assertEqual(oldpnt.y, newpnt.y)
     oldpnt.x = 4
     oldpnt.y = 5
     self.assertEqual(newpnt.x, 2)
     self.assertEqual(newpnt.y, 3)
class Pin:
    """ Pins are the parts of Bodies (/symbols/components) that connect
    to nets. Basically a line segment, with a null end and a connect end
    """

    def __init__(self, pin_number, p1, p2, label=None):
        self.label = label # is a Label
        self.p1 = Point(p1) # null end
        self.p2 = Point(p2) # connect end
        self.pin_number = pin_number
        self.attributes = dict()


    def add_attribute(self, key, value):
        """ Add attribute to a pin """
        self.attributes[key] = value


    def bounds(self):
        """ Return the min and max points of a pin """
        x_values = [self.p1.x, self.p2.x]
        y_values = [self.p1.y, self.p2.y]
        if self.label is not None:
            x_values.extend([pt.x for pt in self.label.bounds()])
            y_values.extend([pt.y for pt in self.label.bounds()])
        return [Point(min(x_values), min(y_values)),
                Point(max(x_values), max(y_values))]


    def json(self):
        """ Return a pin as JSON """
        ret = {
            "pin_number":self.pin_number,
            "p1":self.p1.json(),
            "p2":self.p2.json(),
            "attributes" : self.attributes,
            }
        if self.label is not None:
            ret["label"] = self.label.json()
        return ret
    def _get_ctr_and_radius(self, end_pts, offset):
        """ Apply gerber circular interpolation logic. """
        start, end = end_pts
        radius = sqrt(offset['i']**2 + offset['j']**2)
        center = Point(x=start.x + offset['i'],
                       y=start.y + offset['j'])

        # In single-quadrant mode, gerber requires implicit
        # determination of offset direction, so we find the
        # center through trial and error.
        if not self.status['multi_quadrant']:
            if not snap(center.dist(end), radius):
                center = Point(x=start.x - offset['i'],
                               y=start.y - offset['j'])
                if not snap(center.dist(end), radius):
                    center = Point(x=start.x + offset['i'],
                                   y=start.y - offset['j'])
                    if not snap(center.dist(end), radius):
                        center = Point(x=start.x - offset['i'],
                                       y=start.y + offset['j'])
                        if not snap(center.dist(end), radius):
                            raise ImpossibleGeometry
        return (center, radius)
def run_task_01():
    """
    Run task 1.
    Open a window and display the first image.
    """

    logger.info('Task 1 started')

    # variables to drag a rectangle contour
    dragging_contour = False
    current_dragging_contour = None
    current_dragging_contour_id = None

    # variables to drag a quadrilateral by dragging its points
    dragging_quadrilateral = False
    current_dragging_quadrilateral = None
    current_dragging_quadrilateral_figure = None
    dragging_corner_point = None
    all_quadrilaterals = []
    all_quadrilateral_figures = []

    # the current selected action
    current_action = "add"

    # the previous event (used for active buttons)
    previous_event = "Add"

    # read all filenames
    filenames = glob('./datasets/images/dataset_pictures_msk/zaal_*/*.jpg')

    # the layout of the window
    layout = [[
        sg.Text(
            'Add, remove and modify contours in the displayed images by using the provided actions.',
            font=('Helvetica', 12, ''))
    ],
              [
                  sg.Button('Add', font=('Helvetica', 10, '')),
                  sg.Button('Remove', font=('Helvetica', 10, '')),
                  sg.Button('Draw', font=('Helvetica', 10, '')),
                  sg.Button('Drag', font=('Helvetica', 10, '')),
                  sg.Button('Convert', font=('Helvetica', 10, '')),
                  sg.Button('Clear canvas', font=('Helvetica', 10, '')),
                  sg.Button('Save to database', font=('Helvetica', 10, '')),
                  sg.Button('Next image', font=('Helvetica', 10, '')),
                  sg.StatusBar('---/---',
                               key='file_counter',
                               font=('Helvetica', 12, '')),
              ],
              [
                  sg.Frame('Image', [[
                      sg.Graph(
                          canvas_size=graph_size,
                          graph_bottom_left=(0, graph_size[1]),
                          graph_top_right=(graph_size[0], 0),
                          key="graph",
                          pad=None,
                          enable_events=True,
                          drag_submits=True,
                      )
                  ]])
              ]]

    # close the window if no filenames could be found
    if len(filenames) != 0:
        window = get_window("Task 1", layout)
        graph = window.Element("graph")
    else:
        return

    visible_contours = []
    file_counter = 0
    # display the first image
    invisible_contours, filepath, img_shape, img = show_next_image(
        graph, filenames, file_counter)
    room = get_room_from_file(filepath)

    window.FindElement("file_counter").Update(
        value=(str(file_counter + 1) + "/" + str(len(filenames))))

    logger.info('Starting event loop of task 1')

    # show to the user the active button ('Add' on start)
    toggle_active_button(window, previous_event, 'Add')

    # the event loop
    while True:
        event, values = window.Read()
        if values is not None:
            point = Point(values["graph"][0], values["graph"][1])

        if (event is not None and event in ('Add', 'Remove', 'Draw', 'Drag')):
            toggle_active_button(window, previous_event, event)
            previous_event = event

        # button click events
        if event == "Add":
            current_action = "add"
        if event == "Remove":
            current_action = "remove"
        if event == "Draw":
            current_action = "draw"
        if event == "Drag":
            current_action = "drag"
        if event == "Convert":
            all_quadrilateral_figures = on_convert_contours_event(
                graph, visible_contours, invisible_contours,
                all_quadrilaterals, all_quadrilateral_figures)
            visible_contours = []
        if event == "Clear canvas":
            graph.erase()
            invisible_contours, filepath, img_shape, img = show_next_image(
                graph, filenames, file_counter)
            room = get_room_from_file(filepath)
            all_quadrilaterals = []
            all_quadrilateral_figures = []

        if event == "Save to database":
            for quadrilateral in all_quadrilaterals:
                x1 = quadrilateral.TLPoint.x
                y1 = quadrilateral.TLPoint.y
                x2 = quadrilateral.TRPoint.x
                y2 = quadrilateral.TRPoint.y
                x3 = quadrilateral.BRPoint.x
                y3 = quadrilateral.BRPoint.y
                x4 = quadrilateral.BLPoint.x
                y4 = quadrilateral.BLPoint.y

                # sort the corners on y-coordinate, then on x: order will be TL, TR, BL, BR
                # and map to a percentage in the painting
                uniform_corners = convert_corners_to_uniform_format([
                    [x1, y1],
                    [x2, y2],
                    [x3, y3],
                    [x4, y4],
                ], img_shape[0], img_shape[1])
                uniform_corners = sort_corners(uniform_corners)

                full_histogram, block_histogram, LBP_histogram = extract_features(
                    img, uniform_corners, False)

                image = {
                    'filename': basename(filepath),
                    'corners': uniform_corners,
                    'room': room,
                    'full_histogram': full_histogram,
                    'block_histogram': block_histogram,
                    'LBP_histogram': LBP_histogram
                }

                create_image(image)

        if event in ("Next image", "Save to database"):
            if len(filenames) == 0:
                window.close()
                return

            visible_contours = []
            file_counter += 1
            invisible_contours, filepath, img_shape, img = show_next_image(
                graph, filenames, file_counter)
            room = get_room_from_file(filepath)
            if invisible_contours is None:
                break

            window.FindElement("file_counter").Update(
                value=(str(file_counter + 1) + "/" + str(len(filenames))))

            # make add again the current action
            toggle_active_button(window, previous_event, 'Add')
            previous_event = 'Add'
            current_action = 'add'

            all_quadrilaterals = []
            all_quadrilateral_figures = []

        # the canvas (graph) events
        if event == "graph":
            if current_action == "add":
                on_add_contour_event(point, graph, visible_contours,
                                     invisible_contours)

            if current_action == "remove":
                on_remove_contour_event(point, graph, visible_contours,
                                        invisible_contours)

            if current_action == "draw":
                dragging_contour, current_dragging_contour, current_dragging_contour_id = on_draw_event(
                    point, graph, dragging_contour, current_dragging_contour,
                    current_dragging_contour_id)

            if current_action == "drag":
                dragging_quadrilateral, all_quadrilaterals, all_quadrilateral_figures, dragging_corner_point = on_drag_event(
                    point, graph, dragging_quadrilateral,
                    dragging_corner_point, all_quadrilaterals,
                    all_quadrilateral_figures)

        if event == "graph+UP" and current_action == "draw":
            dragging_contour, current_dragging_contour, current_dragging_contour_id, visible_contours = on_draw_done_event(
                point, graph, dragging_contour, current_dragging_contour,
                current_dragging_contour_id, visible_contours)

        if event == "graph+UP" and current_action == "drag":
            dragging_quadrilateral, current_dragging_quadrilateral, current_dragging_quadrilateral_figure, dragging_corner_point = on_drag_done_event(
                dragging_quadrilateral, current_dragging_quadrilateral,
                current_dragging_quadrilateral_figure, dragging_corner_point)

        if event == None:
            break

    window.close()
 def __init__(self, pin_number, p1, p2, label=None):
     self.label = label # is a Label
     self.p1 = Point(p1) # null end
     self.p2 = Point(p2) # connect end
     self.pin_number = pin_number
     self.attributes = dict()