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 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 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
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 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