Example #1
0
    def closest_in_cell(self, vector):
        """
            Return the closest object to the passed vector in vectors cell.
        """
        objs = self.all_in_cell(vector)

        if not objs:
            return None

        return min(objs, key=lambda o: euclidean_dist_square(vector, o.vector))
Example #2
0
    def closest_in_cell(self, vector):
        """
            Return the closest object to the passed vector in vectors cell.
        """
        objs = self.all_in_cell(vector)

        if not objs:
            return None

        return min(objs, key=lambda o: euclidean_dist_square(vector, o.vector))
Example #3
0
def _closest_path(segments, point, paths_dict, order_path):
    min_path, min_point, min_point_id, min_d, min_segment = None, None, None, None, None
    for segment in segments:
        path = paths_dict[segment[0]]
        point_id = None
        if _is_closed_segment(segment):
            # segment
            p, d, point_id = closest_point_on_edge(path[segment[1]],
                                                   path[segment[2]], point)
        else:
            # point
            p = path[segment[1]]
            d = euclidean_dist_square(p, point)
        if min_d is None or d < min_d:
            min_path, min_point, min_d, min_segment, min_point_id = path, p, d, segment, point_id

    if order_path:
        if _is_closed_segment(min_segment):
            if min_point_id is 2:
                # order contour so that the projection point is the starting point
                min_path = np.concatenate(
                    (to_ndarray([min_point]), min_path[min_segment[2]:],
                     min_path[:min_segment[2]]))
            else:
                # closest point is part of the path, rotate the path
                # around that point
                if min_segment[1] is 0:
                    # proper contour start, do nothing
                    pass
                else:
                    min_path = np.roll(min_path,
                                       min_segment[min_point_id],
                                       axis=0)

        elif min_segment[1] < 0:
            # reverse open path if it ends on the end point denoted as -1
            min_path = min_path[::-1]

    return min_path, min_segment[0]
def _closest_path(segments, point, paths_dict, order_path):
    min_path, min_point, min_point_id, min_d, min_segment = None, None, None, None, None
    for segment in segments:
        path = paths_dict[segment[0]]
        point_id = None
        if _is_closed_segment(segment):
            # segment
            p, d, point_id = closest_point_on_edge(path[segment[1]], path[segment[2]], point)
        else:
            # point
            p = path[segment[1]]
            d = euclidean_dist_square(p, point)
        if min_d is None or d < min_d:
            min_path, min_point, min_d, min_segment, min_point_id = path, p, d, segment, point_id

    if order_path:
        if _is_closed_segment(min_segment):
            if min_point_id is 2:
                # order contour so that the projection point is the starting point
                min_path = np.concatenate((to_ndarray([min_point]),
                                           min_path[min_segment[2]:],
                                           min_path[:min_segment[2]]))
            else:
                # closest point is part of the path, rotate the path
                # around that point
                if min_segment[1] is 0:
                    # proper contour start, do nothing
                    pass
                else:
                    min_path = np.roll(min_path, min_segment[min_point_id], axis=0)

        elif min_segment[1] < 0:
            # reverse open path if it ends on the end point denoted as -1
            min_path = min_path[::-1]

    return min_path, min_segment[0]
Example #5
0
def _connect_lines(lines, delta, theta, center, max_connection_dist):
    # lines are np arrays of np arrays tha represent vertices
    connected_lines = []

    # lines should be aligned left-right and be parallel to X-axis
    lines_by_y = {}
    d_lines = []
    for line in lines:

        # align left to right
        if line[0][0] > line[-1][0]:
            line = line[::-1]

        # line should be a list of np arrays that represent vertices
        line = list(line)
        d_lines.append(line)
        lines_by_y.setdefault(line[0][1], []).append(line)

    y_positions = sorted(lines_by_y.keys())
    dist_squared = max_connection_dist ** 2

    while len(lines_by_y) > 0:
        prev_y = y_positions[0]

        # line has to be a list, not a np array
        # because points will be added to it
        line = lines_by_y[prev_y].pop()

        # used y-positions to be removed from line collections
        used_ys = [prev_y]

        for y in y_positions[1:]:
            if not prev_y < y < prev_y + (2 * delta):  # > prev_y and np.isclose(y, prev_y + delta):
                break

            # find if any of lines at the next y is close enough to connect
            next_line_connection_side = 0 if ((len(line) % 4) is 0) else -1
            current_line_connection_vertex = line[-1]

            for line_idx, l in enumerate(lines_by_y[y]):
                next_line_vertex = l[next_line_connection_side]

                # TODO: maybe do a clip in the square between points and if resulting number of polygons
                # is 1 than we cont need the euclidean dist -> just put that polygon into line
                if euclidean_dist_square(current_line_connection_vertex, next_line_vertex) < dist_squared:

                    del lines_by_y[y][line_idx]
                    used_ys.append(y)

                    # properly orient the line
                    if next_line_connection_side is -1:
                        l = l[::-1]
                    line.extend(list(l))

                    # go for next y position
                    break

            prev_y = y

        for y in used_ys:
            if len(lines_by_y[y]) is 0:
                del lines_by_y[y]
                y_positions.remove(y)

        # convert back to np array
        connected_lines.append(rotate_xy(to_ndarray(line), theta, center))
    return connected_lines