Exemple #1
0
    def do_intersect(self, s_2: 'Vector') -> bool:

        # orientation of the (self.tail, self.head, s_2.tail) triangle
        s_1_orientation_tail = Point.orientation(self.tail, self.head,
                                                 s_2.tail)

        # orientation of the (self.tail, self.head, s_2.head) triangle
        s_1_orientation_head = Point.orientation(self.tail, self.head,
                                                 s_2.head)

        # orientation of the (s_2.tail, s_2.head, self.tail) triangle
        s_2_orientation_tail = Point.orientation(s_2.tail, s_2.head, self.tail)

        # orientation of the (s_2.tail, s_2.head, self.head) triangle
        s_2_orientation_head = Point.orientation(s_2.tail, s_2.head, self.head)

        # general case
        if s_1_orientation_tail != s_1_orientation_head and s_2_orientation_tail != s_2_orientation_head:
            return True

        # collinear case
        if s_1_orientation_tail == 0 and s_1_orientation_head == 0 and s_2_orientation_tail == 0 and s_2_orientation_head == 0:

            if self.tail.between(s_2.head, s_2.tail) or self.head.between(s_2.head, s_2.tail) \
                    or s_2.tail.between(self.head, self.tail) or s_2.head.between(self.head, self.tail):
                return True

        return False
def find_centroid(vertices: list) -> Point:

    centroid: 'Point' = Point()

    for v in vertices:
        centroid += Point(*v)

    return centroid / len(vertices)
def convex_hull_incremental(vertices: list) -> list:

    hull = list(orientate_vertices(vertices[0], vertices[1], vertices[2]))

    for i in range(3, len(vertices)):

        p_i = Point(*vertices[i])

        if not p_i.in_poly(hull):
            union_point_poly(hull, vertices[i])

    return hull
def convex_hull_graham_scan(vertices: list) -> list:

    vertices = simple_poly(vertices)
    hull = vertices[:2]

    for v in vertices[2:]:

        # edge case if only one point is in hull
        while len(hull) > 1 and Point.orientation(
                Point(*hull[-2]), Point(*hull[-1]), Point(*v)) < 0:
            hull.pop()

        hull.append(v)

    return hull
Exemple #5
0
def orientate_edges(edges):

    centroid = find_centroid()

    for e in edges:

        if Point.orientation(*e, centroid) < 0:
            e[1], e[0] = e[0], e[1]
def get_hull_edges(vertices: list) -> list:

    size: int = len(vertices)
    edges = []
    fail_flag = -2

    for i in range(size - 1):
        for j in range(i + 1, size):

            current_orientation = None

            for v in vertices:

                if v == vertices[i] or v == vertices[j]:
                    continue

                orientation = Point.orientation(Point(*vertices[i]),
                                                Point(*vertices[j]), Point(*v))

                if orientation == 0:
                    continue

                if current_orientation is None:
                    current_orientation = orientation
                    continue

                if current_orientation != orientation:
                    current_orientation = fail_flag
                    break

            if current_orientation is None or current_orientation == fail_flag:
                continue

            if current_orientation == -1:
                edges.append((vertices[i], vertices[j]))

            else:
                edges.append((vertices[j], vertices[i]))

    return edges
def convex_hull_quad(vertices: list) -> list:

    hull = []

    for l in vertices:

        p_l = Point(l[0], l[1])
        is_in_hull = True

        for i in range(len(vertices) - 2):
            p_i = Point(vertices[i][0], vertices[i][1])

            for j in range(i + 1, len(vertices) - 1):
                p_j = Point(vertices[j][0], vertices[j][1])

                for k in range(j + 1, len(vertices)):
                    p_k = Point(vertices[k][0], vertices[k][1])

                    if p_i == p_l or p_j == p_l or p_k == p_l:
                        continue

                    if p_l.in_triangle(p_i, p_j, p_k):
                        is_in_hull = False
                        break

                if not is_in_hull:
                    break

            if not is_in_hull:
                break

        if is_in_hull:
            hull.append(l)

    return simple_poly(hull)
def sort_hull(edges: list) -> None:

    for i in range(len(edges) - 1):

        for j in range(i + 1, len(edges)):

            if edges[i][1] == edges[j][0]:

                if i + 1 != j:
                    edges[i + 1], edges[j] = edges[j], edges[i + 1]

                break

    i = 0

    while i < len(edges) - 1:

        current_v = edges[i]
        j = (i + 1) % len(edges)

        while j < len(edges):

            next_v = edges[j % len(edges)]

            if current_v[0] == next_v[0]:

                if Point.distance(current_v[0], current_v[1]) > Point.distance(
                        next_v[0], next_v[1]):
                    edges.remove(edges[i])

                else:
                    edges.remove(edges[j % len(edges)])

            else:
                j += 1

        i += 1

    return None
def convex_hull_jarvis_march(vertices: list) -> list:

    i: int = get_point_index(vertices, x=True, max_x=False, max_y=False)
    vertices[0], vertices[i] = vertices[i], vertices[0]

    vec = Vector(Point(*vertices[0]), Point(vertices[0][0],
                                            vertices[0][1] + 1))
    j = vertices.index(
        min(vertices,
            key=lambda x: vec.angle_between(
                Vector(Point(*vertices[0]), Point(*x)))))
    vertices[1], vertices[j] = vertices[j], vertices[1]

    vertices.append(vertices[0])
    hull_size = 2
    vec.tail = Point(*vertices[1])

    while True:

        vec.head = vec.tail
        vec.tail = Point(*vertices[hull_size])
        k = hull_size
        min_dist = vec.head.distance(vec.tail)

        for j in range(hull_size, len(vertices)):

            p_j = Point(*vertices[j])
            ori = Point.orientation(vec.head, vec.tail, p_j)
            curr_dist = vec.tail.distance(p_j)

            if ori > 0:
                k = j
                vec.tail = p_j

            elif ori == 0 and curr_dist < min_dist:
                k = j
                vec.tail = p_j
                min_dist = curr_dist

        if vertices[k] == vertices[0]:
            break

        else:
            vertices[hull_size], vertices[k] = vertices[k], vertices[hull_size]
            hull_size += 1

    vertices.pop()
    return vertices[:hull_size]
def find_closest_point_index(vertices: list, p: tuple) -> int:

    min_dist_index: int = 0
    min_dist = Point.distance(Point(*vertices[0]), Point(*p))

    for i in range(1, len(vertices)):

        current_distance = Point.distance(Point(*vertices[i]), Point(*p))

        if current_distance < min_dist:
            min_dist_index = i
            min_dist = current_distance

    return min_dist_index
Exemple #11
0
def simple_poly(vertices: list) -> list:

    # find point with min y and max x coordinates
    index = vertices.index(min(vertices, key=lambda x: (x[1], -x[0])))

    # swap with first point
    vertices[0], vertices[index] = vertices[index], vertices[0]

    vertices = sorted(vertices,
                      key=lambda x:
                      (Vector(Point(*vertices[0]), Point(*x)).slope(),
                       Point(*vertices[0]).euclidean_distance(Point(*x))))

    bottom_most = Point(*vertices[0])

    k = -1

    while Point(*vertices[k]) != bottom_most and \
        Vector(bottom_most, Point(*vertices[k])).slope() == Vector(bottom_most, Point(*vertices[k-1])).slope():

        k -= 1

    return vertices[:k] + vertices[:len(vertices) + k - 1:-1]
Exemple #12
0
    def orientation_vector(self):

        direction_vector: Point = self.direction_vector()
        return Point(direction_vector.y, -direction_vector.x)