def intersecting(pa, pb, qa, qb): """Returns how two segment defined by p and q are intersecting with each other. It is assumed that a bounding box check has been performed for the two segments and that these boxes *do* overlap! Call intersection() to get the location of intersection. """ a = orient2d(pa, pb, qa) b = orient2d(pa, pb, qb) if (a > 0 and b > 0) or (a < 0 and b < 0): return NOT_INTERSECTING c = orient2d(qa, qb, pa) d = orient2d(qa, qb, pb) if (c > 0 and d > 0) or (c < 0 and d < 0): return NOT_INTERSECTING if a == 0.0 and b == 0.0 and c == 0.0 and d == 0.0: nume_a = 1.0 * ((qb[0] - qa[0]) * (pa[1] - qa[1])) - ( (qb[1] - qa[1]) * (pa[0] - qa[0]) ) nume_b = 1.0 * ((pb[0] - pa[0]) * (pa[1] - qa[1])) - ( (pb[1] - pa[1]) * (pa[0] - qa[0]) ) if nume_a == 0.0 and nume_b == 0.0: return COINCIDENT return PARALLEL if a == 0 or b == 0 or c == 0 or d == 0: return INTERSECTING_AT_END return INTERSECTING
def is_on_left_if_equal_shewchuk(target_point_x: int, target_point_y:int, node_that_equal: Dot, node_idx)\ -> bool: prev_point = vis.polygon_dots[node_idx-1] next_point = vis.polygon_dots[(node_idx+1) % len(vis.polygon_dots)] return np.sign(orient2d((target_point_x, target_point_y), node_that_equal.get_tuple(), prev_point.get_tuple())) \ * np.sign(orient2d((target_point_x, target_point_y), node_that_equal.get_tuple(), next_point.get_tuple())) < 0
def is_on_left_by_func_shewchuk(point_x: int, point_y: int, prev_node: Dot, cur_node: Dot, cur_node_idx: int) -> bool: if prev_node.x != cur_node.x: if prev_node.y < cur_node.y: is_fit_func = orient2d(prev_node.get_tuple(), cur_node.get_tuple(), (point_x, point_y)) >= 0 else: is_fit_func = orient2d(cur_node.get_tuple(), prev_node.get_tuple(), (point_x, point_y)) >= 0 else: is_fit_func = True return (is_fit_func and point_y != prev_node.y)\ and (point_y != cur_node.y or is_on_left_if_equal_shewchuk(point_x, point_y, cur_node, cur_node_idx))
def orientation(point, polygon, st, dr): i1, i2 = binary_search(point, polygon, st, dr) inf_orientation = orient2d(polygon[i1], polygon[i2], point) if inf_orientation < 0: return "outside" elif inf_orientation == 0: return "on egde" i1, i2 = binary_search(point, polygon, dr, st, type="sup") sup_orientation = orient2d(polygon[i1], polygon[i2], point) if sup_orientation < 0: return "outside" elif sup_orientation > 0: return "inside"
def test_bigvalues(): C = int(2e17) for i in range(0, 2048): ra = orient2d((0+C,0+C), (15+C, pow(10, -i)+C), (25+C,0+C)) fa = determinant(0+C,0+C, 15+C, pow(10, -i)+C, 25+C, 0+C) try: assert ra == fa except AssertionError: print(ra, "<>", fa, i, C)
def test_orient2d(self): assert orient2d([0.1, 0.1], [0.1, 0.1], [0.3, 0.7]) == 0 assert orient2d([0, 0], [-1e-64, 0], [0, 1]) < 0 assert orient2d([0, 0], [1e-64, 1e-64], [1, 1]) == 0 assert orient2d([0, 0], [1e-64, 0], [0, 1]) > 0 x = 1e-64 for i in range(200): assert orient2d([-x, 0], [0, 1], [x, 0]) < 0 assert orient2d([-x, 0], [0, 0], [x, 0]) == 0 assert orient2d([-x, 0], [0, -1], [x, 0]) > 0 assert orient2d([0, 1], [0, 0], [x, x]) x *= 10
def is_r_turn(p1: Tuple[float, float], p2: Tuple[float, float], p3: Tuple[float, float]) -> bool: """ проверка поворота :param p1: top :param p2: v :param p3: w :return: True - поворот правый, либо на прямой False - поворот левый """ return orient2d(p1, p2, p3) <= 0
def eps_for_edge_geometry(g): eps = sys.float_info.max if len(g) > 2: for j in range(1, len(g) - 1): i = j - 1 k = j + 1 area = abs(orient2d(g[i], g[j], g[k]) * 0.5) base = dist(g[i], g[k]) if base == 0: continue height = area / (0.5 * base) # height = sys.float_info.max if height < eps: eps = height return eps
def binary_search_inf(l, r, Q, points): if points[l].x > Q.x or points[r].x < Q.x: return -1 print(l, r) while (l != r + 1) and (r != 0 or l != len(points) - 1): if l <= r: m = int((l + r) / 2) else: m = int((l + r + len(points)) / 2 % len(points)) if points[m].x >= Q.x: if m != 0: r = m - 1 else: r = len(points) - 1 elif points[m].x < Q.x: if m != len(points) - 1: l = m + 1 else: l = 0 print(l, r) pr = (points[l].x, points[l].y) pl = (points[r].x, points[r].y) q = (Q.x, Q.y) o = orient2d(pl, pr, q) print(pl, pr, q) if o < 0: return -1 elif o > 0: return 1 else: if pl[1] <= q[1] and pr[1] >= q[1] or pl[1] >= q[1] and pr[1] <= q[1]: return 0 else: return -1
] ) return np.linalg.det(x) with open("in_out_samples/3.in", "r") as fin: a, b, c, d = ( parse_point(fin.readline()), parse_point(fin.readline()), parse_point(fin.readline()), parse_point(fin.readline()), ) print(a, b, c, d) det = orient2d(a, b, c) # daca a, b, c formeaza viraj la stanga # inversam a si c pentru a forma unul si a putea aplica formula if det < 0: cpy = a a = c c = cpy title = None res = theta(a, b, c, d) if abs(res - 0) < 1.0e-6: title = "conciclice" elif res > 0: title = "in interior" else: title = "in exterior"
def orient_node(nodea, nodeb, nodec): return orient2d((nodea.x, nodea.y), (nodeb.x, nodeb.y), (nodec.x, nodec.y))
def test_left(self): """Points make a left turn, area positive""" assert orient2d( (0, 0), (10, 0), (10, 10)) == 100.0
def test_right(self): """Points make a right turn, area negative""" assert orient2d( (0, 0), (10, 0), (10, -10)) == -100.0
from geompreds import orient2d def determinant(xa, ya, xb, yb, xc, yc): """Returns determinant of three points """ return (xb - xa) * (yc - ya) - \ (xc - xa) * (yb - ya) def test_bigvalues(): C = int(2e17) for i in range(0, 2048): ra = orient2d((0+C,0+C), (15+C, pow(10, -i)+C), (25+C,0+C)) fa = determinant(0+C,0+C, 15+C, pow(10, -i)+C, 25+C, 0+C) try: assert ra == fa except AssertionError: print(ra, "<>", fa, i, C) if __name__ == '__main__': assert orient2d( (0, 0), (0, 10), (-10, 10)) == 100. assert orient2d( (0, 0), (0, 10), (10, 10)) == -100. test_bigvalues()
def CCW(a, b, c): if geompreds.orient2d(a, b, c) > 0: return True else: return False
infFront = [] supFront = [] for (ipoint, point) in enumerate(points): if ipoint <= 1: infFront.append(point) else: infFront.append(point) n = len(infFront) while (True): if n <= 2: break orientation = orient2d(infFront[n - 3], infFront[n - 2], infFront[n - 1]) if orientation > 0: break else: infFront.pop(n - 2) n -= 1 c_hull = infFront for (ipoint, point) in enumerate(reversed(points)): if ipoint <= 1: supFront.append(point) else: supFront.append(point) n = len(supFront) while (True):
def test_straight(self): """Points on a straight line, area zero""" assert orient2d( (0, 0), (10, 0), (20, 0)) == 0.0
points.append(parse_point(fin.readline())) start_index, leftmost_point = min(enumerate(points), key=lambda x: x[1][0]) # cat timp punctul din mijloc al tripletului este diferit de punctul de start (i.e. nu am ciclat) a, b, c = (start_index - 1) % len(points), start_index, (start_index + 1) % len(points) convex_hull = [b] while True: # if orient2d(points[a], points[b], points[c]) > 0: convex_hull.append(c) last_visited_point = c while len(convex_hull) > 2 and orient2d(points[convex_hull[-3]], points[convex_hull[-2]], points[convex_hull[-1]]) <= 0: convex_hull.pop(-2) print(convex_hull) a = convex_hull[-2] b = convex_hull[-1] c = (last_visited_point + 1) % len(points) if b == start_index: break while orient2d(points[convex_hull[-3]], points[convex_hull[-2]], points[convex_hull[-1]]) <= 0: convex_hull.pop(-2) print(convex_hull)