def foo(points: [Point, ...], points_sorted_by_y): if len(points) == 2: return Distance(points[0], points[1]) if len(points) == 1: return Distance(Point(MAX_DISTANCE, 0), Point(0, 0)) A = points[:int(len(points) / 2)] B = points[int(len(points) / 2):] A_sorted_by_y = [point for point in points_sorted_by_y if point in A] B_sorted_by_y = [point for point in points_sorted_by_y if point in B] disA = foo(A, A_sorted_by_y) disB = foo(B, B_sorted_by_y) min_distance = disA if disA.dis < disB.dis else disB middle_point = B[0] ind = 0 while ind < len(points_sorted_by_y): p1 = points_sorted_by_y[ind] if abs(p1.x - middle_point.x) > min_distance.dis: ind += 1 continue for j in range(ind + 1, ind + 7): try: p2 = points_sorted_by_y[j] except: break new_distance = Distance(p1, p2) if new_distance.dis < min_distance.dis: min_distance = new_distance ind += 1 return min_distance
def is_on(points,given_point): for ind in range(len(points)-1): p_max = Point(max(points[ind].x, points[ind+1].x), max(points[ind].y, points[ind+1].y)) p_min = Point(min(points[ind].x, points[ind+1].x), min(points[ind].y, points[ind+1].y)) if define_orientation(points[ind],points[ind+1],given_point) == "on" \ and p_min.x <= given_point.x <= p_max.x and p_min.y <= given_point.y <= p_max.y: return True
def alg_Cyrus_Beck(segment, points): reverse_if_left_orientation(points) tA = 0 tB = 1 for i in range(len(points)): try: edge = points[i], points[i + 1] except: edge = points[i], points[0] normal = Point(edge[1].y - edge[0].y, edge[0].x - edge[1].x) t1 = (normal.x * (edge[1].x - segment[0].x) + normal.y * (edge[1].y - segment[0].y)) t2 = (normal.x * (segment[1].x - segment[0].x) + normal.y * (segment[1].y - segment[0].y)) if t2 != 0: t = t1 / t2 else: # if define_orientation(edge[0],edge[1],segment[0]) == "left": # return 0,0 # print("zero div",t1,t2) continue scalar_product = scalar_mult( Point(segment[1].x - segment[0].x, segment[1].y - segment[0].y), normal) if scalar_product > 0: # orientation dependence? tA = max(tA, t) else: tB = min(tB, t) if tA > tB: return 0, 0 return tA, tB
def find_min_max(points): points_x = [] points_y = [] for i in points: points_x.append(i.x) points_y.append(i.y) return Point(min(points_x),min(points_y)),Point(max(points_x),max(points_y))
def point_on_line(point, p1, p2): p_max = Point(max(p1.x, p2.x), max(p1.y, p2.y)) p_min = Point(min(p1.x, p2.x), min(p1.y, p2.y)) if define_orientation(p1, p2, point) == "on" \ and p_min.x <= point.x <= p_max.x and p_min.y <= point.y <= p_max.y: return True else: return False
def test(func, i=1000, flag=True): errors = 0 for i in range(i): points = [ Point(random.randint(-10, 10), random.randint(-10, 10)) for i in range(10) ] points = [i for n, i in enumerate(points) if i not in points[:n]] min = Distance(points[0], points[1]) for p1 in points: for p2 in points: if p1 == p2: continue if Distance(p1, p2).dis < min.dis: min = Distance(p1, p2) min_by_func = func(points) if min_by_func.dis != min.dis: errors += 1 if flag: for p in points: plt.plot(p.x, p.y, 'ro') plt.plot(min.p1.x, min.p1.y, 'ro', color=(1, 1, 0)) plt.plot(min.p2.x, min.p2.y, 'ro', color=(1, 1, 0)) plt.plot(min_by_func.p1.x, min_by_func.p1.y, 'ro', color=(0, 1, 0)) plt.plot(min_by_func.p2.x, min_by_func.p2.y, 'ro', color=(0, 1, 0)) print("Expected %f but found %f" % (min.dis, min_by_func.dis)) plt.show() print("The are %d errors" % errors)
def jarvis_test(n=1000): errors = 0 for i in range(n): print(end=str(i) + " ") points = [ Point(random.uniform(-10, 10), random.uniform(-10, 10)) for i in range(30) ] carcass = jarvis(points) state = is_convex(carcass) for point in points: if is_inside(carcass, point) == "inside" or is_inside( carcass, point) == "on": pass else: state = False break if state: pass # print("ok") else: errors += 1 draw_figure(carcass) for p in carcass: plt.plot(p.x, p.y, 'ro', color=(0, 0, 0)) plt.plot(carcass[0].x, carcass[0].y, 'ro', color=(1, 0, 0)) for p in points: plt.plot(p.x, p.y, 'ro') plt.show() print("error") print() return errors
def diameter_search_test(n=1000): errors = 0 for i in range(n): print(end=str(i) + " ") points = [ Point(random.uniform(-10, 10), random.uniform(-10, 10)) for i in range(30) ] d_max, d1, d2 = diameter_search(points) n = len(points) c = int(factorial(n) / factorial(n - 2) / 2) for i in range(c * 5): p1 = random.choice(points) p2 = random.choice(points) dis = distance(p1, p2) if dis > d_max: print(d_max, dis) carcass = jarvis(points) draw_figure(carcass) draw_figure((d1, d2)) draw_figure((p1, p2)) plt.show() errors += 1 break print() return errors
def test_inside(func, figure=[ Point(-1, -1), Point(-5, 3), Point(0, 11), Point(6, 13), Point(10, 4.5), Point(4, -3) ], range_number=100): draw_figure(figure) random.seed(1) for i in range(range_number): given_point = Point(random.randint(-5, 10), random.randint(-5, 10)) #-2,0 func_value = func(figure, given_point) if func_value == "on": plt.plot(given_point.x, given_point.y, 'ro', color=(0, 0, 0), markersize=4) elif func_value == "inside": plt.plot(given_point.x, given_point.y, 'ro', markersize=4) else: plt.plot(given_point.x, given_point.y, 'ro', color=(0, 0.5, 0.3), markersize=4) plt.show()
def test_inside(func, figure=[ Point(-1, -1), Point(-5, 3), Point(0, 11), Point(6, 13), Point(10, 4.5), Point(4, -3) ], range_number=100): draw_figure(figure) random.seed(1) mistakes_counter = 0 for i in range(range_number): given_point = Point(random.randint(-5, 10), random.randint(-5, 10)) #-2,0 func_value = func(figure, given_point) standard_value = is_inside(figure, given_point) if func_value != standard_value: print("ABORT", given_point, "Returned:", func_value, "Expected:", standard_value) plt.plot(given_point.x, given_point.y, 'ro', color=(0.5, 0.5, 0.5), markersize=5) continue mistakes_counter += 1 if func_value == "on": plt.plot(given_point.x, given_point.y, 'ro', color=(0, 0, 0), markersize=4) elif func_value == "inside": plt.plot(given_point.x, given_point.y, 'ro', markersize=4) else: plt.plot(given_point.x, given_point.y, 'ro', color=(0, 0.5, 0.3), markersize=4) print("There is no incompatibilities" if mistakes_counter == 0 else str(mistakes_counter) + " incompatibilities") plt.show()
def collision(given_point, points, position): # position can be inside or outside next_position_point = Point(given_point.x + given_point.speed[0], given_point.y + given_point.speed[1]) flag = is_inside(points, next_position_point) if flag == position or flag == "on": for ind in range(len(points) - 1): if (is_intersect(points[ind], points[ind + 1], next_position_point, given_point)): b = Vector(points[ind], points[ind + 1]) if (is_intersect(points[-1], points[0], next_position_point, given_point)): b = Vector(points[-1], points[0]) a = Vector(given_point, next_position_point) try: arr = [] for point in points: arr.append(distance(point, given_point)) new_a = b * ((a * b) / (b * b) * 2) - a given_point.set_speed((new_a.vx, new_a.vy)) except: given_point.x, given_point.y = (48, 54)
def collision(given_point, points, position): # position can be inside or outside next_position_point = Point(given_point.x + given_point.speed[0], given_point.y + given_point.speed[1]) flag = is_inside(points, next_position_point) if flag == position or flag == "on": for ind in range(len(points) - 1): if (is_intersect(points[ind], points[ind + 1], next_position_point, given_point)): b = Vector(points[ind], points[ind + 1]) if (is_intersect(points[-1], points[0], next_position_point, given_point)): b = Vector(points[-1], points[0]) a = Vector(given_point, next_position_point) try: arr = [] for point in points: arr.append(distance(point, given_point)) new_a = b * ((a * b) / (b * b) * 2) - a given_point.set_speed((new_a.vx, new_a.vy)) except: given_point.x, given_point.y = ( 48, 54 ) #тут иногда возникает исключение, когда точка попадает прямо в угол. тогда формула неправильная
# arr.append(distance(point, given_point)) # i = argmin(arr) # try: # b1 = Vector(points[i], points[i+1]) # except: # b1 = Vector(points[i], points[0]) # try: # b2 = Vector(points[i], points[i-1]) # except: # b2 = Vector(points[i], points[-1]) # b1 = b1 * (1 / len(b1)) # b2 = b2 * (1 / len(b2)) # orthogonal = Vector(b1.vx + b2.vx, b1.vy + b2.vy) # b = Vector(-orthogonal.vy, orthogonal.vx) # new_a = b * ((a * b) / (b * b) * 2) - a # given_point.set_speed((new_a.vx, new_a.vy)) if __name__ == "__main__": given_point = Point(0, -3) given_point.set_speed((0, -1)) points = [Point(-30, 30), Point(30, 30), Point(0, -50)] fig = plt.figure() ax = plt.axes(xlim=(-50, 150), ylim=(-60, 150)) point, = ax.plot(0, -30, 'o', markersize=4) anim = FuncAnimation(fig, animate, frames=1, interval=200, blit=True) draw_figure(points) plt.show()
if octane_is_inside(simple_figure, point) == "outside": new_points.append(point) point.move() points = new_points mat.set_data([point.x for point in points], [point.y for point in points]) return mat, if __name__ == "__main__": fig = plt.figure() ax = plt.axes(xlim=(-50, 150), ylim=(-50, 150)) # random.seed(15) # random.seed(392) # random.seed(2) random.seed(205) points = [Point(random.randint(-50, 100), random.randint(-50, 100)) for i in range(0, 100)] convex_figure = [Point(-10, -10), Point(-50, 30), Point(0, 110), Point(60, 130), Point(100, 45), Point(40, -30)] simple_figure = [Point(10, 10), Point(40, 50), Point(10, 80), Point(50, 70), Point(70, 90), Point(60, 30), Point(90, 40), Point(60, 20), Point(40, 35)] new_points = [] for point in points: if convex_is_inside(convex_figure,point) == "inside": new_points.append(point) point.set_random_speed(1,seed=100) points = new_points mat, = ax.plot([point.x for point in points], [point.y for point in points], 'o', markersize=4) anim = FuncAnimation(fig, animate_points, frames=100, interval=1, blit=True) # blit=True means only re-draw the parts that have changed.
figure[ind].y - given_point.y, figure[ind + 1].x - given_point.x, figure[ind + 1].y - given_point.y) if D > 0: delta = 4 if D < 0: delta = -4 if D == 0: return "on" s += delta if s == 8 or s == -8: return "inside" if s == 0: return "outside" if __name__ == "__main__": given_point = Point(1, 1) # -2,0 simple_figure = [ Point(1, 1), Point(4, 5), Point(1, 8), Point(5, 7), Point(7, 9), Point(6, 3), Point(9, 4), Point(6, 2), Point(4, 3.5) ] test_inside(is_inside, simple_figure)
return lines, def sorter(p1): value1 = pi / 2 if p1.x == min_point.x \ else atan((p1.y - min_point.y) / abs(min_point.x - p1.x)) if p1.x < min_point.x: value1 = pi - value1 return value1, distance(p1, min_point) if __name__ == "__main__": random.seed(322) # arr = [[9, 7], [1, -2], [-9, 9], [-5, -10], [7, 10], [8, 0], [2, -8], [9, 8], [2, 3], [2, -3], [2, -6], [-3, -7], [3, -7], # [8, 4], [0, 1], [-1, -2], [1, -2], [-10, 9], [-8, 2], [-2, -2]] points = [Point(random.uniform(-3, 3), random.uniform(-3, 3)) for i in range(15)] points = [i for n, i in enumerate(points) if i not in points[:n]] min_point = min(points, key=attrgetter('y')) stack = [min_point] points.remove(min_point) points.sort(key=lambda point: sorter(point)) points.append(min_point) fig = plt.figure() ax = plt.axes(xlim=(-11, 11), ylim=(-11, 11)) lines, = plt.plot([], []) anim = FuncAnimation(fig, animate, frames=7, interval=500, blit=True) plt.plot(min_point.x, min_point.y, 'ro', color=(0.5, 0.5, 0)) for ind, point in enumerate(points): plt.plot(point.x, point.y, 'ro', markersize=2) plt.show()
def animate_points(i): dis = divide_and_conquer(points) if dis.dis < 3.3: dis.p1.set_speed((-dis.p1.speed[0], -dis.p1.speed[1])) dis.p2.set_speed((-dis.p1.speed[0], -dis.p1.speed[1])) for p in points: if not (-50 <= p.x + p.speed[0] <= 50 and -50 <= p.y + p.speed[1] <= 50): p.set_speed((-p.speed[0], -p.speed[1])) p.move() mat.set_data([point.x for point in points], [point.y for point in points]) return mat, if __name__ == "__main__": random.seed(2) points = [ Point(random.uniform(-50, 50), random.uniform(-50, 50)) for i in range(20) ] points = [i for n, i in enumerate(points) if i not in points[:n]] for p in points: p.set_random_speed(0.3) fig = plt.figure() ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50)) mat, = ax.plot([], [], 'o', color=(0, 0, 1), markersize=10) anim = FuncAnimation( fig, animate_points, frames=100, interval=5, blit=True) # blit=True means only re-draw the parts that have changed. plt.show()
if new_distance.dis < min_distance.dis: min_distance = new_distance ind += 1 return min_distance def divide_and_conquer(points: [Point, ...]): points.sort(key=lambda point: (point.x, point.y)) points_sorted_by_y = points.copy() points_sorted_by_y.sort(key=lambda point: (point.y, point.x)) return foo(points, points_sorted_by_y) if __name__ == "__main__": points = [ Point(1, 3), Point(3, 4), Point(4, 3), Point(2, 6), Point(4, 5), Point(4.5, 4.5), Point(1, 8), Point(1.2, 4.1) ] # points = [Point(random.uniform(-100, 100), random.uniform(-100, 100)) for i in range(1000)] points = [i for n, i in enumerate(points) if i not in points[:n]] for p in points: plt.plot(p.x, p.y, 'ro') print(divide_and_conquer(points)) plt.show()
if change_speed_flag: point.set_speed((-point.speed[0], -point.speed[1])) point.move() mat.set_data([point.x for point in points], [point.y for point in points]) lines.set_data([i.x for i in carcass] + [carcass[0].x], [i.y for i in carcass] + [carcass[0].y]) lines2.set_data([d1.x, d2.x], [d1.y, d2.y]) return mat, lines, lines2, if __name__ == "__main__": fig = plt.figure() ax = plt.axes(xlim=(-100, 100), ylim=(-100, 100)) random.seed(205) points = [ Point(random.randint(-50, 50), random.randint(-50, 50)) for i in range(0, 100) ] for point in points: point.set_random_speed(0.1) mat, = ax.plot([point.x for point in points], [point.y for point in points], 'o', markersize=4) lines, = ax.plot([], []) lines2, = ax.plot([], []) anim = FuncAnimation( fig, animate_points, frames=100, interval=1, blit=True) # blit=True means only re-draw the parts that have changed. plt.show()
d_max = 0, p, q counter = 0 while q != carcass[0] and counter < n: p = P.next(p) d_max = (distance(p, q), p, q) if distance(p, q) >= d_max[0] else d_max while S(p, P.next(p), P.next(q)) > \ S(p, P.next(p), q): counter += 1 q = P.next(q) if distance(p, q) != distance(q0, carcass[0]): d_max = (distance(p, q), p, q) if distance(p, q) >= d_max[0] else d_max # if S(p, P.next(p), P.next(q)) == S(p, P.next(p), q): # if distance(p, q) != (q0, carcass[-1]): # d_max = (distance(p, P.next(q)), p, P.next(q)) if distance(p, P.next(q)) >= d_max[0] else d_max return d_max if __name__ == "__main__": random.seed(9) #9 1 points = [ Point(random.randint(-10, 10), random.randint(-10, 10)) for i in range(30) ] # points = [Point(0,0), Point(10,0),Point(0,10),Point(10,10)] d_max = diameter_search(points) print(d_max[0]) draw_figure(d_max[1:]) draw_figure(jarvis(points)) plt.show()
for i in range(0, len(points)): total = 0 for j in range(0, len(points)): try: total += is_intersect(points[i], points[i + 1], points[j], points[j + 1]) except: pass if total > 3: return False if total != 3 and total != 0: return False return True def draw_figure(points, color=False): for ind in range(0, len(points)): try: draw_line(points[ind], points[ind + 1], color) except: draw_line(points[ind], points[0], color) if __name__ == "__main__": points = [] for i in range(0, 4): points.append(Point(random.randint(0, 20), random.randint(0, 20))) print("Simple", is_simple(points)) draw_figure(points) plt.show()
def is_inside(original_figure, given_point): if not dimensional_test(original_figure, given_point): return "outside" figure = copy.deepcopy(original_figure) figure += [figure[0]] if is_on(figure, given_point): return "on" sections = create_sections(figure) given_section = determine_section(sections, given_point) given_section = [sections[given_section[0]], sections[given_section[1]]] orientation = define_orientation(given_section[0], given_section[1], given_point) if orientation == "left": return "inside" elif orientation == "right": return "outside" elif orientation == "on": return "on" if __name__ == "__main__": convex_figure = [ Point(-1, -1), Point(-5, 3), Point(0, 11), Point(6, 13), Point(10, 4.5), Point(4, -3) ] test_inside(is_inside, range_number=300)
if S(P, Q, point) > max: max = S(P, Q, point) max_point = point C = max_point convex_hull.insert(convex_hull.index(P), C) segment_1, segment_2 = [], [ ] # segment_1 is to the right side of PC, segment_2 is to the right side of the CQ for point in segment: if define_orientation(P, C, point) == "right": segment_1.append(point) if define_orientation(C, Q, point) == "right": segment_2.append(point) find_hull(segment_1, P, C, convex_hull) find_hull(segment_2, C, Q, convex_hull) if __name__ == "__main__": random.seed(10) points = [ Point(random.uniform(-10, 10), random.uniform(-10, 10)) for i in range(30) ] plt.plot([i.x for i in points], [i.y for i in points], 'ro', color=(0.5, 0.5, 0)) hull = quick_hull(points) plt.plot([i.x for i in hull], [i.y for i in hull], 'ro', color=(0.5, 0.5, 1)) draw_figure(hull) plt.show()
else: tB = min(tB, t) if tA > tB: return 0, 0 return tA, tB def change_line_with_params(segment, t1, t2) -> [Point, Point]: return (Point(segment[0].x + (segment[1].x - segment[0].x) * t1, segment[0].y + (segment[1].y - segment[0].y) * t1), Point(segment[0].x + (segment[1].x - segment[0].x) * t2, segment[0].y + (segment[1].y - segment[0].y) * t2)) if __name__ == "__main__": segment_list = [[Point(2, 5), Point(4, 6)], [Point(-2, 2), Point(0, 4)], [Point(-4, 4), Point(4, 4)], [Point(-4, 2), Point(0.1, 4.4)], [Point(0, 6), Point(4, 6)], [Point(2, 2), Point(4, 5)], [Point(0, 5), Point(0, -5)]] point_list = [[Point(-3, 0), Point(-5, 6), Point(4, 3), Point(1, 0)], [Point(-3, 0), Point(0, 4), Point(1, 6), Point(-2, 4.5)]]
outside_point.y -= 0.1 counter = 0 for i in range(0, len(points) - 1): try: counter += is_intersect(given_point, outside_point, points[i], points[i + 1]) except: counter += is_intersect(given_point, outside_point, points[i], points[0]) if counter % 2 == 0: return "outside" else: return "inside" else: return "outside" if __name__ == "__main__": given_point = Point(5, 3) #4,4 -1,-1 points = [ Point(1, 1), Point(4, 5), Point(1, 8), Point(5, 7), Point(7, 9), Point(6, 3), Point(9, 4), Point(6, 2), Point(4, 3.5) ] test_inside(is_inside, range_number=100)
def onclick(event): global convex_hull convex_hull = append_point(convex_hull, Point(event.xdata, event.ydata))
new_points.append(point) point.move() points = new_points mat.set_data([point.x for point in points], [point.y for point in points]) return mat, if __name__ == "__main__": fig = plt.figure() ax = plt.axes(xlim=(-50, 150), ylim=(-50, 150)) # random.seed(15) # random.seed(392) # random.seed(2) random.seed(205) points = [ Point(random.randint(-50, 100), random.randint(-50, 100)) for i in range(0, 100) ] convex_figure = [ Point(-10, -10), Point(-50, 30), Point(0, 110), Point(60, 130), Point(100, 45), Point(40, -30) ] simple_figure = [ Point(10, 10), Point(40, 50), Point(10, 80), Point(50, 70),
def change_line_with_params(segment, t1, t2) -> [Point, Point]: return (Point(segment[0].x + (segment[1].x - segment[0].x) * t1, segment[0].y + (segment[1].y - segment[0].y) * t1), Point(segment[0].x + (segment[1].x - segment[0].x) * t2, segment[0].y + (segment[1].y - segment[0].y) * t2))
while end - start > 1: sep = int((start + end) / 2) orientation = define_orientation(sections[0], sections[sep], given_point) if orientation == "left": start = sep else: end = sep return start,end def is_inside(original_figure,given_point): if not dimensional_test(original_figure,given_point): return "outside" figure = copy.deepcopy(original_figure) figure += [figure[0]] if is_on(figure,given_point): return "on" sections = create_sections(figure) given_section = determine_section(sections,given_point) given_section = [sections[given_section[0]], sections[given_section[1]]] orientation = define_orientation(given_section[0], given_section[1], given_point) if orientation == "left": return "inside" elif orientation == "right": return "outside" elif orientation == "on": return "on" if __name__ == "__main__": convex_figure = [Point(-1,-1),Point(-5,3),Point(0,11),Point(6,13),Point(10,4.5),Point(4,-3)] test_inside(is_inside,range_number=300)
import matplotlib.pyplot as plt from lab1_1 import Point, det, draw_line def is_intersect(p1, p2, p3, p4): det1 = det((p2.x - p1.x), (p2.y - p1.y), (p3.x - p1.x), (p3.y - p1.y)) det2 = det((p2.x - p1.x), (p2.y - p1.y), (p4.x - p1.x), (p4.y - p1.y)) det3 = det((p4.x - p3.x), (p4.y - p3.y), (p1.x - p3.x), (p1.y - p3.y)) det4 = det((p4.x - p3.x), (p4.y - p3.y), (p2.x - p3.x), (p2.y - p3.y)) if det1 * det2 <= 0 and det3 * det4 <= 0: return True else: return False if __name__ == "__main__": # p1 = Point(3,5) # p2 = Point(3, 7) # p3 = Point(3, 6) # p4 = Point(8, 6) p1 = Point(random.randint(0, 20), random.randint(0, 20)) p2 = Point(random.randint(0, 20), random.randint(0, 20)) p3 = Point(random.randint(0, 20), random.randint(0, 20)) p4 = Point(random.randint(0, 20), random.randint(0, 20)) draw_line(p1, p2) draw_line(p3, p4) plt.show() print("intersect:", is_intersect(p1, p2, p3, p4))