def test_reduced_circle(self): point_on = Vector2D(1.0, .0) circle = MyCircle(Vector2D(.0, .0), 1.0) self.assertTrue(circle.is_point_on_edge(point_on)) r = 0.75 angle = 3 * pi / 4.0 p0 = Vector2D(r * cos(angle) + 0.25, r * sin(angle)) p1 = Vector2D(-0.5, .0); line = Line2D(circle.centre, point_on) red_circle_new0 = reduced_circle_new(point_on, p0, line) red_circle_new1 = reduced_circle_new(point_on, p1, line) self.assertEqual(0.25, red_circle_new0.centre.get_x()) self.assertEqual(0.0, red_circle_new0.centre.get_y()) self.assertEqual(0.75, red_circle_new0.radius) self.assertEqual(0.25, red_circle_new1.centre.get_x()) self.assertEqual(0.0, red_circle_new1.centre.get_y()) self.assertEqual(0.75, red_circle_new1.radius) self.test_triangle_obtuse() for i in range(500): self.test_random()
def test_random(self): point_on = self.get_random_point() point_centre = self.get_random_point() norm = point_on.sub(point_centre).norm() circle = MyCircle(point_centre, norm) self.assertTrue(circle.is_point_on_edge(point_on)) point_along = self.get_random_point() point_aim = self.get_random_point() new_circle_new = reduced_circle_new(point_on, point_aim, Line2D(circle.centre, point_along)) self.assertTrue(new_circle_new.is_point_on_edge(point_on)) self.assertTrue(new_circle_new.is_point_on_edge(point_aim))
def find_smallest_circle_sqtime(a_list_of_points): gravity_centre = find_gravity_centre(a_list_of_points) smallest_circle = MyCircle(gravity_centre, .1) farther_point = max(a_list_of_points, key=lambda p: smallest_circle.centre.sub(p).norm()) smallest_circle.radius = smallest_circle.centre.sub(farther_point).norm() anchor_radius = 0.0 anchor_point = farther_point for p in a_list_of_points: if p is not farther_point: circle = reduced_circle_new(farther_point, p, Line2D(smallest_circle.centre, farther_point)) if anchor_radius < circle.radius: anchor_radius = circle.radius anchor_point = p smallest_circle = circle # the pair of pivot points found: a = farther_point b = anchor_point in_progress = True while in_progress: in_progress = False two_points_based_centre = a.sum(b).multiply(0.5) two_points_based_radius = 0.5 * a.sub(b).norm() two_points_based_circle = MyCircle(two_points_based_centre, two_points_based_radius) if all(two_points_based_circle.is_point_inside(p) for p in a_list_of_points): smallest_circle = two_points_based_circle pivot_points = [a, b] else: final_radius = two_points_based_radius final_point = None final_centre = smallest_circle.centre for p in a_list_of_points: if p is not a and p is not b: obtuse_point = get_vertex_with_obtuse_angle(a, b, p) if obtuse_point is p: continue line_ab = Line2D(a, b) mid = line_ab.middle_point() line_along = Line2D(mid, mid.sum(line_ab.orthogonal_vector())) circle = reduced_circle_new(a, p, line_along) if final_radius < circle.radius < smallest_circle.radius: final_radius = circle.radius final_centre = circle.centre final_point = p # assert isinstance(final_point, Point2D) obtuse_point = get_vertex_with_obtuse_angle(a, b, final_point) if obtuse_point is not None: assert final_point is not obtuse_point, 'final is obtuse!' in_progress = True if obtuse_point is a: a = final_point else: b = final_point else: smallest_circle.centre = final_centre smallest_circle.radius = final_radius # assert final_point is not a and not b if final_point is not None: pivot_points = [a, b, final_point] else: pivot_points = [a, b] assert isinstance(pivot_points, list) return smallest_circle, pivot_points